diff --git a/.github/workflows/indexer-processor-testing.yaml b/.github/workflows/indexer-processor-testing.yaml index de9656487c1fa..9c93b737076d8 100644 --- a/.github/workflows/indexer-processor-testing.yaml +++ b/.github/workflows/indexer-processor-testing.yaml @@ -63,7 +63,7 @@ jobs: sed -i "s/MAINNET_API_KEY/${{ steps.api_key_tokens.outputs.mainnet_api_key }}/g" ./imported_transactions/imported_transactions.yaml cat ./imported_transactions/imported_transactions.yaml # Print the updated file for verification - cargo run -- --testing-folder ./imported_transactions --output-folder ../indexer-test-transactions/new_json_transactions + cargo run -- --testing-folder ./imported_transactions --output-folder ../indexer-test-transactions/src/new_json_transactions - name: Install jq run: sudo apt-get install jq # Ensure jq is installed for JSON processing @@ -72,10 +72,10 @@ jobs: # Prepare Original and New JSON Files - name: Prepare and Clean JSON Files run: | - cd ecosystem/indexer-grpc/indexer-test-transactions - ls -al ./new_json_transactions/scripted_transactions + cd ecosystem/indexer-grpc/indexer-test-transactions/src + ls -al ./new_json_transactions - for folder in json_transactions/scripted_transactions new_json_transactions/scripted_transactions; do + for folder in json_transactions/scripted_transactions new_json_transactions/json_transactions/scripted_transactions; do for file in $folder/*.json; do echo "Processing $file..." base_file=$(basename "$file") diff --git a/Cargo.lock b/Cargo.lock index 1a0c1b7d43a64..9e6a80da4bbeb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,6 +131,21 @@ 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 = "allocative" version = "0.3.3" @@ -275,7 +290,7 @@ dependencies = [ [[package]] name = "aptos" -version = "5.1.0" +version = "6.0.1" dependencies = [ "anyhow", "aptos-api-types", @@ -947,7 +962,7 @@ dependencies = [ "maplit", "mini-moka", "mirai-annotations", - "mockall 0.11.4", + "mockall", "move-core-types", "num-derive", "num-traits", @@ -1128,7 +1143,7 @@ dependencies = [ "futures", "itertools 0.13.0", "maplit", - "mockall 0.11.4", + "mockall", "ordered-float 3.9.2", "rand 0.8.5", "serde", @@ -1174,7 +1189,6 @@ dependencies = [ "aptos-crypto", "aptos-db-indexer", "aptos-db-indexer-schemas", - "aptos-executor", "aptos-executor-types", "aptos-experimental-runtimes", "aptos-infallible", @@ -1197,14 +1211,12 @@ dependencies = [ "clap 4.5.21", "crossbeam-channel", "dashmap", - "derive_more", "either", "hex", "indicatif 0.15.0", "itertools 0.13.0", "lru 0.7.8", "move-core-types", - "num-derive", "once_cell", "owo-colors", "proptest", @@ -1450,18 +1462,15 @@ dependencies = [ "aptos-crypto", "aptos-db", "aptos-db-indexer", - "aptos-db-indexer-schemas", "aptos-drop-helper", "aptos-executor-service", "aptos-executor-test-helpers", "aptos-executor-types", "aptos-experimental-runtimes", - "aptos-genesis", "aptos-indexer-grpc-table-info", "aptos-infallible", "aptos-logger", "aptos-metrics-core", - "aptos-scratchpad", "aptos-sdk", "aptos-storage-interface", "aptos-temppath", @@ -1472,7 +1481,6 @@ dependencies = [ "bcs 0.1.4", "bytes", "criterion", - "dashmap", "fail", "itertools 0.13.0", "move-core-types", @@ -1605,7 +1613,7 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "criterion", - "derive_more", + "derive_more 0.99.17", "itertools 0.13.0", "once_cell", "ouroboros", @@ -2111,7 +2119,7 @@ dependencies = [ "aptos-indexer-grpc-server-framework", "aptos-indexer-grpc-utils", "aptos-metrics-core", - "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=4801acae7aea30d7e96bbfbe5ec5b04056dfa4cf)", + "aptos-moving-average", "aptos-protos 1.3.1", "async-trait", "clap 4.5.21", @@ -2138,7 +2146,7 @@ dependencies = [ "aptos-indexer-grpc-server-framework", "aptos-indexer-grpc-utils", "aptos-metrics-core", - "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=4801acae7aea30d7e96bbfbe5ec5b04056dfa4cf)", + "aptos-moving-average", "aptos-protos 1.3.1", "aptos-transaction-filter", "async-trait", @@ -2198,7 +2206,7 @@ dependencies = [ "aptos-indexer-grpc-server-framework", "aptos-indexer-grpc-utils", "aptos-metrics-core", - "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=4801acae7aea30d7e96bbfbe5ec5b04056dfa4cf)", + "aptos-moving-average", "async-trait", "clap 4.5.21", "futures", @@ -2252,7 +2260,7 @@ dependencies = [ "aptos-mempool", "aptos-mempool-notifications", "aptos-metrics-core", - "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=4801acae7aea30d7e96bbfbe5ec5b04056dfa4cf)", + "aptos-moving-average", "aptos-proptest-helpers", "aptos-protos 1.3.1", "aptos-runtimes", @@ -2306,12 +2314,17 @@ name = "aptos-indexer-grpc-manager" version = "1.0.0" dependencies = [ "anyhow", + "aptos-config", "aptos-indexer-grpc-server-framework", + "aptos-protos 1.3.1", "async-trait", "clap 4.5.21", "jemallocator", "serde", "tokio", + "tokio-scoped", + "tonic 0.12.3", + "tracing", ] [[package]] @@ -2399,38 +2412,6 @@ dependencies = [ "url", ] -[[package]] -name = "aptos-indexer-processor-sdk" -version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=9ecd252ccff53023664562001dd04c2886488c0d#9ecd252ccff53023664562001dd04c2886488c0d" -dependencies = [ - "anyhow", - "aptos-indexer-transaction-stream", - "aptos-protos 1.3.1 (git+https://github.com/aptos-labs/aptos-core.git?rev=5c48aee129b5a141be2792ffa3d9bd0a1a61c9cb)", - "async-trait", - "bcs 0.1.4", - "bigdecimal", - "chrono", - "derive_builder", - "futures", - "hex", - "instrumented-channel", - "kanal", - "mockall 0.12.1", - "num_cpus", - "once_cell", - "petgraph 0.6.5", - "prometheus", - "prometheus-client", - "serde", - "serde_json", - "thiserror", - "tiny-keccak", - "tokio", - "tracing", - "url", -] - [[package]] name = "aptos-indexer-test-transactions" version = "1.0.0" @@ -2464,27 +2445,6 @@ dependencies = [ "url", ] -[[package]] -name = "aptos-indexer-transaction-stream" -version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=9ecd252ccff53023664562001dd04c2886488c0d#9ecd252ccff53023664562001dd04c2886488c0d" -dependencies = [ - "anyhow", - "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=9ecd252ccff53023664562001dd04c2886488c0d)", - "aptos-protos 1.3.1 (git+https://github.com/aptos-labs/aptos-core.git?rev=5c48aee129b5a141be2792ffa3d9bd0a1a61c9cb)", - "chrono", - "futures-util", - "once_cell", - "prometheus", - "prost 0.12.3", - "sample", - "serde", - "tokio", - "tonic 0.11.0", - "tracing", - "url", -] - [[package]] name = "aptos-infallible" version = "0.1.0" @@ -2665,8 +2625,10 @@ dependencies = [ "aptos-metrics-core", "aptos-types", "ark-bls12-381", + "ark-bn254", "ark-ec", "ark-ff", + "ark-groth16", "ark-serialize", "bcs 0.1.4", "dashmap", @@ -2970,23 +2932,7 @@ dependencies = [ [[package]] name = "aptos-moving-average" version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=4801acae7aea30d7e96bbfbe5ec5b04056dfa4cf#4801acae7aea30d7e96bbfbe5ec5b04056dfa4cf" -dependencies = [ - "chrono", -] - -[[package]] -name = "aptos-moving-average" -version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=51a34901b40d7f75767ac907b4d2478104d6a515#51a34901b40d7f75767ac907b4d2478104d6a515" -dependencies = [ - "chrono", -] - -[[package]] -name = "aptos-moving-average" -version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=9ecd252ccff53023664562001dd04c2886488c0d#9ecd252ccff53023664562001dd04c2886488c0d" +source = "git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=3064a075e1abc06c60363f3f2551cc41f5c091de#3064a075e1abc06c60363f3f2551cc41f5c091de" dependencies = [ "chrono", ] @@ -3438,7 +3384,7 @@ dependencies = [ "claims", "futures", "maplit", - "mockall 0.11.4", + "mockall", "once_cell", "rand 0.7.3", "serde", @@ -3504,13 +3450,12 @@ dependencies = [ [[package]] name = "aptos-protos" version = "1.3.1" -source = "git+https://github.com/aptos-labs/aptos-core.git?rev=5c48aee129b5a141be2792ffa3d9bd0a1a61c9cb#5c48aee129b5a141be2792ffa3d9bd0a1a61c9cb" +source = "git+https://github.com/aptos-labs/aptos-core.git?rev=6116af69aa173ca49e1761daabd6fe103fe2c65e#6116af69aa173ca49e1761daabd6fe103fe2c65e" dependencies = [ - "futures-core", "pbjson", - "prost 0.12.3", + "prost 0.13.4", "serde", - "tonic 0.11.0", + "tonic 0.12.3", ] [[package]] @@ -3526,6 +3471,7 @@ version = "0.1.0" dependencies = [ "aptos-logger", "aptos-metrics-core", + "rand 0.7.3", "ureq", "url", ] @@ -3777,7 +3723,7 @@ name = "aptos-schemadb" version = "0.1.0" dependencies = [ "anyhow", - "aptos-infallible", + "aptos-drop-helper", "aptos-logger", "aptos-metrics-core", "aptos-storage-interface", @@ -3796,10 +3742,10 @@ version = "0.1.0" dependencies = [ "aptos-crypto", "aptos-drop-helper", - "aptos-experimental-runtimes", "aptos-infallible", "aptos-metrics-core", "aptos-types", + "aptos-vm", "bitvec 1.0.1", "criterion", "itertools 0.13.0", @@ -3826,6 +3772,7 @@ dependencies = [ "bcs 0.1.4", "ed25519-dalek-bip32", "hex", + "lazy_static", "move-core-types", "once_cell", "rand 0.7.3", @@ -3961,7 +3908,7 @@ dependencies = [ "bcs 0.1.4", "claims", "futures", - "mockall 0.11.4", + "mockall", "move-core-types", "ntest", "once_cell", @@ -3978,27 +3925,24 @@ version = "0.1.0" dependencies = [ "anyhow", "aptos-crypto", - "aptos-drop-helper", - "aptos-experimental-runtimes", - "aptos-logger", + "aptos-experimental-layered-map", "aptos-metrics-core", "aptos-scratchpad", "aptos-secure-net", "aptos-types", - "aptos-vm", "arr_macro", - "assert_unordered", "bcs 0.1.4", - "crossbeam-channel", "dashmap", + "derive_more 0.99.17", + "itertools 0.13.0", "once_cell", "parking_lot 0.12.1", "proptest", "proptest-derive", + "rand 0.7.3", "rayon", "serde", "thiserror", - "threadpool", ] [[package]] @@ -4052,7 +3996,7 @@ dependencies = [ "futures", "maplit", "mini-moka", - "mockall 0.11.4", + "mockall", "once_cell", "rand 0.7.3", "serde", @@ -4435,7 +4379,6 @@ dependencies = [ "aptos-proptest-helpers", "arbitrary", "ark-bn254", - "ark-crypto-primitives", "ark-ec", "ark-ff", "ark-groth16", @@ -4477,7 +4420,6 @@ dependencies = [ "quick_cache", "rand 0.7.3", "rayon", - "regex", "reqwest 0.11.23", "ring 0.16.20", "rsa 0.9.6", @@ -4583,10 +4525,11 @@ dependencies = [ "bytes", "claims", "crossbeam-channel", - "derive_more", + "derive_more 0.99.17", "fail", "futures", "hex", + "itertools 0.13.0", "move-binary-format", "move-core-types", "move-unit-test", @@ -4750,9 +4693,11 @@ dependencies = [ "aptos-vm-environment", "aptos-vm-genesis", "aptos-vm-logging", - "aptos-vm-types", "fail", + "move-binary-format", "move-core-types", + "move-vm-runtime", + "move-vm-types", "rand 0.7.3", ] @@ -5079,15 +5024,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c07dab4369547dbe5114677b33fbbf724971019f3818172d59a97a61c774ffd" -[[package]] -name = "assert_unordered" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74323b7881323eb351134e08ee5331594826789557afef8e309baf481b2264" -dependencies = [ - "ansi_term", -] - [[package]] name = "async-channel" version = "1.9.0" @@ -5118,6 +5054,7 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" dependencies = [ + "brotli", "flate2", "futures-core", "memchr", @@ -5925,6 +5862,27 @@ dependencies = [ "serde_with", ] +[[package]] +name = "brotli" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bstr" version = "0.2.17" @@ -6201,9 +6159,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" @@ -6622,18 +6580,18 @@ checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" [[package]] name = "const_format" -version = "0.2.32" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.32" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", @@ -7137,12 +7095,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.9", - "darling_macro 0.20.9", + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -7161,9 +7119,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", @@ -7186,11 +7144,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.20.9", + "darling_core 0.20.10", "quote", "syn 2.0.87", ] @@ -7284,17 +7242,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "delegate" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e018fccbeeb50ff26562ece792ed06659b9c2dae79ece77c4456bb10d9bf79b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "der" version = "0.5.1" @@ -7370,7 +7317,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" dependencies = [ - "darling 0.20.9", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.87", @@ -7410,6 +7357,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "unicode-xid", +] + [[package]] name = "determinator" version = "0.12.0" @@ -7646,12 +7614,6 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" -[[package]] -name = "dtoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" - [[package]] name = "dunce" version = "1.0.4" @@ -9072,7 +9034,7 @@ dependencies = [ "fixedbitset 0.4.2", "guppy-summaries", "guppy-workspace-hack", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.12.1", "nested", "once_cell", @@ -9121,7 +9083,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.11", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util 0.7.10", @@ -9140,7 +9102,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util 0.7.10", @@ -9569,7 +9531,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -9919,9 +9881,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", "hashbrown 0.15.1", @@ -9971,7 +9933,7 @@ dependencies = [ "crossbeam-utils", "dashmap", "env_logger", - "indexmap 2.6.0", + "indexmap 2.7.0", "is-terminal", "itoa", "log", @@ -10003,19 +9965,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "instrumented-channel" -version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=9ecd252ccff53023664562001dd04c2886488c0d#9ecd252ccff53023664562001dd04c2886488c0d" -dependencies = [ - "delegate", - "derive_builder", - "kanal", - "once_cell", - "prometheus", - "prometheus-client", -] - [[package]] name = "integer-encoding" version = "3.0.4" @@ -11005,23 +10954,8 @@ dependencies = [ "downcast", "fragile", "lazy_static", - "mockall_derive 0.11.4", - "predicates 2.1.5", - "predicates-tree", -] - -[[package]] -name = "mockall" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43766c2b5203b10de348ffe19f7e54564b64f3d6018ff7648d1e2d6d3a0f0a48" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "lazy_static", - "mockall_derive 0.12.1", - "predicates 3.1.2", + "mockall_derive", + "predicates", "predicates-tree", ] @@ -11037,18 +10971,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "mockall_derive" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "module-generation" version = "0.1.0" @@ -11120,7 +11042,7 @@ dependencies = [ "arbitrary", "backtrace", "dearbitrary", - "indexmap 1.9.3", + "indexmap 2.7.0", "move-bytecode-spec", "move-core-types", "proptest", @@ -12216,9 +12138,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -12290,7 +12212,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc7c92f190c97f79b4a332f5e81dcf68c8420af2045c936c9be0bc9de6f63b5" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 1.0.109", @@ -12554,9 +12476,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "open" -version = "5.3.1" +version = "5.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ecd52f0b8d15c40ce4820aa251ed5de032e5d91fab27f7db2f40d42a8bdf69c" +checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" dependencies = [ "is-wsl", "libc", @@ -12860,7 +12782,7 @@ dependencies = [ "async-trait", "coset", "log", - "mockall 0.11.4", + "mockall", "p256", "passkey-types", "rand 0.8.5", @@ -12894,7 +12816,7 @@ dependencies = [ "ciborium", "coset", "data-encoding", - "indexmap 2.6.0", + "indexmap 2.7.0", "rand 0.8.5", "serde", "serde_json", @@ -13080,7 +13002,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset 0.4.2", - "indexmap 2.6.0", + "indexmap 2.7.0", ] [[package]] @@ -13291,10 +13213,12 @@ dependencies = [ [[package]] name = "poem" -version = "3.0.1" -source = "git+https://github.com/poem-web/poem.git?rev=809b2816d3504beeba140fef3fdfe9432d654c5b#809b2816d3504beeba140fef3fdfe9432d654c5b" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fef0e102c6b811e0e01928eed4872b3ff63917f37dc2dab39a93db55f25d314d" dependencies = [ "anyhow", + "async-compression", "bytes", "chrono", "cookie 0.18.1", @@ -13306,12 +13230,12 @@ dependencies = [ "hyper-util", "mime", "multer 3.1.0", - "nix 0.28.0", + "nix 0.29.0", "parking_lot 0.12.1", "percent-encoding", "pin-project-lite", "poem-derive", - "quick-xml 0.32.0", + "quick-xml 0.36.2", "regex", "rfc7239", "rustls-pemfile 2.1.1", @@ -13334,8 +13258,9 @@ dependencies = [ [[package]] name = "poem-derive" -version = "3.0.0" -source = "git+https://github.com/poem-web/poem.git?rev=809b2816d3504beeba140fef3fdfe9432d654c5b#809b2816d3504beeba140fef3fdfe9432d654c5b" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdfed15c1102d2a9a51b9f1aba945628c72ccb52fc5d3e4ad4ffbbd222e11821" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -13345,19 +13270,20 @@ dependencies = [ [[package]] name = "poem-openapi" -version = "5.0.2" -source = "git+https://github.com/poem-web/poem.git?rev=809b2816d3504beeba140fef3fdfe9432d654c5b#809b2816d3504beeba140fef3fdfe9432d654c5b" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c354a706a81a17657da8441869c6ce3d486ef5e72705919d6035fb038a6f7b5" dependencies = [ "base64 0.22.1", "bytes", - "derive_more", + "derive_more 1.0.0", "futures-util", - "indexmap 2.6.0", + "indexmap 2.7.0", "mime", "num-traits", "poem", "poem-openapi-derive", - "quick-xml 0.32.0", + "quick-xml 0.36.2", "regex", "serde", "serde_json", @@ -13370,12 +13296,13 @@ dependencies = [ [[package]] name = "poem-openapi-derive" -version = "5.0.2" -source = "git+https://github.com/poem-web/poem.git?rev=809b2816d3504beeba140fef3fdfe9432d654c5b#809b2816d3504beeba140fef3fdfe9432d654c5b" +version = "5.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88e4cd0c926ab1d9a015ecc1077c950d5897577554691ff70efcd9c90ddeb614" dependencies = [ - "darling 0.20.9", + "darling 0.20.10", "http 1.1.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "mime", "proc-macro-crate 3.1.0", "proc-macro2", @@ -13569,16 +13496,6 @@ dependencies = [ "regex", ] -[[package]] -name = "predicates" -version = "3.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" -dependencies = [ - "anstyle", - "predicates-core", -] - [[package]] name = "predicates-core" version = "1.0.6" @@ -13753,15 +13670,14 @@ dependencies = [ [[package]] name = "processor" version = "1.0.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=51a34901b40d7f75767ac907b4d2478104d6a515#51a34901b40d7f75767ac907b4d2478104d6a515" +source = "git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=3064a075e1abc06c60363f3f2551cc41f5c091de#3064a075e1abc06c60363f3f2551cc41f5c091de" dependencies = [ "ahash 0.8.11", "allocative", "allocative_derive", "anyhow", - "aptos-indexer-processor-sdk", - "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=51a34901b40d7f75767ac907b4d2478104d6a515)", - "aptos-protos 1.3.1 (git+https://github.com/aptos-labs/aptos-core.git?rev=5c48aee129b5a141be2792ffa3d9bd0a1a61c9cb)", + "aptos-moving-average", + "aptos-protos 1.3.1 (git+https://github.com/aptos-labs/aptos-core.git?rev=6116af69aa173ca49e1761daabd6fe103fe2c65e)", "async-trait", "bcs 0.1.4", "bigdecimal", @@ -13769,6 +13685,7 @@ dependencies = [ "canonical_json", "chrono", "clap 4.5.21", + "const_format", "diesel", "diesel-async", "diesel_migrations", @@ -13781,19 +13698,19 @@ dependencies = [ "google-cloud-storage", "hex", "hyper 0.14.28", + "indexmap 2.7.0", "itertools 0.12.1", "jemallocator", "kanal", "lazy_static", "native-tls", - "num 0.4.1", "num_cpus", "once_cell", "parquet", "parquet_derive", "postgres-native-tls", "prometheus", - "prost 0.12.3", + "prost 0.13.4", "rayon", "regex", "serde", @@ -13805,7 +13722,7 @@ dependencies = [ "tiny-keccak", "tokio", "tokio-postgres", - "tonic 0.11.0", + "tonic 0.12.3", "tracing", "unescape", "url", @@ -13843,33 +13760,9 @@ dependencies = [ "lazy_static", "memchr", "parking_lot 0.12.1", - "protobuf", "thiserror", ] -[[package]] -name = "prometheus-client" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" -dependencies = [ - "dtoa", - "itoa", - "parking_lot 0.12.1", - "prometheus-client-derive-encode", -] - -[[package]] -name = "prometheus-client-derive-encode" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "prometheus-http-query" version = "0.5.2" @@ -14111,7 +14004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62ffd2f9a162cfae131bed6d9d1ed60adced33be340a94f96952897d7cb0c240" dependencies = [ "chrono", - "indexmap 2.6.0", + "indexmap 2.7.0", "newtype-uuid", "quick-xml 0.36.2", "strip-ansi-escapes", @@ -14137,16 +14030,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "quick-xml" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "quick-xml" version = "0.36.2" @@ -14154,6 +14037,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" dependencies = [ "memchr", + "serde", ] [[package]] @@ -15141,11 +15025,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "sample" -version = "0.1.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?rev=9ecd252ccff53023664562001dd04c2886488c0d#9ecd252ccff53023664562001dd04c2886488c0d" - [[package]] name = "scale-info" version = "1.0.0" @@ -15154,7 +15033,7 @@ checksum = "5c55b744399c25532d63a0d2789b109df8d46fc93752d46b0782991a931a782f" dependencies = [ "bitvec 0.20.4", "cfg-if", - "derive_more", + "derive_more 0.99.17", "parity-scale-codec 2.3.1", "scale-info-derive", ] @@ -15439,7 +15318,7 @@ version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "ryu", "serde", @@ -15518,7 +15397,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_json", "serde_with_macros", @@ -15531,7 +15410,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" dependencies = [ - "darling 0.20.9", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.87", @@ -15555,7 +15434,7 @@ version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "ryu", "serde", @@ -15585,7 +15464,7 @@ dependencies = [ [[package]] name = "server-framework" version = "1.0.0" -source = "git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=51a34901b40d7f75767ac907b4d2478104d6a515#51a34901b40d7f75767ac907b4d2478104d6a515" +source = "git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=3064a075e1abc06c60363f3f2551cc41f5c091de#3064a075e1abc06c60363f3f2551cc41f5c091de" dependencies = [ "anyhow", "aptos-system-utils 0.1.0 (git+https://github.com/aptos-labs/aptos-core.git?rev=202bdccff2b2d333a385ae86a4fcf23e89da9f62)", @@ -15983,6 +15862,7 @@ dependencies = [ "hex", "hyper 0.14.28", "itertools 0.13.0", + "move-binary-format", "move-core-types", "num_cpus", "once_cell", @@ -16946,7 +16826,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -16959,7 +16839,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "toml_datetime", "winnow", ] @@ -16970,7 +16850,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "toml_datetime", "winnow", ] @@ -17019,7 +16899,6 @@ dependencies = [ "axum 0.6.20", "base64 0.21.7", "bytes", - "flate2", "h2 0.3.26", "http 0.2.11", "http-body 0.4.6", @@ -17028,17 +16907,12 @@ dependencies = [ "percent-encoding", "pin-project 1.1.3", "prost 0.12.3", - "rustls-native-certs 0.7.0", - "rustls-pemfile 2.1.1", - "rustls-pki-types", "tokio", - "tokio-rustls 0.25.0", "tokio-stream", "tower", "tower-layer", "tower-service", "tracing", - "zstd 0.12.4", ] [[package]] @@ -17073,7 +16947,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", - "zstd 0.13.0", + "zstd", ] [[package]] @@ -17657,7 +17531,7 @@ dependencies = [ "errno", "js-sys", "libc", - "rustix 0.38.28", + "rustix 0.37.27", "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", "winapi 0.3.9", @@ -18490,32 +18364,13 @@ dependencies = [ "thiserror", ] -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe 6.0.6", -] - [[package]] name = "zstd" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" dependencies = [ - "zstd-safe 7.0.0", -] - -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" -dependencies = [ - "libc", - "zstd-sys", + "zstd-safe", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7eb0a47c949b8..d70df5de06172 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -492,30 +492,24 @@ arc-swap = "1.6.0" arr_macro = "0.2.1" ark-bls12-381 = "0.4.0" ark-bn254 = "0.4.0" -ark-circom = { git = "https://github.com/aptos-labs/circom-compat", rev = "e3d686641a3dd9d66087a74acdc20dc2a3c24f63" } -ark-crypto-primitives = "0.4.0" ark-ec = "0.4.0" ark-ff = "0.4.0" ark-groth16 = "0.4.0" ark-relations = "0.4.0" ark-serialize = "0.4.0" ark-std = { version = "0.4.0", features = ["getrandom"] } -aptos-moving-average = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "4801acae7aea30d7e96bbfbe5ec5b04056dfa4cf" } +aptos-moving-average = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "3064a075e1abc06c60363f3f2551cc41f5c091de" } assert_approx_eq = "1.1.0" -assert_unordered = "0.3.5" async-channel = "1.7.1" async-mutex = "1.4.0" async-recursion = "1.0.5" -async-stream = "0.3" async-trait = "0.1.53" axum = "0.7.5" base64 = "0.13.0" -base64-url = "2.0.1" backoff = { version = "0.4.0", features = ["tokio"] } backtrace = "0.3.58" bcs = { git = "https://github.com/aptos-labs/bcs.git", rev = "d31fab9d81748e2594be5cd5cdf845786a30562d" } better_any = "0.1.1" -bellman = { version = "0.13.1", default-features = false } bigdecimal = { version = "0.4.0", features = ["serde"] } version-compare = "0.1.1" bitvec = "1.0.1" @@ -530,7 +524,6 @@ byteorder = "1.4.3" bytes = { version = "1.4.0", features = ["serde"] } camino = { version = "1.1.6" } chrono = { version = "0.4.19", features = ["clock", "serde"] } -cfg_block = "0.1.1" cfg-if = "1.0.0" ciborium = "0.2" claims = "0.7" @@ -551,7 +544,6 @@ codespan-reporting = "0.11.1" colored = "2.0.0" concurrent-queue = "2.2.0" console-subscriber = "0.3.0" -const_format = "0.2.26" core_affinity = "0.8.1" coset = "0.3" criterion = "0.3.5" @@ -594,7 +586,6 @@ env_logger = "0.10.0" erased-serde = "0.3.13" ethabi = "18.0.0" ethnum = "1.5.0" -event-listener = "2.5.3" evm = { version = "0.33.1", features = ["tracing"] } evm-runtime = { version = "0.33.0", features = ["tracing"] } dearbitrary = { version = "1.0.4", features = ["derive"] } @@ -632,11 +623,9 @@ hostname = "0.3.1" http = "0.2.9" httpmock = "0.6.8" hyper = { version = "0.14.18", features = ["full"] } -hyper-tls = "0.5.0" im = "15.0.0" image = "0.24.5" -indexmap = "1.9.3" -include_dir = { version = "0.7.2", features = ["glob"] } +indexmap = "2.7.0" indicatif = "0.15.0" indoc = "1.0.6" inferno = "0.11.14" @@ -685,7 +674,6 @@ p256 = { version = "0.13.2" } prettydiff = "0.6.2" primitive-types = { version = "0.10" } signature = "2.1.0" -sec1 = "0.7.0" pairing = "0.23" parking_lot = "0.12.0" paste = "1.0.7" @@ -698,20 +686,16 @@ percent-encoding = "2.1.0" petgraph = "0.6.5" pin-project = "1.0.10" plotters = { version = "0.3.5", default-features = false } -# We're using git deps until https://github.com/poem-web/poem/pull/829 gets formally released. -poem = { git = "https://github.com/poem-web/poem.git", rev = "809b2816d3504beeba140fef3fdfe9432d654c5b", features = [ - "anyhow", - "rustls", -] } -poem-openapi = { git = "https://github.com/poem-web/poem.git", rev = "809b2816d3504beeba140fef3fdfe9432d654c5b", features = [ - "swagger-ui", - "url", -] } -poem-openapi-derive = { git = "https://github.com/poem-web/poem.git", rev = "809b2816d3504beeba140fef3fdfe9432d654c5b" } +poem = { version = "3.1.3", features = ["anyhow", "compression", "rustls"] } +poem-openapi = { version = "5.1.2", features = ["swagger-ui", "url"] } +poem-openapi-derive = "5.1.1" poseidon-ark = { git = "https://github.com/arnaucube/poseidon-ark.git", rev = "6d2487aa1308d9d3860a2b724c485d73095c1c68" } pprof = { version = "0.11", features = ["flamegraph", "protobuf-codec"] } pretty = "0.10.0" pretty_assertions = "1.2.1" +# We set default-features to false so we don't onboard the libpq dep. See more here: +# https://github.com/aptos-labs/aptos-core/pull/12568 +processor = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "3064a075e1abc06c60363f3f2551cc41f5c091de", default-features = false } procfs = "0.14.1" proc-macro2 = "1.0.38" project-root = "0.2.2" @@ -721,8 +705,6 @@ prometheus-parse = "0.2.4" proptest = "1.4.0" proptest-derive = "0.4.0" prost = { version = "0.13.4", features = ["no-recursion-limit"] } -prost-types = "0.13.4" -quanta = "0.10.1" quick_cache = "0.5.1" quick-junit = "0.5.0" quote = "1.0.18" @@ -756,7 +738,6 @@ rstest = "0.15.0" rusty-fork = "0.3.0" rustversion = "1.0.14" scopeguard = "1.2.0" -sha-1 = "0.10.0" sha2 = "0.9.3" sha256 = "1.4.0" sha2_0_10_6 = { package = "sha2", version = "0.10.6" } @@ -777,13 +758,13 @@ serde-generate = { git = "https://github.com/aptos-labs/serde-reflection", rev = serde-reflection = { git = "https://github.com/aptos-labs/serde-reflection", rev = "73b6bbf748334b71ff6d7d09d06a29e3062ca075" } serde_with = "3.4.0" serde_yaml = "0.8.24" +server-framework = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "3064a075e1abc06c60363f3f2551cc41f5c091de" } set_env = "1.3.4" shadow-rs = "0.16.2" simplelog = "0.9.0" smallbitvec = "2.5.1" smallvec = "1.8.0" static_assertions = "1.1.0" -stats_alloc = "0.1.8" status-line = "0.2.0" strum = "0.24.1" strum_macros = "0.24.2" @@ -799,17 +780,14 @@ textwrap = "0.15.0" thiserror = "1.0.37" threadpool = "1.8.1" thread_local = "1.1.7" -time = { version = "0.3.24", features = ["serde"] } tiny-bip39 = "0.8.2" tiny-keccak = { version = "2.0.2", features = ["keccak", "sha3"] } -toml_edit = "0.14.3" tracing = "0.1.37" tracing-subscriber = { version = "0.3.17", features = ["json", "env-filter"] } trybuild = "1.0.80" try_match = "0.4.2" tokio = { version = "1.35.1", features = ["full"] } tokio-io-timeout = "1.2.0" -tokio-metrics = "0.3.1" tokio-retry = "0.3.0" tokio-scoped = { version = "0.2.0" } tokio-stream = { version = "0.1.14", features = ["fs"] } @@ -827,7 +805,6 @@ tonic = { version = "0.12.3", features = [ tonic-reflection = "0.12.3" topological-sort = "0.2.2" triomphe = "0.1.9" -tsify-next = "0.5.4" tui = "0.19.0" typed-arena = "2.0.2" typenum = "1.17.0" diff --git a/api/Cargo.toml b/api/Cargo.toml index fcc5efdca74ec..4bda07ed5528d 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -25,6 +25,7 @@ aptos-logger = { workspace = true } aptos-mempool = { workspace = true } aptos-metrics-core = { workspace = true } aptos-runtimes = { workspace = true } +aptos-sdk = { workspace = true } aptos-storage-interface = { workspace = true } aptos-types = { workspace = true } aptos-vm = { workspace = true } @@ -55,7 +56,6 @@ aptos-gas-meter = { workspace = true } aptos-gas-schedule = { workspace = true, features = ["testing"] } aptos-move-stdlib = { workspace = true } aptos-proptest-helpers = { workspace = true } -aptos-sdk = { workspace = true } move-package = { workspace = true } passkey-types = { workspace = true } percent-encoding = { workspace = true } diff --git a/api/Makefile b/api/Makefile index bebdb02971bbc..a0ba7110c7502 100644 --- a/api/Makefile +++ b/api/Makefile @@ -2,20 +2,14 @@ # Parts of the project are originally copyright © Meta Platforms, Inc. # SPDX-License-Identifier: Apache-2.0 -test: clean lint-v0 lint-v1 test-code-gen-v0 test-code-gen-v1 test-api-spec-v0 test-api-spec-v1 clean +test: clean lint test-code-gen clean -lint-v0: - $(call lint,doc/v0/openapi.yaml) - -lint-v1: - $(call lint,doc/v1/spec.yaml) - -test-code-gen-v0: - $(call test_code_gen,doc/v0/openapi.yaml) +lint: + $(call lint,doc/spec.yaml) # This doesn't work right now: https://github.com/OpenAPITools/openapi-generator/issues/13038. -test-code-gen-v1: - $(call test_code_gen,doc/v1/spec.yaml) +test-code-gen: + $(call test_code_gen,doc/spec.yaml) clean: - pkill aptos-node @@ -23,33 +17,9 @@ clean: - rm -f openapitools.json - rm -rf .hypothesis -test-api-spec-v0: - $(call test_api_spec,openapi.yaml) - -test-api-spec-v1: - $(call test_api_spec,spec.yaml) - serve: cd doc && python3 -m http.server 8888 -define test_api_spec - - pkill aptos-node - cargo build -p aptos-node - ./../target/debug/aptos-node --test --lazy & - - curl https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh > /tmp/wait-for-it.sh - chmod +x /tmp/wait-for-it.sh - /tmp/wait-for-it.sh -t 300 localhost:8080 - - schemathesis run --method GET \ - --show-errors-tracebacks \ - --code-sample-style=curl \ - --store-network-log=./../target/schemathesis-network-log.yaml \ - --checks all \ - --base-url http://localhost:8080 \ - http://localhost:8080/$(1) -endef - define lint npx @redocly/openapi-cli lint $(1) --skip-rule no-empty-servers endef @@ -60,4 +30,4 @@ define test_code_gen cd /tmp/aptos_api_client && cargo build endef -.PHONY: test lint-v0 lint-v1 test-code-gen-v0 test-code-gen-v1 test-api-spec-v0 test-api-spec-v1 clean serve +.PHONY: test lint test-code-gen test-api-spec clean serve diff --git a/api/doc/spec.json b/api/doc/spec.json index c436c7f51082b..5bfa0accdcf43 100644 --- a/api/doc/spec.json +++ b/api/doc/spec.json @@ -1261,6 +1261,608 @@ "operationId": "get_account_resources" } }, + "/accounts/{address}/balance/{asset_type}": { + "get": { + "tags": [ + "Accounts" + ], + "summary": "Get account resources", + "description": "Retrieves all account resources for a given account and a specific ledger version. If the\nledger version is not specified in the request, the latest ledger version is used.\n\nThe Aptos nodes prune account state history, via a configurable time window.\nIf the requested ledger version has been pruned, the server responds with a 410.", + "parameters": [ + { + "name": "address", + "schema": { + "$ref": "#/components/schemas/Address" + }, + "in": "path", + "description": "Address of account with or without a `0x` prefix", + "required": true, + "deprecated": false, + "explode": true + }, + { + "name": "asset_type", + "schema": { + "$ref": "#/components/schemas/AssetType" + }, + "in": "path", + "required": true, + "deprecated": false, + "explode": true + }, + { + "name": "ledger_version", + "schema": { + "$ref": "#/components/schemas/U64" + }, + "in": "query", + "description": "Ledger version to get state of account\n\nIf not provided, it will be the latest version", + "required": false, + "deprecated": false, + "explode": true + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "application/x-bcs": { + "schema": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8" + } + } + } + }, + "headers": { + "X-APTOS-CHAIN-ID": { + "description": "Chain ID of the current chain", + "required": true, + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint8" + } + }, + "X-APTOS-LEDGER-VERSION": { + "description": "Current ledger version of the chain", + "required": true, + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-OLDEST-VERSION": { + "description": "Oldest non-pruned ledger version of the chain", + "required": true, + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-TIMESTAMPUSEC": { + "description": "Current timestamp of the chain", + "required": true, + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-EPOCH": { + "description": "Current epoch of the chain", + "required": true, + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-BLOCK-HEIGHT": { + "description": "Current block height of the chain", + "required": true, + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-OLDEST-BLOCK-HEIGHT": { + "description": "Oldest non-pruned block height of the chain", + "required": true, + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-GAS-USED": { + "description": "The cost of the call in terms of gas", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-CURSOR": { + "description": "Cursor to be used for endpoints that support cursor-based\npagination. Pass this to the `start` field of the endpoint\non the next call to get the next page of results.", + "deprecated": false, + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AptosError" + } + } + }, + "headers": { + "X-APTOS-CHAIN-ID": { + "description": "Chain ID of the current chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint8" + } + }, + "X-APTOS-LEDGER-VERSION": { + "description": "Current ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-OLDEST-VERSION": { + "description": "Oldest non-pruned ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-TIMESTAMPUSEC": { + "description": "Current timestamp of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-EPOCH": { + "description": "Current epoch of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-BLOCK-HEIGHT": { + "description": "Current block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-OLDEST-BLOCK-HEIGHT": { + "description": "Oldest non-pruned block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-GAS-USED": { + "description": "The cost of the call in terms of gas", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + } + } + }, + "403": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AptosError" + } + } + }, + "headers": { + "X-APTOS-CHAIN-ID": { + "description": "Chain ID of the current chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint8" + } + }, + "X-APTOS-LEDGER-VERSION": { + "description": "Current ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-OLDEST-VERSION": { + "description": "Oldest non-pruned ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-TIMESTAMPUSEC": { + "description": "Current timestamp of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-EPOCH": { + "description": "Current epoch of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-BLOCK-HEIGHT": { + "description": "Current block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-OLDEST-BLOCK-HEIGHT": { + "description": "Oldest non-pruned block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-GAS-USED": { + "description": "The cost of the call in terms of gas", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + } + } + }, + "404": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AptosError" + } + } + }, + "headers": { + "X-APTOS-CHAIN-ID": { + "description": "Chain ID of the current chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint8" + } + }, + "X-APTOS-LEDGER-VERSION": { + "description": "Current ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-OLDEST-VERSION": { + "description": "Oldest non-pruned ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-TIMESTAMPUSEC": { + "description": "Current timestamp of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-EPOCH": { + "description": "Current epoch of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-BLOCK-HEIGHT": { + "description": "Current block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-OLDEST-BLOCK-HEIGHT": { + "description": "Oldest non-pruned block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-GAS-USED": { + "description": "The cost of the call in terms of gas", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + } + } + }, + "410": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AptosError" + } + } + }, + "headers": { + "X-APTOS-CHAIN-ID": { + "description": "Chain ID of the current chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint8" + } + }, + "X-APTOS-LEDGER-VERSION": { + "description": "Current ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-OLDEST-VERSION": { + "description": "Oldest non-pruned ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-TIMESTAMPUSEC": { + "description": "Current timestamp of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-EPOCH": { + "description": "Current epoch of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-BLOCK-HEIGHT": { + "description": "Current block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-OLDEST-BLOCK-HEIGHT": { + "description": "Oldest non-pruned block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-GAS-USED": { + "description": "The cost of the call in terms of gas", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + } + } + }, + "500": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AptosError" + } + } + }, + "headers": { + "X-APTOS-CHAIN-ID": { + "description": "Chain ID of the current chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint8" + } + }, + "X-APTOS-LEDGER-VERSION": { + "description": "Current ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-OLDEST-VERSION": { + "description": "Oldest non-pruned ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-TIMESTAMPUSEC": { + "description": "Current timestamp of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-EPOCH": { + "description": "Current epoch of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-BLOCK-HEIGHT": { + "description": "Current block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-OLDEST-BLOCK-HEIGHT": { + "description": "Oldest non-pruned block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-GAS-USED": { + "description": "The cost of the call in terms of gas", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + } + } + }, + "503": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AptosError" + } + } + }, + "headers": { + "X-APTOS-CHAIN-ID": { + "description": "Chain ID of the current chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint8" + } + }, + "X-APTOS-LEDGER-VERSION": { + "description": "Current ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-OLDEST-VERSION": { + "description": "Oldest non-pruned ledger version of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-LEDGER-TIMESTAMPUSEC": { + "description": "Current timestamp of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-EPOCH": { + "description": "Current epoch of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-BLOCK-HEIGHT": { + "description": "Current block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-OLDEST-BLOCK-HEIGHT": { + "description": "Oldest non-pruned block height of the chain", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + }, + "X-APTOS-GAS-USED": { + "description": "The cost of the call in terms of gas", + "deprecated": false, + "schema": { + "type": "integer", + "format": "uint64" + } + } + } + } + }, + "operationId": "get_account_balance" + } + }, "/accounts/{address}/modules": { "get": { "tags": [ @@ -13959,6 +14561,21 @@ }, "components": { "schemas": { + "AbstractionSignature": { + "type": "object", + "required": [ + "function_info", + "auth_data" + ], + "properties": { + "function_info": { + "type": "string" + }, + "auth_data": { + "$ref": "#/components/schemas/HexEncodedBytes" + } + } + }, "AccountData": { "type": "object", "description": "Account data\n\nA simplified version of the onchain Account resource", @@ -13993,6 +14610,9 @@ }, { "$ref": "#/components/schemas/AccountSignature_NoAccountSignature" + }, + { + "$ref": "#/components/schemas/AccountSignature_AbstractionSignature" } ], "discriminator": { @@ -14002,10 +14622,33 @@ "multi_ed25519_signature": "#/components/schemas/AccountSignature_MultiEd25519Signature", "single_key_signature": "#/components/schemas/AccountSignature_SingleKeySignature", "multi_key_signature": "#/components/schemas/AccountSignature_MultiKeySignature", - "no_account_signature": "#/components/schemas/AccountSignature_NoAccountSignature" + "no_account_signature": "#/components/schemas/AccountSignature_NoAccountSignature", + "abstraction_signature": "#/components/schemas/AccountSignature_AbstractionSignature" } } }, + "AccountSignature_AbstractionSignature": { + "allOf": [ + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "abstraction_signature" + ], + "example": "abstraction_signature" + } + } + }, + { + "$ref": "#/components/schemas/AbstractionSignature" + } + ] + }, "AccountSignature_Ed25519Signature": { "allOf": [ { @@ -14171,6 +14814,12 @@ "api_disabled" ] }, + "AssetType": { + "type": "string", + "format": "hex", + "description": "A hex encoded 32 byte Aptos account address or a struct tag.\n\nThis is represented in a string as a 64 character hex string, sometimes\nshortened by stripping leading 0s, and adding a 0x or\nFormat: `{address}::{module name}::{struct name}`\n", + "example": "0x1::aptos_coin::AptosCoin" + }, "Block": { "type": "object", "description": "A Block with or without transactions\n\nThis contains the information about a transactions along with\nassociated transactions if requested", diff --git a/api/doc/spec.yaml b/api/doc/spec.yaml index 8fef310321eda..5364dfa20571a 100644 --- a/api/doc/spec.yaml +++ b/api/doc/spec.yaml @@ -933,6 +933,453 @@ paths: type: integer format: uint64 operationId: get_account_resources + /accounts/{address}/balance/{asset_type}: + get: + tags: + - Accounts + summary: Get account resources + description: |- + 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. + parameters: + - name: address + schema: + $ref: '#/components/schemas/Address' + in: path + description: Address of account with or without a `0x` prefix + required: true + deprecated: false + explode: true + - name: asset_type + schema: + $ref: '#/components/schemas/AssetType' + in: path + required: true + deprecated: false + explode: true + - name: ledger_version + schema: + $ref: '#/components/schemas/U64' + in: query + description: |- + Ledger version to get state of account + + If not provided, it will be the latest version + required: false + deprecated: false + explode: true + responses: + '200': + description: '' + content: + application/json: + schema: + type: integer + format: uint64 + application/x-bcs: + schema: + type: array + items: + type: integer + format: uint8 + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + required: true + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + required: true + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-CURSOR: + description: |- + Cursor to be used for endpoints that support cursor-based + pagination. Pass this to the `start` field of the endpoint + on the next call to get the next page of results. + deprecated: false + schema: + type: string + '400': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '403': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '404': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '410': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '500': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + '503': + description: '' + content: + application/json: + schema: + $ref: '#/components/schemas/AptosError' + headers: + X-APTOS-CHAIN-ID: + description: Chain ID of the current chain + deprecated: false + schema: + type: integer + format: uint8 + X-APTOS-LEDGER-VERSION: + description: Current ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-OLDEST-VERSION: + description: Oldest non-pruned ledger version of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-LEDGER-TIMESTAMPUSEC: + description: Current timestamp of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-EPOCH: + description: Current epoch of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-BLOCK-HEIGHT: + description: Current block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-OLDEST-BLOCK-HEIGHT: + description: Oldest non-pruned block height of the chain + deprecated: false + schema: + type: integer + format: uint64 + X-APTOS-GAS-USED: + description: The cost of the call in terms of gas + deprecated: false + schema: + type: integer + format: uint64 + operationId: get_account_balance /accounts/{address}/modules: get: tags: @@ -10438,6 +10885,16 @@ paths: operationId: view components: schemas: + AbstractionSignature: + type: object + required: + - function_info + - auth_data + properties: + function_info: + type: string + auth_data: + $ref: '#/components/schemas/HexEncodedBytes' AccountData: type: object description: |- @@ -10468,6 +10925,7 @@ components: - $ref: '#/components/schemas/AccountSignature_SingleKeySignature' - $ref: '#/components/schemas/AccountSignature_MultiKeySignature' - $ref: '#/components/schemas/AccountSignature_NoAccountSignature' + - $ref: '#/components/schemas/AccountSignature_AbstractionSignature' discriminator: propertyName: type mapping: @@ -10476,6 +10934,19 @@ components: single_key_signature: '#/components/schemas/AccountSignature_SingleKeySignature' multi_key_signature: '#/components/schemas/AccountSignature_MultiKeySignature' no_account_signature: '#/components/schemas/AccountSignature_NoAccountSignature' + abstraction_signature: '#/components/schemas/AccountSignature_AbstractionSignature' + AccountSignature_AbstractionSignature: + allOf: + - type: object + required: + - type + properties: + type: + type: string + enum: + - abstraction_signature + example: abstraction_signature + - $ref: '#/components/schemas/AbstractionSignature' AccountSignature_Ed25519Signature: allOf: - type: object @@ -10592,6 +11063,16 @@ components: - web_framework_error - bcs_not_supported - api_disabled + AssetType: + type: string + format: hex + description: | + A hex encoded 32 byte Aptos account address or a struct tag. + + This is represented in a string as a 64 character hex string, sometimes + shortened by stripping leading 0s, and adding a 0x or + Format: `{address}::{module name}::{struct name}` + example: 0x1::aptos_coin::AptosCoin Block: type: object description: |- diff --git a/api/src/accounts.rs b/api/src/accounts.rs index d94454f6b34e3..4427f01b2f2c7 100644 --- a/api/src/accounts.rs +++ b/api/src/accounts.rs @@ -15,11 +15,15 @@ use crate::{ }; use anyhow::Context as AnyhowContext; use aptos_api_types::{ - AccountData, Address, AptosErrorCode, AsConverter, LedgerInfo, MoveModuleBytecode, + AccountData, Address, AptosErrorCode, AsConverter, AssetType, LedgerInfo, MoveModuleBytecode, MoveModuleId, MoveResource, MoveStructTag, StateKeyWrapper, U64, }; +use aptos_sdk::types::{get_paired_fa_metadata_address, get_paired_fa_primary_store_address}; use aptos_types::{ - account_config::{AccountResource, ObjectGroupResource}, + account_config::{ + AccountResource, CoinStoreResourceUntyped, ConcurrentFungibleBalanceResource, + FungibleStoreResource, ObjectGroupResource, + }, event::{EventHandle, EventKey}, state_store::state_key::StateKey, }; @@ -30,7 +34,7 @@ use poem_openapi::{ param::{Path, Query}, OpenApi, }; -use std::{collections::BTreeMap, convert::TryInto, sync::Arc}; +use std::{collections::BTreeMap, convert::TryInto, str::FromStr, sync::Arc}; /// API for accounts, their associated resources, and modules pub struct AccountsApi { @@ -124,6 +128,42 @@ impl AccountsApi { .await } + /// 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. + #[oai( + path = "/accounts/:address/balance/:asset_type", + method = "get", + operation_id = "get_account_balance", + tag = "ApiTags::Accounts" + )] + async fn get_account_balance( + &self, + accept_type: AcceptType, + /// Address of account with or without a `0x` prefix + address: Path
, + asset_type: Path, + /// Ledger version to get state of account + /// + /// If not provided, it will be the latest version + ledger_version: Query>, + ) -> BasicResultWith404 { + fail_point_poem("endpoint_get_account_balance")?; + self.context + .check_api_output_enabled("Get account balance", &accept_type)?; + + let context = self.context.clone(); + api_spawn_blocking(move || { + let account = Account::new(context, address.0, ledger_version.0, None, None)?; + account.balance(asset_type.0, &accept_type) + }) + .await + } + /// Get account modules /// /// Retrieves all account modules' bytecode for a given account at a specific ledger version. @@ -251,6 +291,113 @@ impl Account { } } + pub fn balance( + &self, + asset_type: AssetType, + accept_type: &AcceptType, + ) -> BasicResultWith404 { + let (fa_metadata_address, mut balance) = match asset_type { + AssetType::Coin(move_struct_tag) => { + let coin_store_type_tag = + StructTag::from_str(&format!("0x1::coin::CoinStore<{}>", move_struct_tag)) + .map_err(|err| { + BasicErrorWith404::internal_with_code( + err, + AptosErrorCode::InternalError, + &self.latest_ledger_info, + ) + })?; + // query coin balance + let state_value = self.context.get_state_value_poem( + &StateKey::resource(&self.address.into(), &coin_store_type_tag).map_err( + |err| { + BasicErrorWith404::internal_with_code( + err, + AptosErrorCode::InternalError, + &self.latest_ledger_info, + ) + }, + )?, + self.ledger_version, + &self.latest_ledger_info, + )?; + let coin_balance = match state_value { + None => 0, + Some(bytes) => bcs::from_bytes::(&bytes) + .map_err(|err| { + BasicErrorWith404::internal_with_code( + err, + AptosErrorCode::InternalError, + &self.latest_ledger_info, + ) + })? + .coin(), + }; + ( + get_paired_fa_metadata_address(&move_struct_tag), + coin_balance, + ) + }, + AssetType::FungibleAsset(fa_metadata_adddress) => (fa_metadata_adddress.into(), 0), + }; + let primary_fungible_store_address = + get_paired_fa_primary_store_address(self.address.into(), fa_metadata_address); + if let Some(data_blob) = self.context.get_state_value_poem( + &StateKey::resource_group( + &primary_fungible_store_address, + &ObjectGroupResource::struct_tag(), + ), + self.ledger_version, + &self.latest_ledger_info, + )? { + if let Ok(object_group) = bcs::from_bytes::(&data_blob) { + if let Some(fa_store) = object_group.group.get(&FungibleStoreResource::struct_tag()) + { + let fa_store_resource = bcs::from_bytes::(fa_store) + .map_err(|err| { + BasicErrorWith404::internal_with_code( + err, + AptosErrorCode::InternalError, + &self.latest_ledger_info, + ) + })?; + if fa_store_resource.balance != 0 { + balance += fa_store_resource.balance(); + } else if let Some(concurrent_fa_balance) = object_group + .group + .get(&ConcurrentFungibleBalanceResource::struct_tag()) + { + // query potential concurrent fa balance + let concurrent_fa_balance_resource = + bcs::from_bytes::( + concurrent_fa_balance, + ) + .map_err(|err| { + BasicErrorWith404::internal_with_code( + err, + AptosErrorCode::InternalError, + &self.latest_ledger_info, + ) + })?; + balance += concurrent_fa_balance_resource.balance(); + } + } + } + } + match accept_type { + AcceptType::Json => BasicResponse::try_from_json(( + balance, + &self.latest_ledger_info, + BasicResponseStatus::Ok, + )), + AcceptType::Bcs => BasicResponse::try_from_encoded(( + bcs::to_bytes(&balance).unwrap(), + &self.latest_ledger_info, + BasicResponseStatus::Ok, + )), + } + } + pub fn get_account_resource(&self) -> Result, BasicErrorWith404> { let state_key = StateKey::resource_typed::(self.address.inner()).map_err(|e| { diff --git a/api/src/runtime.rs b/api/src/runtime.rs index 31e30eb64302e..7c3ab2343788d 100644 --- a/api/src/runtime.rs +++ b/api/src/runtime.rs @@ -29,7 +29,7 @@ use poem::{ handler, http::Method, listener::{Listener, RustlsCertificate, RustlsConfig, TcpListener}, - middleware::Cors, + middleware::{Compression, Cors}, web::Html, EndpointExt, Route, Server, }; @@ -180,6 +180,7 @@ pub fn attach_poem_to_runtime( let spec_json = spec_endpoint_json(&api_service); let spec_yaml = spec_endpoint_yaml(&api_service); + let config = config.clone(); let mut address = config.api.address; if random_port { @@ -251,6 +252,7 @@ pub fn attach_poem_to_runtime( ), ) .with(cors) + .with_if(config.api.compression_enabled, Compression::new()) .with(PostSizeLimit::new(size_limit)) // NOTE: Make sure to keep this after all the `with` middleware. .catch_all_error(convert_error) diff --git a/api/src/tests/account_abstraction_test.rs b/api/src/tests/account_abstraction_test.rs new file mode 100644 index 0000000000000..0e507ec251f3e --- /dev/null +++ b/api/src/tests/account_abstraction_test.rs @@ -0,0 +1,188 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use super::new_test_context; +use aptos_api_test_context::{current_function_name, TestContext}; +use aptos_crypto::{ + bls12381::{PrivateKey, PublicKey}, + test_utils::KeyPair, + SigningKey, Uniform, +}; +use aptos_types::{ + function_info::FunctionInfo, + transaction::{EntryFunction, TransactionStatus}, +}; +use move_core_types::{identifier::Identifier, language_storage::ModuleId, vm_status::StatusCode}; +use rand::rngs::OsRng; +use serde_json::json; +use std::{path::PathBuf, sync::Arc}; + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_account_abstraction_single_signer() { + let key_pair = Arc::new(KeyPair::::generate(&mut OsRng)); + + let mut context = new_test_context(current_function_name!()); + let mut account = context.create_account().await; + let user_addr = account.address(); + let other = context.create_account().await; + + // Publish packages + let named_addresses = vec![("aa".to_string(), user_addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")) + .join("../aptos-move/move-examples/account_abstraction/bls12381_single_key"); + TestContext::build_package(path, named_addresses) + }); + context.publish_package(&mut account, txn).await; + + let txn0 = context.mint_user_account(&account).await; + context.commit_block(&vec![txn0]).await; + + context + .api_execute_entry_function( + &mut account, + &format!("0x{}::single_key::update_public_key", user_addr.to_hex()), + json!([]), + json!([hex::encode(key_pair.public_key.to_bytes())]), + ) + .await; + + let func_info = FunctionInfo::new( + user_addr, + "single_key".to_string(), + "authenticate".to_string(), + ); + let txn3 = context + .add_dispatchable_authentication_function(&account, func_info.clone()) + .await; + context.commit_block(&vec![txn3]).await; + + let factory = context.transaction_factory(); + + let fake_sign = Arc::new(|_: &[u8]| b"invalid_signature".to_vec()); + // case 1: invalid aa signature + account.set_abstraction_auth(func_info.clone(), fake_sign); + let aa_txn = account.sign_aa_transaction_with_transaction_builder( + vec![], + None, + factory + .account_transfer(other.address(), 1) + .expiration_timestamp_secs(u64::MAX), + ); + + let txn_status = context.try_commit_block(&vec![aa_txn]).await; + assert!(matches!( + txn_status.last(), + Some(TransactionStatus::Discard(StatusCode::ABORTED)) + )); + // decrement seq num for aborted txn. + account.decrement_sequence_number(); + + // case 2: successful AA txn. + let sign_func = Arc::new(move |x: &[u8]| { + key_pair + .private_key + .sign_arbitrary_message(x) + .to_bytes() + .to_vec() + }); + account.set_abstraction_auth(func_info.clone(), sign_func); + let balance_start = context.get_apt_balance(other.address()).await; + let aa_txn = account.sign_aa_transaction_with_transaction_builder( + vec![], + None, + factory + .account_transfer(other.address(), 4) + .expiration_timestamp_secs(u64::MAX), + ); + context + .expect_status_code(202) + .post_bcs_txn("/transactions", bcs::to_bytes(&aa_txn).unwrap()) + .await; + context.commit_mempool_txns(1).await; + assert_eq!( + balance_start + 4, + context.get_apt_balance(other.address()).await + ); +} + +/// This tests a function with params (signer_a, signer_b, signer_c, d) works for the AA authentication flow. +/// a, c are AA; b, d are normal ed25519 accounts. +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_account_abstraction_multi_agent_with_abstracted_sender() { + let key_pair = Arc::new(KeyPair::::generate(&mut OsRng)); + let mut context = new_test_context(current_function_name!()); + let mut a = context.create_account().await; + let b = context.create_account().await; + let mut c = context.create_account().await; + let d = context.create_account().await; + let a_addr = a.address(); + + // Publish packages + let named_addresses = vec![("aa".to_string(), a_addr)]; + let txn = futures::executor::block_on(async move { + let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")) + .join("../aptos-move/move-examples/account_abstraction/bls12381_single_key"); + TestContext::build_package(path, named_addresses) + }); + context.publish_package(&mut a, txn).await; + + context + .commit_block(&vec![context.mint_user_account(&a).await]) + .await; + context + .commit_block(&vec![context.mint_user_account(&b).await]) + .await; + context + .commit_block(&vec![context.mint_user_account(&c).await]) + .await; + + // Convert c to aa + context + .api_execute_entry_function( + &mut c, + &format!("0x{}::single_key::update_public_key", a_addr.to_hex()), + json!([]), + json!([hex::encode(key_pair.public_key.to_bytes())]), + ) + .await; + let func_info = FunctionInfo::new(a_addr, "single_key".to_string(), "authenticate".to_string()); + let txn = context + .add_dispatchable_authentication_function(&c, func_info.clone()) + .await; + context.commit_block(&vec![txn]).await; + + let sign_func = Arc::new(move |x: &[u8]| { + key_pair + .private_key + .sign_arbitrary_message(x) + .to_bytes() + .to_vec() + }); + c.set_abstraction_auth(func_info, sign_func); + + let factory = context.transaction_factory(); + let balance_start = context.get_apt_balance(d.address()).await; + let aa_txn = a.sign_aa_transaction_with_transaction_builder( + vec![&b, &c], + None, + factory + .entry_function(EntryFunction::new( + ModuleId::new(a_addr, Identifier::new("test_functions").unwrap()), + Identifier::new("transfer_to_the_last").unwrap(), + vec![], + vec![bcs::to_bytes(&d.address()).unwrap()], + )) + .expiration_timestamp_secs(u64::MAX), + ); + context + .expect_status_code(202) + .post_bcs_txn("/transactions", bcs::to_bytes(&aa_txn).unwrap()) + .await; + context.commit_mempool_txns(1).await; + assert_eq!( + balance_start + 3, + context.get_apt_balance(d.address()).await + ); +} diff --git a/api/src/tests/accounts_test.rs b/api/src/tests/accounts_test.rs index b5bac410dc0c9..676dede993396 100644 --- a/api/src/tests/accounts_test.rs +++ b/api/src/tests/accounts_test.rs @@ -7,6 +7,18 @@ use crate::tests::new_test_context_with_db_sharding_and_internal_indexer; use aptos_api_test_context::{current_function_name, find_value, TestContext}; use aptos_api_types::{MoveModuleBytecode, MoveResource, MoveStructTag, StateKeyWrapper}; use aptos_cached_packages::aptos_stdlib; +use aptos_sdk::types::APTOS_COIN_TYPE_STR; +use aptos_types::{ + account_config::{primary_apt_store, ObjectCoreResource}, + transaction::{EntryFunction, TransactionPayload}, + AptosCoinType, CoinType, +}; +use move_core_types::{ + account_address::AccountAddress, + identifier::Identifier, + language_storage::{ModuleId, TypeTag}, + move_resource::MoveStructType, +}; use serde_json::json; use std::str::FromStr; @@ -179,6 +191,56 @@ async fn test_get_account_resources_by_invalid_ledger_version() { context.check_golden_output(resp); } +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_get_account_balance() { + let mut context = new_test_context(current_function_name!()); + let root_account = context.root_account().await; + let coin_balance_before = context + .get(&account_balance( + &root_account.address().to_hex_literal(), + APTOS_COIN_TYPE_STR, + )) + .await; + let txn = root_account.sign_with_transaction_builder(context.transaction_factory().payload( + aptos_stdlib::coin_migrate_to_fungible_store(AptosCoinType::type_tag()), + )); + context.commit_block(&vec![txn.clone()]).await; + let coin_balance_after = context + .get(&account_balance( + &root_account.address().to_hex_literal(), + APTOS_COIN_TYPE_STR, + )) + .await; + assert_eq!(coin_balance_before, coin_balance_after); + let fa_balance = context + .get(&account_balance( + &root_account.address().to_hex_literal(), + &AccountAddress::TEN.to_hex_literal(), + )) + .await; + assert_eq!(coin_balance_after, fa_balance); + // upgrade to concurrent store + let txn = root_account.sign_with_transaction_builder(context.transaction_factory().payload( + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::TEN, + Identifier::new("fungible_asset").unwrap(), + ), + Identifier::new("upgrade_store_to_concurrent").unwrap(), + vec![TypeTag::Struct(Box::new(ObjectCoreResource::struct_tag()))], + vec![bcs::to_bytes(&primary_apt_store(root_account.address())).unwrap()], + )), + )); + context.commit_block(&vec![txn.clone()]).await; + let concurrent_fa_balance = context + .get(&account_balance( + &root_account.address().to_hex_literal(), + &AccountAddress::TEN.to_hex_literal(), + )) + .await; + assert_eq!(concurrent_fa_balance, fa_balance); +} + async fn test_get_account_modules_by_ledger_version_with_context(mut context: TestContext) { let payload = aptos_stdlib::publish_module_source("test_module", "module 0xa550c18::test_module {}"); @@ -425,6 +487,10 @@ fn account_modules(address: &str) -> String { format!("/accounts/{}/modules", address) } +fn account_balance(address: &str, coin_type: &str) -> String { + format!("/accounts/{}/balance/{}", address, coin_type) +} + fn account_modules_with_ledger_version(address: &str, ledger_version: i128) -> String { format!( "{}?ledger_version={}", diff --git a/api/src/tests/index_test.rs b/api/src/tests/index_test.rs index a542e87972e6d..96bc8a1d2ce12 100644 --- a/api/src/tests/index_test.rs +++ b/api/src/tests/index_test.rs @@ -122,3 +122,24 @@ async fn test_cors_on_non_200_responses() { let cors_header = resp.headers().get("access-control-allow-origin").unwrap(); assert_eq!(cors_header, "test"); } + +/// Verifies gzip compression is applied when accept-encoding header is present +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_compression_middleware() { + let context = new_test_context(current_function_name!()); + + let req = warp::test::request() + .header("accept-encoding", "gzip") + .method("GET") + .path("/v1/info"); + + let resp = context.reply(req).await; + assert_eq!(resp.status(), 200); + let content_encoding = resp.headers().get("content-encoding").unwrap(); + assert_eq!(content_encoding, "gzip"); + + let req = warp::test::request().method("GET").path("/v1/info"); + let resp = context.reply(req).await; + assert_eq!(resp.status(), 200); + assert!(resp.headers().get("content-encoding").is_none()); +} diff --git a/api/src/tests/mod.rs b/api/src/tests/mod.rs index 43468220043b8..ff6325fa6b796 100644 --- a/api/src/tests/mod.rs +++ b/api/src/tests/mod.rs @@ -2,6 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 +mod account_abstraction_test; mod accounts_test; mod blocks_test; mod converter_test; diff --git a/api/test-context/src/test_context.rs b/api/test-context/src/test_context.rs index 70fbc75adf4db..0f9c9de274b93 100644 --- a/api/test-context/src/test_context.rs +++ b/api/test-context/src/test_context.rs @@ -42,6 +42,7 @@ use aptos_types::{ block_info::BlockInfo, block_metadata::BlockMetadata, chain_id::ChainId, + function_info::FunctionInfo, indexer::indexer_db_reader::IndexerReader, ledger_info::{LedgerInfo, LedgerInfoWithSignatures}, transaction::{ @@ -512,6 +513,19 @@ impl TestContext { ) } + pub async fn add_dispatchable_authentication_function( + &self, + account: &LocalAccount, + func: FunctionInfo, + ) -> SignedTransaction { + let factory = self.transaction_factory(); + account.sign_with_transaction_builder( + factory + .add_dispatchable_authentication_function(func) + .expiration_timestamp_secs(u64::MAX), + ) + } + pub async fn execute_multisig_transaction( &mut self, owner: &mut LocalAccount, @@ -777,7 +791,10 @@ impl TestContext { } } - pub async fn commit_block(&mut self, signed_txns: &[SignedTransaction]) { + pub async fn try_commit_block( + &mut self, + signed_txns: &[SignedTransaction], + ) -> Vec { let metadata = self.new_block_metadata(); let timestamp = metadata.timestamp_usecs(); let txns: Vec = std::iter::once(Transaction::BlockMetadata(metadata.clone())) @@ -801,28 +818,36 @@ impl TestContext { .unwrap(); let compute_status = result.compute_status_for_input_txns().clone(); assert_eq!(compute_status.len(), txns.len(), "{:?}", result); - // But the rest of the txns must be Kept. - for st in compute_status { + if !compute_status + .iter() + .any(|s| !matches!(&s, TransactionStatus::Keep(_))) + { + self.executor + .commit_blocks( + vec![metadata.id()], + // StateCheckpoint/BlockEpilogue is added on top of the input transactions. + self.new_ledger_info(&metadata, result.root_hash(), txns.len() + 1), + ) + .unwrap(); + + self.mempool + .mempool_notifier + .notify_new_commit(txns, timestamp) + .await + .unwrap(); + } + compute_status + } + + pub async fn commit_block(&mut self, signed_txns: &[SignedTransaction]) { + // The txns must be kept. + for st in self.try_commit_block(signed_txns).await { match st { TransactionStatus::Discard(st) => panic!("transaction is discarded: {:?}", st), TransactionStatus::Retry => panic!("should not retry"), TransactionStatus::Keep(_) => (), } } - - self.executor - .commit_blocks( - vec![metadata.id()], - // StateCheckpoint/BlockEpilogue is added on top of the input transactions. - self.new_ledger_info(&metadata, result.root_hash(), txns.len() + 1), - ) - .unwrap(); - - self.mempool - .mempool_notifier - .notify_new_commit(txns, timestamp) - .await - .unwrap(); } pub async fn get_sequence_number(&self, account: AccountAddress) -> u64 { diff --git a/api/types/src/account.rs b/api/types/src/account.rs index f232248e3af37..9a2f75efcd10a 100644 --- a/api/types/src/account.rs +++ b/api/types/src/account.rs @@ -2,10 +2,11 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::{HexEncodedBytes, U64}; +use crate::{Address, HexEncodedBytes, MoveStructTag, U64}; use aptos_types::account_config::AccountResource; use poem_openapi::Object; -use serde::{Deserialize, Serialize}; +use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; +use std::{fmt::Debug, str::FromStr}; /// Account data /// @@ -25,3 +26,42 @@ impl From for AccountData { } } } + +/// An Enum for referencing an asset type, either coin or fungible asset. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum AssetType { + Coin(MoveStructTag), + FungibleAsset(Address), +} + +impl FromStr for AssetType { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match Address::from_str(s) { + Ok(address) => Ok(AssetType::FungibleAsset(address)), + Err(_) => match MoveStructTag::from_str(s) { + Ok(tag) => Ok(AssetType::Coin(tag)), + Err(e) => Err(e), + }, + } + } +} +impl Serialize for AssetType { + fn serialize(&self, serializer: S) -> Result { + match self { + Self::Coin(struct_tag) => MoveStructTag::serialize(struct_tag, serializer), + Self::FungibleAsset(addr) => Address::serialize(addr, serializer), + } + } +} + +impl<'de> Deserialize<'de> for AssetType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let data = ::deserialize(deserializer)?; + data.parse().map_err(D::Error::custom) + } +} diff --git a/api/types/src/derives.rs b/api/types/src/derives.rs index 8964633db43ef..06a3db2596fcd 100644 --- a/api/types/src/derives.rs +++ b/api/types/src/derives.rs @@ -20,8 +20,8 @@ use crate::{ move_types::{MoveAbility, MoveStructValue}, - Address, EntryFunctionId, HashValue, HexEncodedBytes, IdentifierWrapper, MoveModuleId, - MoveStructTag, MoveType, StateKeyWrapper, U128, U256, U64, + Address, AssetType, EntryFunctionId, HashValue, HexEncodedBytes, IdentifierWrapper, + MoveModuleId, MoveStructTag, MoveType, StateKeyWrapper, U128, U256, U64, }; use aptos_openapi::{impl_poem_parameter, impl_poem_type}; use indoc::indoc; @@ -46,6 +46,24 @@ impl_poem_type!( ) ); +impl_poem_type!( + AssetType, + "string", + ( + example = Some(serde_json::Value::String( + "0x1::aptos_coin::AptosCoin".to_string() + )), + format = Some("hex"), + description = Some(indoc! {" + A hex encoded 32 byte Aptos account address or a struct tag. + + This is represented in a string as a 64 character hex string, sometimes + shortened by stripping leading 0s, and adding a 0x or + Format: `{address}::{module name}::{struct name}` + "}) + ) +); + impl_poem_type!( EntryFunctionId, "string", @@ -293,6 +311,7 @@ impl_poem_type!( impl_poem_parameter!( Address, + AssetType, HashValue, IdentifierWrapper, HexEncodedBytes, diff --git a/api/types/src/lib.rs b/api/types/src/lib.rs index e7ab206cde38a..0fc27da27a0a0 100644 --- a/api/types/src/lib.rs +++ b/api/types/src/lib.rs @@ -23,7 +23,7 @@ pub mod transaction; mod view; mod wrappers; -pub use account::AccountData; +pub use account::{AccountData, AssetType}; pub use address::Address; pub use block::{BcsBlock, Block}; pub use bytecode::Bytecode; @@ -45,17 +45,17 @@ pub use state::RawStateValueRequest; use std::str::FromStr; pub use table::{RawTableItemRequest, TableItemRequest}; pub use transaction::{ - AccountSignature, BlockMetadataTransaction, DeleteModule, DeleteResource, DeleteTableItem, - DirectWriteSet, Ed25519Signature, EncodeSubmissionRequest, EntryFunctionPayload, Event, - FeePayerSignature, GasEstimation, GasEstimationBcs, GenesisPayload, GenesisTransaction, - MultiAgentSignature, MultiEd25519Signature, MultiKeySignature, MultisigPayload, - MultisigTransactionPayload, NoAccountSignature, PendingTransaction, PublicKey, ScriptPayload, - ScriptWriteSet, Signature, SingleKeySignature, SubmitTransactionRequest, Transaction, - TransactionData, TransactionId, TransactionInfo, TransactionOnChainData, TransactionPayload, - TransactionSignature, TransactionSigningMessage, TransactionsBatchSingleSubmissionFailure, - TransactionsBatchSubmissionResult, UserCreateSigningMessageRequest, UserTransaction, - UserTransactionRequest, VersionedEvent, WriteModule, WriteResource, WriteSet, WriteSetChange, - WriteSetPayload, WriteTableItem, + AbstractionSignature, AccountSignature, BlockMetadataTransaction, DeleteModule, DeleteResource, + DeleteTableItem, DirectWriteSet, Ed25519Signature, EncodeSubmissionRequest, + EntryFunctionPayload, Event, FeePayerSignature, GasEstimation, GasEstimationBcs, + GenesisPayload, GenesisTransaction, MultiAgentSignature, MultiEd25519Signature, + MultiKeySignature, MultisigPayload, MultisigTransactionPayload, NoAccountSignature, + PendingTransaction, PublicKey, ScriptPayload, ScriptWriteSet, Signature, SingleKeySignature, + SubmitTransactionRequest, Transaction, TransactionData, TransactionId, TransactionInfo, + TransactionOnChainData, TransactionPayload, TransactionSignature, TransactionSigningMessage, + TransactionsBatchSingleSubmissionFailure, TransactionsBatchSubmissionResult, + UserCreateSigningMessageRequest, UserTransaction, UserTransactionRequest, VersionedEvent, + WriteModule, WriteResource, WriteSet, WriteSetChange, WriteSetPayload, WriteTableItem, }; pub use view::{ViewFunction, ViewRequest}; pub use wrappers::{EventGuid, IdentifierWrapper, StateKeyWrapper}; diff --git a/api/types/src/transaction.rs b/api/types/src/transaction.rs index bc3b51f2f5fc6..065e149448d92 100755 --- a/api/types/src/transaction.rs +++ b/api/types/src/transaction.rs @@ -22,6 +22,7 @@ use aptos_types::{ block_metadata_ext::BlockMetadataExt, contract_event::{ContractEvent, EventWithVersion}, dkg::{DKGTranscript, DKGTranscriptMetadata}, + function_info::FunctionInfo, jwks::{jwk::JWK, ProviderJWKs, QuorumCertifiedUpdate}, keyless, transaction::{ @@ -33,6 +34,7 @@ use aptos_types::{ Script, SignedTransaction, TransactionOutput, TransactionWithProof, }, }; +use bcs::to_bytes; use once_cell::sync::Lazy; use poem_openapi::{Object, Union}; use serde::{Deserialize, Serialize}; @@ -1916,6 +1918,18 @@ impl VerifyInput for NoAccountSignature { } } +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)] +pub struct AbstractionSignature { + pub function_info: String, + pub auth_data: HexEncodedBytes, +} + +impl VerifyInput for AbstractionSignature { + fn verify(&self) -> anyhow::Result<()> { + Ok(()) + } +} + impl TryFrom for TransactionAuthenticator { type Error = anyhow::Error; @@ -1933,6 +1947,17 @@ impl TryFrom for AccountAuthenticator { } } +impl TryFrom for AccountAuthenticator { + type Error = anyhow::Error; + + fn try_from(value: AbstractionSignature) -> Result { + Ok(AccountAuthenticator::Abstraction { + function_info: FunctionInfo::from_str(&value.function_info)?, + auth_data: bcs::from_bytes(value.auth_data.inner())?, + }) + } +} + /// Account signature scheme /// /// The account signature scheme allows you to have two types of accounts: @@ -1949,6 +1974,7 @@ pub enum AccountSignature { SingleKeySignature(SingleKeySignature), MultiKeySignature(MultiKeySignature), NoAccountSignature(NoAccountSignature), + AbstractionSignature(AbstractionSignature), } impl VerifyInput for AccountSignature { @@ -1959,6 +1985,7 @@ impl VerifyInput for AccountSignature { AccountSignature::SingleKeySignature(inner) => inner.verify(), AccountSignature::MultiKeySignature(inner) => inner.verify(), AccountSignature::NoAccountSignature(inner) => inner.verify(), + AccountSignature::AbstractionSignature(inner) => inner.verify(), } } } @@ -1973,6 +2000,7 @@ impl TryFrom for AccountAuthenticator { AccountSignature::SingleKeySignature(s) => s.try_into()?, AccountSignature::MultiKeySignature(s) => s.try_into()?, AccountSignature::NoAccountSignature(s) => s.try_into()?, + AccountSignature::AbstractionSignature(s) => s.try_into()?, }) } } @@ -2134,6 +2162,15 @@ impl From<&AccountAuthenticator> for AccountSignature { }) }, NoAccountAuthenticator => AccountSignature::NoAccountSignature(NoAccountSignature), + Abstraction { + function_info, + auth_data, + } => Self::AbstractionSignature(AbstractionSignature { + function_info: function_info.to_string(), + auth_data: to_bytes(auth_data) + .expect("bcs serialization cannot fail") + .into(), + }), } } } diff --git a/aptos-move/aptos-abstract-gas-usage/src/algebra.rs b/aptos-move/aptos-abstract-gas-usage/src/algebra.rs index 654cb9c97e97f..e0998444e7e8a 100644 --- a/aptos-move/aptos-abstract-gas-usage/src/algebra.rs +++ b/aptos-move/aptos-abstract-gas-usage/src/algebra.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use aptos_gas_algebra::{ - DynamicExpression, Fee, FeePerGasUnit, GasExpression, InternalGas, InternalGasUnit, NumBytes, - Octa, + DynamicExpression, Fee, FeePerGasUnit, Gas, GasExpression, InternalGas, InternalGasUnit, + NumBytes, Octa, }; use aptos_gas_meter::GasAlgebra; use aptos_gas_schedule::VMGasParameters; @@ -100,4 +100,8 @@ impl GasAlgebra for CalibrationAlgebra { fn storage_fee_used(&self) -> Fee { self.base.storage_fee_used() } + + fn inject_balance(&mut self, new_initial_gas: impl Into) -> PartialVMResult<()> { + self.base.inject_balance(new_initial_gas) + } } diff --git a/aptos-move/aptos-gas-meter/src/algebra.rs b/aptos-move/aptos-gas-meter/src/algebra.rs index adc4d8697d760..d88fdef7fb8b2 100644 --- a/aptos-move/aptos-gas-meter/src/algebra.rs +++ b/aptos-move/aptos-gas-meter/src/algebra.rs @@ -13,7 +13,7 @@ use move_core_types::{ gas_algebra::{InternalGas, InternalGasUnit}, vm_status::StatusCode, }; -use std::fmt::Debug; +use std::{fmt::Debug, ops::AddAssign}; /// Base gas algebra implementation that tracks the gas usage using its internal counters. /// @@ -290,4 +290,14 @@ impl GasAlgebra for StandardGasAlgebra { fn storage_fee_used(&self) -> Fee { self.storage_fee_used } + + // Reset the initial gas balance to reflect the new balance with the change carried over. + fn inject_balance(&mut self, extra_balance: impl Into) -> PartialVMResult<()> { + let extra_unit = extra_balance + .into() + .to_unit_with_params(&self.vm_gas_params.txn); + self.initial_balance.add_assign(extra_unit); + self.balance.add_assign(extra_unit); + Ok(()) + } } diff --git a/aptos-move/aptos-gas-meter/src/traits.rs b/aptos-move/aptos-gas-meter/src/traits.rs index bbbd3c4071f7b..b9bdb99042444 100644 --- a/aptos-move/aptos-gas-meter/src/traits.rs +++ b/aptos-move/aptos-gas-meter/src/traits.rs @@ -83,6 +83,9 @@ pub trait GasAlgebra { /// Returns the amount of storage fee used. fn storage_fee_used(&self) -> Fee; + + /// Bump the `extra_balance`. + fn inject_balance(&mut self, extra_balance: impl Into) -> PartialVMResult<()>; } /// Trait representing a gas meter used inside the Aptos VM. @@ -248,4 +251,11 @@ pub trait AptosGasMeter: MoveGasMeter { fn storage_fee_used(&self) -> Fee { self.algebra().storage_fee_used() } + + /// Bump the `extra_balance`. + fn inject_balance(&mut self, extra_balance: impl Into) -> VMResult<()> { + self.algebra_mut() + .inject_balance(extra_balance) + .map_err(|e| e.finish(Location::Undefined)) + } } diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs index d48c19c67e04b..72526a5404d6e 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs @@ -6,7 +6,7 @@ use crate::{ gas_feature_versions::{RELEASE_V1_14, RELEASE_V1_8, RELEASE_V1_9_SKIPPED}, gas_schedule::NativeGasParameters, - ver::gas_feature_versions::{RELEASE_V1_12, RELEASE_V1_13, RELEASE_V1_23}, + ver::gas_feature_versions::{RELEASE_V1_12, RELEASE_V1_13, RELEASE_V1_23, RELEASE_V1_26}, }; use aptos_gas_algebra::{ InternalGas, InternalGasPerAbstractValueUnit, InternalGasPerArg, InternalGasPerByte, @@ -20,6 +20,11 @@ crate::gas_schedule::macros::define_gas_parameters!( [account_create_address_base: InternalGas, "account.create_address.base", 1102], [account_create_signer_base: InternalGas, "account.create_signer.base", 1102], + // Permissioned signer gas parameters + [permission_address_base: InternalGas, { RELEASE_V1_26 => "permissioned_signer.permission_address.base"}, 1102], + [is_permissioned_signer_base: InternalGas, { RELEASE_V1_26 => "permissioned_signer.is_permissioned_signer.base"}, 1102], + [signer_from_permissioned_handle_base: InternalGas, { RELEASE_V1_26 => "permissioned_signer.signer_from_permissioned_handle.base"}, 1102], + // BN254 algebra gas parameters begin. // Generated at time 1701559125.5498126 by `scripts/algebra-gas/update_bn254_algebra_gas_params.py` with gas_per_ns=209.10511688369482. [algebra_ark_bn254_fq12_add: InternalGas, { 12.. => "algebra.ark_bn254_fq12_add" }, 809], @@ -251,6 +256,7 @@ crate::gas_schedule::macros::define_gas_parameters!( [function_info_check_dispatch_type_compatibility_impl_base: InternalGas, { RELEASE_V1_13.. => "function_info.check_dispatch_type_compatibility_impl.base" }, 1002], [function_info_load_function_base: InternalGas, { RELEASE_V1_13.. => "function_info.load_function.base" }, 551], [dispatchable_fungible_asset_dispatch_base: InternalGas, { RELEASE_V1_13.. => "dispatchable_fungible_asset.dispatch.base" }, 551], + [dispatchable_authenticate_dispatch_base: InternalGas, { RELEASE_V1_26.. => "dispatchable_authenticate.dispatch.base" }, 551], // Reusing SHA2-512's cost from Ristretto [hash_sha2_512_base: InternalGas, { 4.. => "hash.sha2_512.base" }, 11910], // 3_240 * 20 diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs index 5c51fa9ee314b..ef7c0db01dcd6 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs @@ -6,7 +6,9 @@ use crate::{ gas_schedule::VMGasParameters, - ver::gas_feature_versions::{RELEASE_V1_11, RELEASE_V1_12, RELEASE_V1_13, RELEASE_V1_15}, + ver::gas_feature_versions::{ + RELEASE_V1_11, RELEASE_V1_12, RELEASE_V1_13, RELEASE_V1_15, RELEASE_V1_26, + }, }; use aptos_gas_algebra::{ AbstractValueSize, Fee, FeePerByte, FeePerGasUnit, FeePerSlot, Gas, GasExpression, @@ -268,6 +270,11 @@ crate::gas_schedule::macros::define_gas_parameters!( max_ty_depth: NumTypeNodes, { RELEASE_V1_15.. => "max_ty_depth" }, 20, + ], + [ + max_aa_gas: Gas, + { RELEASE_V1_26.. => "max_aa_gas" }, + 60, ] ] ); diff --git a/aptos-move/aptos-gas-schedule/src/ver.rs b/aptos-move/aptos-gas-schedule/src/ver.rs index 9e40e1d833880..5fd9f9ebc6ca6 100644 --- a/aptos-move/aptos-gas-schedule/src/ver.rs +++ b/aptos-move/aptos-gas-schedule/src/ver.rs @@ -69,7 +69,7 @@ /// global operations. /// - V1 /// - TBA -pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_24; +pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_26; pub mod gas_feature_versions { pub const RELEASE_V1_8: u64 = 11; @@ -89,4 +89,5 @@ pub mod gas_feature_versions { pub const RELEASE_V1_22: u64 = 26; pub const RELEASE_V1_23: u64 = 27; pub const RELEASE_V1_24: u64 = 28; + pub const RELEASE_V1_26: u64 = 30; } diff --git a/aptos-move/aptos-release-builder/data/example.yaml b/aptos-move/aptos-release-builder/data/example.yaml index 8d50c14abcffc..456fd49f5186f 100644 --- a/aptos-move/aptos-release-builder/data/example.yaml +++ b/aptos-move/aptos-release-builder/data/example.yaml @@ -10,7 +10,7 @@ proposals: execution_mode: MultiStep update_sequence: - Framework: - bytecode_version: 6 + bytecode_version: 7 git_hash: ~ - name: gas metadata: diff --git a/aptos-move/aptos-release-builder/data/release.yaml b/aptos-move/aptos-release-builder/data/release.yaml index a12d498463731..891bece480d33 100644 --- a/aptos-move/aptos-release-builder/data/release.yaml +++ b/aptos-move/aptos-release-builder/data/release.yaml @@ -11,7 +11,7 @@ proposals: - Gas: new: current - Framework: - bytecode_version: 6 + bytecode_version: 7 git_hash: ~ - FeatureFlag: enabled: diff --git a/aptos-move/aptos-release-builder/src/components/feature_flags.rs b/aptos-move/aptos-release-builder/src/components/feature_flags.rs index b4334bbcd1322..376af23caa9ec 100644 --- a/aptos-move/aptos-release-builder/src/components/feature_flags.rs +++ b/aptos-move/aptos-release-builder/src/components/feature_flags.rs @@ -134,6 +134,9 @@ pub enum FeatureFlag { NativeMemoryOperations, EnableLoaderV2, DisallowInitModuleToPublishModules, + EnableCallTreeAndInstructionVMCache, + PermissionedSigner, + AccountAbstraction, } fn generate_features_blob(writer: &CodeWriter, data: &[u64]) { @@ -357,6 +360,11 @@ impl From for AptosFeatureFlag { FeatureFlag::DisallowInitModuleToPublishModules => { AptosFeatureFlag::DISALLOW_INIT_MODULE_TO_PUBLISH_MODULES }, + FeatureFlag::EnableCallTreeAndInstructionVMCache => { + AptosFeatureFlag::ENABLE_CALL_TREE_AND_INSTRUCTION_VM_CACHE + }, + FeatureFlag::PermissionedSigner => AptosFeatureFlag::PERMISSIONED_SIGNER, + FeatureFlag::AccountAbstraction => AptosFeatureFlag::ACCOUNT_ABSTRACTION, } } } @@ -507,6 +515,11 @@ impl From for FeatureFlag { AptosFeatureFlag::DISALLOW_INIT_MODULE_TO_PUBLISH_MODULES => { FeatureFlag::DisallowInitModuleToPublishModules }, + AptosFeatureFlag::ENABLE_CALL_TREE_AND_INSTRUCTION_VM_CACHE => { + FeatureFlag::EnableCallTreeAndInstructionVMCache + }, + AptosFeatureFlag::PERMISSIONED_SIGNER => FeatureFlag::PermissionedSigner, + AptosFeatureFlag::ACCOUNT_ABSTRACTION => FeatureFlag::AccountAbstraction, } } } diff --git a/aptos-move/aptos-vm-environment/src/prod_configs.rs b/aptos-move/aptos-vm-environment/src/prod_configs.rs index 1696776b739a7..1319d768b0f35 100644 --- a/aptos-move/aptos-vm-environment/src/prod_configs.rs +++ b/aptos-move/aptos-vm-environment/src/prod_configs.rs @@ -145,6 +145,8 @@ pub fn aptos_prod_vm_config( disallow_dispatch_for_native: features.is_enabled(FeatureFlag::DISALLOW_USER_NATIVES), use_compatibility_checker_v2, use_loader_v2: features.is_loader_v2_enabled(), + use_call_tree_and_instruction_cache: features + .is_call_tree_and_instruction_vm_cache_enabled(), } } diff --git a/aptos-move/aptos-vm-profiling/src/bins/run_move.rs b/aptos-move/aptos-vm-profiling/src/bins/run_move.rs index 667a7c49c0bb4..3a1c51b715662 100644 --- a/aptos-move/aptos-vm-profiling/src/bins/run_move.rs +++ b/aptos-move/aptos-vm-profiling/src/bins/run_move.rs @@ -37,7 +37,7 @@ fn make_native_create_signer() -> NativeFunction { let address = pop_arg!(args, AccountAddress); - Ok(NativeResult::ok(0.into(), smallvec![Value::signer( + Ok(NativeResult::ok(0.into(), smallvec![Value::master_signer( address )])) }) diff --git a/aptos-move/aptos-vm/Cargo.toml b/aptos-move/aptos-vm/Cargo.toml index 94897e9368d97..3b68cf1e0b79a 100644 --- a/aptos-move/aptos-vm/Cargo.toml +++ b/aptos-move/aptos-vm/Cargo.toml @@ -46,6 +46,7 @@ derive_more = { workspace = true } fail = { workspace = true } futures = { workspace = true } hex = { workspace = true } +itertools = { workspace = true } move-binary-format = { workspace = true } move-core-types = { workspace = true } move-unit-test = { workspace = true, optional = true } diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs index db50ca10e1fca..128790cc9a4b5 100644 --- a/aptos-move/aptos-vm/src/aptos_vm.rs +++ b/aptos-move/aptos-vm/src/aptos_vm.rs @@ -59,6 +59,7 @@ use aptos_types::{ chain_id::ChainId, contract_event::ContractEvent, fee_statement::FeeStatement, + function_info::FunctionInfo, move_utils::as_move_value::AsMoveValue, on_chain_config::{ ApprovedExecutionHashes, ConfigStorage, FeatureFlag, Features, OnChainConfig, @@ -67,7 +68,8 @@ use aptos_types::{ randomness::Randomness, state_store::{state_key::StateKey, StateView, TStateView}, transaction::{ - authenticator::AnySignature, signature_verified_transaction::SignatureVerifiedTransaction, + authenticator::{AbstractionAuthData, AnySignature, AuthenticationProof}, + signature_verified_transaction::SignatureVerifiedTransaction, BlockOutput, EntryFunction, ExecutionError, ExecutionStatus, ModuleBundle, Multisig, MultisigTransactionPayload, Script, SignedTransaction, Transaction, TransactionArgument, TransactionOutput, TransactionPayload, TransactionStatus, VMValidatorResult, @@ -113,13 +115,16 @@ use move_core_types::{ move_resource::MoveStructType, transaction_argument::convert_txn_args, value::{serialize_values, MoveTypeLayout, MoveValue}, - vm_status::StatusType, + vm_status::{ + StatusCode::{ACCOUNT_AUTHENTICATION_GAS_LIMIT_EXCEEDED, OUT_OF_GAS}, + StatusType, + }, }; use move_vm_metrics::{Timer, VM_TIMER}; use move_vm_runtime::{ logging::expect_no_verification_errors, module_traversal::{TraversalContext, TraversalStorage}, - RuntimeEnvironment, WithRuntimeEnvironment, + ModuleStorage, RuntimeEnvironment, WithRuntimeEnvironment, }; use move_vm_types::gas::{GasMeter, UnmeteredGasMeter}; use num_cpus; @@ -161,6 +166,35 @@ macro_rules! unwrap_or_discard { }; } +pub(crate) struct SerializedSigners { + senders: Vec>, + fee_payer: Option>, +} + +impl SerializedSigners { + pub fn new(senders: Vec>, fee_payer: Option>) -> Self { + Self { senders, fee_payer } + } + + pub fn sender(&self) -> Vec { + self.senders[0].clone() + } + + pub fn senders(&self) -> Vec> { + self.senders.clone() + } + + pub fn fee_payer(&self) -> Option> { + self.fee_payer.clone() + } +} + +pub(crate) fn serialized_signer(account_address: &AccountAddress) -> Vec { + MoveValue::Signer(*account_address) + .simple_serialize() + .unwrap() +} + pub(crate) fn get_system_transaction_output( session: SessionExt, module_storage: &impl AptosModuleStorage, @@ -444,6 +478,7 @@ impl AptosVM { txn_data: &TransactionMetadata, resolver: &impl AptosMoveResolver, module_storage: &impl AptosModuleStorage, + serialized_signers: &SerializedSigners, log_context: &AdapterLogSchema, change_set_configs: &ChangeSetConfigs, traversal_context: &mut TraversalContext, @@ -491,6 +526,7 @@ impl AptosVM { txn_data, resolver, module_storage, + serialized_signers, status, log_context, change_set_configs, @@ -538,6 +574,7 @@ impl AptosVM { txn_data: &TransactionMetadata, resolver: &impl AptosMoveResolver, module_storage: &impl AptosModuleStorage, + serialized_signers: &SerializedSigners, status: ExecutionStatus, log_context: &AdapterLogSchema, change_set_configs: &ChangeSetConfigs, @@ -659,6 +696,7 @@ impl AptosVM { transaction_validation::run_failure_epilogue( session, module_storage, + serialized_signers, gas_meter.balance(), fee_statement, self.features(), @@ -676,6 +714,7 @@ impl AptosVM { &self, mut epilogue_session: EpilogueSession, module_storage: &impl AptosModuleStorage, + serialized_signers: &SerializedSigners, gas_meter: &impl AptosGasMeter, txn_data: &TransactionMetadata, log_context: &AdapterLogSchema, @@ -707,6 +746,7 @@ impl AptosVM { transaction_validation::run_success_epilogue( session, module_storage, + serialized_signers, gas_meter.balance(), fee_statement, self.features(), @@ -739,12 +779,12 @@ impl AptosVM { fn validate_and_execute_script( &self, session: &mut SessionExt, + serialized_signers: &SerializedSigners, code_storage: &impl AptosCodeStorage, // Note: cannot use AptosGasMeter because it is not implemented for // UnmeteredGasMeter. gas_meter: &mut impl GasMeter, traversal_context: &mut TraversalContext, - senders: Vec, script: &Script, ) -> Result<(), VMStatus> { if !self @@ -802,7 +842,7 @@ impl AptosVM { let args = verifier::transaction_arg_validation::validate_combine_signer_and_txn_args( session, code_storage, - senders, + serialized_signers, convert_txn_args(script.args()), &func, self.features().is_enabled(FeatureFlag::STRUCT_CONSTRUCTORS), @@ -824,9 +864,9 @@ impl AptosVM { resolver: &impl AptosMoveResolver, module_storage: &impl AptosModuleStorage, session: &mut SessionExt, + serialized_signers: &SerializedSigners, gas_meter: &mut impl AptosGasMeter, traversal_context: &mut TraversalContext, - senders: Vec, entry_fn: &EntryFunction, _txn_data: &TransactionMetadata, ) -> Result<(), VMStatus> { @@ -883,7 +923,7 @@ impl AptosVM { let args = verifier::transaction_arg_validation::validate_combine_signer_and_txn_args( session, module_storage, - senders, + serialized_signers, entry_fn.args().to_vec(), &function, struct_constructors_enabled, @@ -903,6 +943,7 @@ impl AptosVM { resolver: &'r impl AptosMoveResolver, code_storage: &impl AptosCodeStorage, mut session: UserSession<'r, 'l>, + serialized_signers: &SerializedSigners, gas_meter: &mut impl AptosGasMeter, traversal_context: &mut TraversalContext<'a>, txn_data: &TransactionMetadata, @@ -929,10 +970,10 @@ impl AptosVM { session.execute(|session| { self.validate_and_execute_script( session, + serialized_signers, code_storage, gas_meter, traversal_context, - txn_data.senders(), script, ) })?; @@ -943,9 +984,9 @@ impl AptosVM { resolver, code_storage, session, + serialized_signers, gas_meter, traversal_context, - txn_data.senders(), entry_fn, txn_data, ) @@ -977,9 +1018,12 @@ impl AptosVM { txn_data, )?; + // ============= Gas fee cannot change after this line ============= + self.success_transaction_cleanup( epilogue_session, code_storage, + serialized_signers, gas_meter, txn_data, log_context, @@ -1050,6 +1094,7 @@ impl AptosVM { resolver: &'r impl AptosMoveResolver, module_storage: &impl AptosModuleStorage, session: UserSession<'r, 'l>, + serialized_signers: &SerializedSigners, gas_meter: &mut impl AptosGasMeter, traversal_context: &mut TraversalContext<'a>, txn_data: &TransactionMetadata, @@ -1094,6 +1139,7 @@ impl AptosVM { self.success_transaction_cleanup( epilogue_session, module_storage, + serialized_signers, gas_meter, txn_data, log_context, @@ -1120,6 +1166,7 @@ impl AptosVM { resolver: &'r impl AptosMoveResolver, module_storage: &impl AptosModuleStorage, mut session: UserSession<'r, 'l>, + serialized_signers: &SerializedSigners, prologue_session_change_set: &SystemSessionChangeSet, gas_meter: &mut impl AptosGasMeter, traversal_context: &mut TraversalContext, @@ -1288,6 +1335,7 @@ impl AptosVM { self.success_transaction_cleanup( epilogue_session, module_storage, + serialized_signers, gas_meter, txn_data, log_context, @@ -1302,6 +1350,7 @@ impl AptosVM { resolver: &'r impl AptosMoveResolver, module_storage: &impl AptosModuleStorage, session: UserSession<'r, 'l>, + serialized_signers: &SerializedSigners, prologue_session_change_set: &SystemSessionChangeSet, gas_meter: &mut impl AptosGasMeter, traversal_context: &mut TraversalContext<'a>, @@ -1322,6 +1371,7 @@ impl AptosVM { resolver, module_storage, session, + serialized_signers, gas_meter, traversal_context, txn_data, @@ -1335,6 +1385,7 @@ impl AptosVM { resolver, module_storage, session, + serialized_signers, prologue_session_change_set, gas_meter, traversal_context, @@ -1367,9 +1418,9 @@ impl AptosVM { resolver, module_storage, session, + &SerializedSigners::new(vec![serialized_signer(&multisig_address)], None), gas_meter, traversal_context, - vec![multisig_address], payload, txn_data, ) @@ -1458,10 +1509,7 @@ impl AptosVM { // with the general verify_module above. if init_function.is_ok() { if verifier::module_init::verify_module_init_function(module).is_ok() { - let args: Vec> = senders - .iter() - .map(|s| MoveValue::Signer(*s).simple_serialize().unwrap()) - .collect(); + let args: Vec> = senders.iter().map(serialized_signer).collect(); session.execute_function_bypass_visibility( &module.self_id(), init_func_name, @@ -1824,13 +1872,14 @@ impl AptosVM { &self, session: &mut SessionExt, resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, transaction: &SignedTransaction, transaction_data: &TransactionMetadata, log_context: &AdapterLogSchema, is_approved_gov_script: bool, traversal_context: &mut TraversalContext, - ) -> Result<(), VMStatus> { + gas_meter: &mut impl AptosGasMeter, + ) -> Result { // Check transaction format. if transaction.contains_duplicate_signers() { return Err(VMStatus::error( @@ -1853,6 +1902,76 @@ impl AptosVM { )?; } + // Account Abstraction dispatchable authentication. + let senders = transaction_data.senders(); + let proofs = transaction_data.authentication_proofs(); + + // Add fee payer. + let fee_payer_signer = if let Some(fee_payer) = transaction_data.fee_payer { + Some(match &transaction_data.fee_payer_authentication_proof { + Some(AuthenticationProof::Abstraction { + function_info, + auth_data, + }) => { + if self.features().is_account_abstraction_enabled() { + dispatchable_authenticate( + session, + gas_meter, + fee_payer, + function_info.clone(), + auth_data, + traversal_context, + module_storage, + ) + .map_err(|mut vm_error| { + if vm_error.major_status() == OUT_OF_GAS { + vm_error + .set_major_status(ACCOUNT_AUTHENTICATION_GAS_LIMIT_EXCEEDED); + } + vm_error.into_vm_status() + }) + } else { + return Err(VMStatus::error(StatusCode::FEATURE_UNDER_GATING, None)); + } + }, + _ => Ok(serialized_signer(&fee_payer)), + }?) + } else { + None + }; + let sender_signers = itertools::zip_eq(senders, proofs) + .map(|(sender, proof)| match proof { + AuthenticationProof::Abstraction { + function_info, + auth_data, + } => { + if self.features().is_account_abstraction_enabled() { + dispatchable_authenticate( + session, + gas_meter, + sender, + function_info.clone(), + auth_data, + traversal_context, + module_storage, + ) + .map_err(|mut vm_error| { + if vm_error.major_status() == OUT_OF_GAS { + vm_error + .set_major_status(ACCOUNT_AUTHENTICATION_GAS_LIMIT_EXCEEDED); + } + vm_error.into_vm_status() + }) + } else { + Err(VMStatus::error(StatusCode::FEATURE_UNDER_GATING, None)) + } + }, + _ => Ok(serialized_signer(&sender)), + }) + .collect::>()?; + + let serialized_signers = SerializedSigners::new(sender_signers, fee_payer_signer); + // The prologue MUST be run AFTER any validation. Otherwise you may run prologue and hit // SEQUENCE_NUMBER_TOO_NEW if there is more than one transaction from the same sender and // end up skipping validation. @@ -1860,12 +1979,14 @@ impl AptosVM { session, resolver, module_storage, + &serialized_signers, transaction.payload(), transaction_data, log_context, is_approved_gov_script, traversal_context, - ) + )?; + Ok(serialized_signers) } // Called when the execution of the user transaction fails, in order to discard the @@ -1876,6 +1997,7 @@ impl AptosVM { err: VMStatus, resolver: &impl AptosMoveResolver, module_storage: &impl AptosModuleStorage, + serialized_signers: &SerializedSigners, txn_data: &TransactionMetadata, log_context: &AdapterLogSchema, gas_meter: &mut impl AptosGasMeter, @@ -1900,6 +2022,7 @@ impl AptosVM { txn_data, resolver, module_storage, + serialized_signers, log_context, change_set_configs, traversal_context, @@ -1913,8 +2036,8 @@ impl AptosVM { txn: &SignedTransaction, txn_data: TransactionMetadata, is_approved_gov_script: bool, - gas_meter: &mut impl AptosGasMeter, log_context: &AdapterLogSchema, + gas_meter: &mut impl AptosGasMeter, ) -> (VMStatus, VMOutput) { let _timer = VM_TIMER.timer_with_label("AptosVM::execute_user_transaction_impl"); @@ -1923,7 +2046,8 @@ impl AptosVM { // Revalidate the transaction. let mut prologue_session = PrologueSession::new(self, &txn_data, resolver); - let exec_result = prologue_session.execute(|session| { + let initial_gas = gas_meter.balance(); + let serialized_signers = unwrap_or_discard!(prologue_session.execute(|session| { self.validate_signed_transaction( session, resolver, @@ -1933,9 +2057,24 @@ impl AptosVM { log_context, is_approved_gov_script, &mut traversal_context, + gas_meter, ) - }); - unwrap_or_discard!(exec_result); + })); + + if self.features().is_account_abstraction_enabled() { + let max_aa_gas = unwrap_or_discard!(self.gas_params(log_context)) + .vm + .txn + .max_aa_gas; + if max_aa_gas < txn_data.max_gas_amount() { + // Reset initial gas after validation with max_aa_gas. + unwrap_or_discard!(gas_meter + .inject_balance(txn_data.max_gas_amount().checked_sub(max_aa_gas).unwrap())); + } + } else { + assert_eq!(initial_gas, gas_meter.balance()); + } + let storage_gas_params = unwrap_or_discard!(self.storage_gas_params(log_context)); let change_set_configs = &storage_gas_params.change_set_configs; let (prologue_change_set, mut user_session) = unwrap_or_discard!(prologue_session @@ -1984,6 +2123,7 @@ impl AptosVM { resolver, code_storage, user_session, + &serialized_signers, gas_meter, &mut traversal_context, &txn_data, @@ -1996,6 +2136,7 @@ impl AptosVM { resolver, code_storage, user_session, + &serialized_signers, &prologue_change_set, gas_meter, &mut traversal_context, @@ -2020,12 +2161,13 @@ impl AptosVM { .expect("Balance should always be less than or equal to max gas amount set"); TXN_GAS_USAGE.observe(u64::from(gas_usage) as f64); - result.unwrap_or_else(|err| { + let (vm_status, output) = result.unwrap_or_else(|err| { self.on_user_transaction_execution_failure( prologue_change_set, err, resolver, code_storage, + &serialized_signers, &txn_data, log_context, gas_meter, @@ -2033,7 +2175,8 @@ impl AptosVM { new_published_modules_loaded, &mut traversal_context, ) - }) + }); + (vm_status, output) } /// Main entrypoint for executing a user transaction that also allows the customization of the @@ -2048,28 +2191,36 @@ impl AptosVM { ) -> Result<(VMStatus, VMOutput, G), VMStatus> where G: AptosGasMeter, - F: FnOnce(u64, VMGasParameters, StorageGasParameters, bool, Gas) -> G, + F: Fn(u64, VMGasParameters, StorageGasParameters, bool, Gas) -> G, { let txn_metadata = TransactionMetadata::new(txn); let is_approved_gov_script = is_approved_gov_script(resolver, txn, &txn_metadata); - let balance = txn.max_gas_amount().into(); + let vm_params = self.gas_params(log_context)?.vm.clone(); + + let initial_balance = if self.features().is_account_abstraction_enabled() { + vm_params.txn.max_aa_gas.min(txn.max_gas_amount().into()) + } else { + txn.max_gas_amount().into() + }; + let mut gas_meter = make_gas_meter( self.gas_feature_version(), - self.gas_params(log_context)?.vm.clone(), + vm_params, self.storage_gas_params(log_context)?.clone(), is_approved_gov_script, - balance, + initial_balance, ); + let (status, output) = self.execute_user_transaction_impl( resolver, code_storage, txn, txn_metadata, is_approved_gov_script, - &mut gas_meter, log_context, + &mut gas_meter, ); Ok((status, output, gas_meter)) @@ -2089,7 +2240,7 @@ impl AptosVM { modify_gas_meter: F, ) -> Result<(VMStatus, VMOutput, G), VMStatus> where - F: FnOnce(ProdGasMeter) -> G, + F: Fn(ProdGasMeter) -> G, G: AptosGasMeter, { self.execute_user_transaction_with_custom_gas_meter( @@ -2170,8 +2321,8 @@ impl AptosVM { WriteSetPayload::Script { script, execute_as } => { let mut tmp_session = self.new_session(resolver, session_id, None); let senders = match txn_sender { - None => vec![*execute_as], - Some(sender) => vec![sender, *execute_as], + None => vec![serialized_signer(execute_as)], + Some(sender) => vec![serialized_signer(&sender), serialized_signer(execute_as)], }; let traversal_storage = TraversalStorage::new(); @@ -2179,10 +2330,10 @@ impl AptosVM { self.validate_and_execute_script( &mut tmp_session, + &SerializedSigners::new(senders, None), code_storage, &mut UnmeteredGasMeter, &mut traversal_context, - senders, script, )?; @@ -2553,7 +2704,8 @@ impl AptosVM { &self, session: &mut SessionExt, resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, + serialized_signers: &SerializedSigners, payload: &TransactionPayload, txn_data: &TransactionMetadata, log_context: &AdapterLogSchema, @@ -2576,6 +2728,7 @@ impl AptosVM { transaction_validation::run_script_prologue( session, module_storage, + serialized_signers, txn_data, self.features(), log_context, @@ -2590,6 +2743,7 @@ impl AptosVM { transaction_validation::run_script_prologue( session, module_storage, + serialized_signers, txn_data, self.features(), log_context, @@ -2899,7 +3053,7 @@ impl VMValidator for AptosVM { &self, transaction: SignedTransaction, state_view: &impl StateView, - module_storage: &impl AptosCodeStorage, + module_storage: &impl ModuleStorage, ) -> VMValidatorResult { let _timer = TXN_VALIDATION_SECONDS.start_timer(); let log_context = AdapterLogSchema::new(state_view.id(), 0); @@ -2958,6 +3112,32 @@ impl VMValidator for AptosVM { Some(txn_data.as_user_transaction_context()), ); + let vm_params = match self.gas_params(&log_context) { + Ok(vm_params) => vm_params.vm.clone(), + Err(err) => { + return VMValidatorResult::new(Some(err.status_code()), 0); + }, + }; + let storage_gas_params = match self.storage_gas_params(&log_context) { + Ok(storage_params) => storage_params.clone(), + Err(err) => { + return VMValidatorResult::new(Some(err.status_code()), 0); + }, + }; + + let initial_balance = if self.features().is_account_abstraction_enabled() { + vm_params.txn.max_aa_gas.min(txn_data.max_gas_amount()) + } else { + txn_data.max_gas_amount() + }; + + let mut gas_meter = make_prod_gas_meter( + self.gas_feature_version(), + vm_params, + storage_gas_params, + is_approved_gov_script, + initial_balance, + ); let storage = TraversalStorage::new(); // Increment the counter for transactions verified. @@ -2970,6 +3150,7 @@ impl VMValidator for AptosVM { &log_context, is_approved_gov_script, &mut TraversalContext::new(&storage), + &mut gas_meter, ) { Err(err) if err.status_code() != StatusCode::SEQUENCE_NUMBER_TOO_NEW => ( "failure", @@ -3047,6 +3228,47 @@ fn create_account_if_does_not_exist( .map(|_return_vals| ()) } +fn dispatchable_authenticate( + session: &mut SessionExt, + gas_meter: &mut impl GasMeter, + account: AccountAddress, + function_info: FunctionInfo, + auth_data: &AbstractionAuthData, + traversal_context: &mut TraversalContext, + module_storage: &impl ModuleStorage, +) -> VMResult> { + let auth_data = bcs::to_bytes(auth_data).expect("from rust succeeds"); + let mut params = serialize_values(&vec![ + MoveValue::Signer(account), + function_info.as_move_value(), + ]); + params.push(auth_data); + session + .execute_function_bypass_visibility( + &ACCOUNT_ABSTRACTION_MODULE, + AUTHENTICATE, + vec![], + params, + gas_meter, + traversal_context, + module_storage, + ) + .map(|mut return_vals| { + assert!( + return_vals.mutable_reference_outputs.is_empty() + && return_vals.return_values.len() == 1, + "Abstraction authentication function must only have 1 return value" + ); + let (signer_data, signer_layout) = return_vals.return_values.pop().expect("Must exist"); + assert_eq!( + signer_layout, + MoveTypeLayout::Signer, + "Abstraction authentication function returned non-signer." + ); + signer_data + }) +} + /// Signals that the transaction should trigger the flow for creating an account as part of a /// sponsored transaction. This occurs when: /// * The feature gate is enabled SPONSORED_AUTOMATIC_ACCOUNT_V1_CREATION @@ -3057,7 +3279,7 @@ pub(crate) fn is_account_init_for_sponsored_transaction( txn_data: &TransactionMetadata, features: &Features, resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, ) -> VMResult { if features.is_enabled(FeatureFlag::SPONSORED_AUTOMATIC_ACCOUNT_V1_CREATION) && txn_data.fee_payer.is_some() @@ -3084,7 +3306,7 @@ pub(crate) fn is_account_init_for_sponsored_transaction( pub(crate) fn fetch_module_metadata_for_struct_tag( struct_tag: &StructTag, resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, ) -> VMResult> { if module_storage.is_enabled() { module_storage.fetch_existing_module_metadata(&struct_tag.address, &struct_tag.module) diff --git a/aptos-move/aptos-vm/src/gas.rs b/aptos-move/aptos-vm/src/gas.rs index e1e12e4ddfb50..26d9543e1e846 100644 --- a/aptos-move/aptos-vm/src/gas.rs +++ b/aptos-move/aptos-vm/src/gas.rs @@ -12,11 +12,9 @@ use aptos_logger::{enabled, Level}; use aptos_memory_usage_tracker::MemoryTrackedGasMeter; use aptos_types::on_chain_config::Features; use aptos_vm_logging::{log_schema::AdapterLogSchema, speculative_log, speculative_warn}; -use aptos_vm_types::{ - module_and_script_storage::module_storage::AptosModuleStorage, - storage::{space_pricing::DiskSpacePricing, StorageGasParameters}, -}; +use aptos_vm_types::storage::{space_pricing::DiskSpacePricing, StorageGasParameters}; use move_core_types::vm_status::{StatusCode, VMStatus}; +use move_vm_runtime::ModuleStorage; /// This is used until gas version 18, which introduces a configurable entry for this. const MAXIMUM_APPROVED_TRANSACTION_SIZE_LEGACY: u64 = 1024 * 1024; @@ -47,7 +45,7 @@ pub(crate) fn check_gas( gas_params: &AptosGasParameters, gas_feature_version: u64, resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, txn_metadata: &TransactionMetadata, features: &Features, is_approved_gov_script: bool, diff --git a/aptos-move/aptos-vm/src/keyless_validation.rs b/aptos-move/aptos-vm/src/keyless_validation.rs index 338ac4386115c..06e7376f7f156 100644 --- a/aptos-move/aptos-vm/src/keyless_validation.rs +++ b/aptos-move/aptos-vm/src/keyless_validation.rs @@ -15,7 +15,6 @@ use aptos_types::{ transaction::authenticator::{EphemeralPublicKey, EphemeralSignature}, vm_status::{StatusCode, VMStatus}, }; -use aptos_vm_types::module_and_script_storage::module_storage::AptosModuleStorage; use ark_bn254::Bn254; use ark_groth16::PreparedVerifyingKey; use move_binary_format::errors::Location; @@ -23,6 +22,7 @@ use move_core_types::{ account_address::AccountAddress, language_storage::CORE_CODE_ADDRESS, move_resource::MoveStructType, }; +use move_vm_runtime::ModuleStorage; use serde::Deserialize; macro_rules! value_deserialization_error { @@ -36,7 +36,7 @@ macro_rules! value_deserialization_error { fn get_resource_on_chain Deserialize<'a>>( resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, ) -> anyhow::Result { get_resource_on_chain_at_addr(&CORE_CODE_ADDRESS, resolver, module_storage) } @@ -44,7 +44,7 @@ fn get_resource_on_chain Deserialize<'a>>( fn get_resource_on_chain_at_addr Deserialize<'a>>( addr: &AccountAddress, resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, ) -> anyhow::Result { let metadata = fetch_module_metadata_for_struct_tag(&T::struct_tag(), resolver, module_storage) .map_err(|e| e.into_vm_status())?; @@ -87,21 +87,21 @@ fn get_jwks_onchain(resolver: &impl AptosMoveResolver) -> anyhow::Result anyhow::Result { get_resource_on_chain_at_addr::(jwk_addr, resolver, module_storage) } pub(crate) fn get_groth16_vk_onchain( resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, ) -> anyhow::Result { get_resource_on_chain::(resolver, module_storage) } fn get_configs_onchain( resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, ) -> anyhow::Result { get_resource_on_chain::(resolver, module_storage) } @@ -160,7 +160,7 @@ pub(crate) fn validate_authenticators( authenticators: &Vec<(AnyKeylessPublicKey, KeylessSignature)>, features: &Features, resolver: &impl AptosMoveResolver, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, ) -> Result<(), VMStatus> { let mut with_zk = false; for (pk, sig) in authenticators { diff --git a/aptos-move/aptos-vm/src/lib.rs b/aptos-move/aptos-vm/src/lib.rs index 8aa474f762699..9d66988b08f47 100644 --- a/aptos-move/aptos-vm/src/lib.rs +++ b/aptos-move/aptos-vm/src/lib.rs @@ -139,7 +139,7 @@ use aptos_types::{ }, vm_status::VMStatus, }; -use aptos_vm_types::module_and_script_storage::code_storage::AptosCodeStorage; +use move_vm_runtime::ModuleStorage; use std::{marker::Sync, sync::Arc}; pub use verifier::view_function::determine_is_view; @@ -150,7 +150,7 @@ pub trait VMValidator { &self, transaction: SignedTransaction, state_view: &impl StateView, - module_storage: &impl AptosCodeStorage, + module_storage: &impl ModuleStorage, ) -> VMValidatorResult; } diff --git a/aptos-move/aptos-vm/src/system_module_names.rs b/aptos-move/aptos-vm/src/system_module_names.rs index e6945a6114c20..1124da643abfc 100644 --- a/aptos-move/aptos-vm/src/system_module_names.rs +++ b/aptos-move/aptos-vm/src/system_module_names.rs @@ -15,9 +15,18 @@ pub static ACCOUNT_MODULE: Lazy = Lazy::new(|| { ) }); +pub static ACCOUNT_ABSTRACTION_MODULE: Lazy = Lazy::new(|| { + ModuleId::new( + account_config::CORE_CODE_ADDRESS, + ident_str!("account_abstraction").to_owned(), + ) +}); + pub const CREATE_ACCOUNT_IF_DOES_NOT_EXIST: &IdentStr = ident_str!("create_account_if_does_not_exist"); +pub const AUTHENTICATE: &IdentStr = ident_str!("authenticate"); + // Data to resolve basic account and transaction flow functions and structs /// The ModuleId for the aptos block module pub static BLOCK_MODULE: Lazy = Lazy::new(|| { diff --git a/aptos-move/aptos-vm/src/testing.rs b/aptos-move/aptos-vm/src/testing.rs index 2ee83eea33d1f..ffd356d101f46 100644 --- a/aptos-move/aptos-vm/src/testing.rs +++ b/aptos-move/aptos-vm/src/testing.rs @@ -1,6 +1,8 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +#[cfg(any(test, feature = "testing"))] +use crate::aptos_vm::{serialized_signer, SerializedSigners}; use crate::AptosVM; #[cfg(any(test, feature = "testing"))] use crate::{ @@ -112,6 +114,10 @@ impl AptosVM { &txn_data, &resolver, &module_storage, + &SerializedSigners::new( + vec![serialized_signer(&txn_data.sender)], + txn_data.fee_payer().as_ref().map(serialized_signer), + ), &log_context, change_set_configs, &mut TraversalContext::new(&traversal_storage), diff --git a/aptos-move/aptos-vm/src/transaction_metadata.rs b/aptos-move/aptos-vm/src/transaction_metadata.rs index 87148c22957de..b5041e8a5d1a6 100644 --- a/aptos-move/aptos-vm/src/transaction_metadata.rs +++ b/aptos-move/aptos-vm/src/transaction_metadata.rs @@ -8,21 +8,21 @@ use aptos_types::{ account_address::AccountAddress, chain_id::ChainId, transaction::{ - user_transaction_context::UserTransactionContext, EntryFunction, Multisig, - SignedTransaction, TransactionPayload, + authenticator::AuthenticationProof, user_transaction_context::UserTransactionContext, + EntryFunction, Multisig, SignedTransaction, TransactionPayload, }, }; pub struct TransactionMetadata { pub sender: AccountAddress, - pub authentication_key: Vec, + pub authentication_proof: AuthenticationProof, pub secondary_signers: Vec, - pub secondary_authentication_keys: Vec>, + pub secondary_authentication_proofs: Vec, pub sequence_number: u64, pub fee_payer: Option, /// `None` if the [TransactionAuthenticator] lacks an authenticator for the fee payer. /// `Some([])` if the authenticator for the fee payer is a [NoAccountAuthenticator]. - pub fee_payer_authentication_key: Option>, + pub fee_payer_authentication_proof: Option, pub max_gas_amount: Gas, pub gas_unit_price: FeePerGasUnit, pub transaction_size: NumBytes, @@ -39,29 +39,20 @@ impl TransactionMetadata { pub fn new(txn: &SignedTransaction) -> Self { Self { sender: txn.sender(), - authentication_key: txn - .authenticator() - .sender() - .authentication_key() - .map_or_else(Vec::new, |auth_key| auth_key.to_vec()), + authentication_proof: txn.authenticator().sender().authentication_proof(), secondary_signers: txn.authenticator().secondary_signer_addresses(), - secondary_authentication_keys: txn + secondary_authentication_proofs: txn .authenticator() .secondary_signers() .iter() - .map(|account_auth| { - account_auth - .authentication_key() - .map_or_else(Vec::new, |auth_key| auth_key.to_vec()) - }) + .map(|account_auth| account_auth.authentication_proof()) .collect(), sequence_number: txn.sequence_number(), fee_payer: txn.authenticator_ref().fee_payer_address(), - fee_payer_authentication_key: txn.authenticator().fee_payer_signer().map(|signer| { - signer - .authentication_key() - .map_or_else(Vec::new, |auth_key| auth_key.to_vec()) - }), + fee_payer_authentication_proof: txn + .authenticator() + .fee_payer_signer() + .map(|signer| signer.authentication_proof()), max_gas_amount: txn.max_gas_amount().into(), gas_unit_price: txn.gas_unit_price().into(), transaction_size: (txn.raw_txn_bytes_len() as u64).into(), @@ -124,8 +115,14 @@ impl TransactionMetadata { senders } - pub fn authentication_key(&self) -> &[u8] { - &self.authentication_key + pub fn authentication_proofs(&self) -> Vec<&AuthenticationProof> { + let mut proofs = vec![self.authentication_proof()]; + proofs.extend(self.secondary_authentication_proofs.iter()); + proofs + } + + pub fn authentication_proof(&self) -> &AuthenticationProof { + &self.authentication_proof } pub fn sequence_number(&self) -> u64 { diff --git a/aptos-move/aptos-vm/src/transaction_validation.rs b/aptos-move/aptos-vm/src/transaction_validation.rs index 38f255524917f..f1957ab980735 100644 --- a/aptos-move/aptos-vm/src/transaction_validation.rs +++ b/aptos-move/aptos-vm/src/transaction_validation.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ + aptos_vm::SerializedSigners, errors::{convert_epilogue_error, convert_prologue_error, expect_only_successful_execution}, move_vm_ext::SessionExt, system_module_names::{ @@ -14,10 +15,9 @@ use crate::{ use aptos_gas_algebra::Gas; use aptos_types::{ account_config::constants::CORE_CODE_ADDRESS, fee_statement::FeeStatement, - on_chain_config::Features, transaction::Multisig, + move_utils::as_move_value::AsMoveValue, on_chain_config::Features, transaction::Multisig, }; use aptos_vm_logging::log_schema::AdapterLogSchema; -use aptos_vm_types::module_and_script_storage::module_storage::AptosModuleStorage; use fail::fail_point; use move_binary_format::errors::VMResult; use move_core_types::{ @@ -28,7 +28,9 @@ use move_core_types::{ value::{serialize_values, MoveValue}, vm_status::{AbortLocation, StatusCode, VMStatus}, }; -use move_vm_runtime::{logging::expect_no_verification_errors, module_traversal::TraversalContext}; +use move_vm_runtime::{ + logging::expect_no_verification_errors, module_traversal::TraversalContext, ModuleStorage, +}; use move_vm_types::gas::UnmeteredGasMeter; use once_cell::sync::Lazy; @@ -49,6 +51,9 @@ pub static APTOS_TRANSACTION_VALIDATION: Lazy = user_epilogue_extended_name: Identifier::new("epilogue_extended").unwrap(), user_epilogue_gas_payer_extended_name: Identifier::new("epilogue_gas_payer_extended") .unwrap(), + unified_prologue_name: Identifier::new("unified_prologue").unwrap(), + unified_prologue_fee_payer_name: Identifier::new("unified_prologue_fee_payer").unwrap(), + unified_epilogue_name: Identifier::new("unified_epilogue").unwrap(), }); /// On-chain functions used to validate transactions @@ -66,6 +71,9 @@ pub struct TransactionValidation { pub multi_agent_prologue_extended_name: Identifier, pub user_epilogue_extended_name: Identifier, pub user_epilogue_gas_payer_extended_name: Identifier, + pub unified_prologue_name: Identifier, + pub unified_prologue_fee_payer_name: Identifier, + pub unified_epilogue_name: Identifier, } impl TransactionValidation { @@ -85,7 +93,8 @@ impl TransactionValidation { pub(crate) fn run_script_prologue( session: &mut SessionExt, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, + serialized_signers: &SerializedSigners, txn_data: &TransactionMetadata, features: &Features, log_context: &AdapterLogSchema, @@ -93,136 +102,241 @@ pub(crate) fn run_script_prologue( is_simulation: bool, ) -> Result<(), VMStatus> { let txn_sequence_number = txn_data.sequence_number(); - let txn_authentication_key = txn_data.authentication_key().to_vec(); + let txn_authentication_key = txn_data.authentication_proof().optional_auth_key(); let txn_gas_price = txn_data.gas_unit_price(); let txn_max_gas_units = txn_data.max_gas_amount(); let txn_expiration_timestamp_secs = txn_data.expiration_timestamp_secs(); let chain_id = txn_data.chain_id(); let mut gas_meter = UnmeteredGasMeter; - let secondary_auth_keys: Vec = txn_data - .secondary_authentication_keys - .iter() - .map(|auth_key| MoveValue::vector_u8(auth_key.to_vec())) - .collect(); - let (prologue_function_name, args) = if let (Some(fee_payer), Some(fee_payer_auth_key)) = ( - txn_data.fee_payer(), - txn_data.fee_payer_authentication_key.as_ref(), - ) { - if features.is_transaction_simulation_enhancement_enabled() { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::U64(txn_sequence_number), - MoveValue::vector_u8(txn_authentication_key), - MoveValue::vector_address(txn_data.secondary_signers()), - MoveValue::Vector(secondary_auth_keys), - MoveValue::Address(fee_payer), - MoveValue::vector_u8(fee_payer_auth_key.to_vec()), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(txn_expiration_timestamp_secs), - MoveValue::U8(chain_id.id()), - MoveValue::Bool(is_simulation), - ]; - ( - &APTOS_TRANSACTION_VALIDATION.fee_payer_prologue_extended_name, - args, - ) - } else { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::U64(txn_sequence_number), - MoveValue::vector_u8(txn_authentication_key), - MoveValue::vector_address(txn_data.secondary_signers()), - MoveValue::Vector(secondary_auth_keys), - MoveValue::Address(fee_payer), - MoveValue::vector_u8(fee_payer_auth_key.to_vec()), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(txn_expiration_timestamp_secs), - MoveValue::U8(chain_id.id()), - ]; - (&APTOS_TRANSACTION_VALIDATION.fee_payer_prologue_name, args) - } - } else if txn_data.is_multi_agent() { - if features.is_transaction_simulation_enhancement_enabled() { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::U64(txn_sequence_number), - MoveValue::vector_u8(txn_authentication_key), - MoveValue::vector_address(txn_data.secondary_signers()), - MoveValue::Vector(secondary_auth_keys), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(txn_expiration_timestamp_secs), - MoveValue::U8(chain_id.id()), - MoveValue::Bool(is_simulation), - ]; - ( - &APTOS_TRANSACTION_VALIDATION.multi_agent_prologue_extended_name, - args, - ) - } else { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::U64(txn_sequence_number), - MoveValue::vector_u8(txn_authentication_key), - MoveValue::vector_address(txn_data.secondary_signers()), - MoveValue::Vector(secondary_auth_keys), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(txn_expiration_timestamp_secs), - MoveValue::U8(chain_id.id()), - ]; - ( - &APTOS_TRANSACTION_VALIDATION.multi_agent_prologue_name, - args, + // Use the new prologues that takes signer from both sender and optional gas payer + if features.is_account_abstraction_enabled() { + let secondary_auth_keys: Vec = txn_data + .secondary_authentication_proofs + .iter() + .map(|auth_key| auth_key.optional_auth_key().as_move_value()) + .collect(); + let (prologue_function_name, serialized_args) = + if let (Some(_fee_payer), Some(fee_payer_auth_key)) = ( + txn_data.fee_payer(), + txn_data + .fee_payer_authentication_proof + .as_ref() + .map(|proof| proof.optional_auth_key()), + ) { + let serialized_args = vec![ + serialized_signers.sender(), + serialized_signers + .fee_payer() + .ok_or_else(|| VMStatus::error(StatusCode::UNREACHABLE, None))?, + txn_authentication_key + .as_move_value() + .simple_serialize() + .unwrap(), + fee_payer_auth_key + .as_move_value() + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_sequence_number) + .simple_serialize() + .unwrap(), + MoveValue::vector_address(txn_data.secondary_signers()) + .simple_serialize() + .unwrap(), + MoveValue::Vector(secondary_auth_keys) + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_gas_price.into()) + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_max_gas_units.into()) + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_expiration_timestamp_secs) + .simple_serialize() + .unwrap(), + MoveValue::U8(chain_id.id()).simple_serialize().unwrap(), + MoveValue::Bool(is_simulation).simple_serialize().unwrap(), + ]; + ( + &APTOS_TRANSACTION_VALIDATION.unified_prologue_fee_payer_name, + serialized_args, + ) + } else { + let serialized_args = vec![ + serialized_signers.sender(), + txn_authentication_key + .as_move_value() + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_sequence_number) + .simple_serialize() + .unwrap(), + MoveValue::vector_address(txn_data.secondary_signers()) + .simple_serialize() + .unwrap(), + MoveValue::Vector(secondary_auth_keys) + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_gas_price.into()) + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_max_gas_units.into()) + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_expiration_timestamp_secs) + .simple_serialize() + .unwrap(), + MoveValue::U8(chain_id.id()).simple_serialize().unwrap(), + MoveValue::Bool(is_simulation).simple_serialize().unwrap(), + ]; + ( + &APTOS_TRANSACTION_VALIDATION.unified_prologue_name, + serialized_args, + ) + }; + session + .execute_function_bypass_visibility( + &APTOS_TRANSACTION_VALIDATION.module_id(), + prologue_function_name, + vec![], + serialized_args, + &mut gas_meter, + traversal_context, + module_storage, ) - } + .map(|_return_vals| ()) + .map_err(expect_no_verification_errors) + .or_else(|err| convert_prologue_error(err, log_context)) } else { - #[allow(clippy::collapsible_else_if)] - if features.is_transaction_simulation_enhancement_enabled() { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::U64(txn_sequence_number), - MoveValue::vector_u8(txn_authentication_key), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(txn_expiration_timestamp_secs), - MoveValue::U8(chain_id.id()), - MoveValue::vector_u8(txn_data.script_hash.clone()), - MoveValue::Bool(is_simulation), - ]; - ( - &APTOS_TRANSACTION_VALIDATION.script_prologue_extended_name, - args, - ) + let secondary_auth_keys: Vec = txn_data + .secondary_authentication_proofs + .iter() + .map(|auth_key| MoveValue::vector_u8(auth_key.optional_auth_key().unwrap_or_default())) + .collect(); + let (prologue_function_name, args) = if let (Some(fee_payer), Some(fee_payer_auth_key)) = ( + txn_data.fee_payer(), + txn_data + .fee_payer_authentication_proof + .as_ref() + .map(|proof| proof.optional_auth_key()), + ) { + if features.is_transaction_simulation_enhancement_enabled() { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::U64(txn_sequence_number), + MoveValue::vector_u8(txn_authentication_key.unwrap_or_default()), + MoveValue::vector_address(txn_data.secondary_signers()), + MoveValue::Vector(secondary_auth_keys), + MoveValue::Address(fee_payer), + MoveValue::vector_u8(fee_payer_auth_key.unwrap_or_default()), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(txn_expiration_timestamp_secs), + MoveValue::U8(chain_id.id()), + MoveValue::Bool(is_simulation), + ]; + ( + &APTOS_TRANSACTION_VALIDATION.fee_payer_prologue_extended_name, + args, + ) + } else { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::U64(txn_sequence_number), + MoveValue::vector_u8(txn_authentication_key.unwrap_or_default()), + MoveValue::vector_address(txn_data.secondary_signers()), + MoveValue::Vector(secondary_auth_keys), + MoveValue::Address(fee_payer), + MoveValue::vector_u8(fee_payer_auth_key.unwrap_or_default()), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(txn_expiration_timestamp_secs), + MoveValue::U8(chain_id.id()), + ]; + (&APTOS_TRANSACTION_VALIDATION.fee_payer_prologue_name, args) + } + } else if txn_data.is_multi_agent() { + if features.is_transaction_simulation_enhancement_enabled() { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::U64(txn_sequence_number), + MoveValue::vector_u8(txn_authentication_key.unwrap_or_default()), + MoveValue::vector_address(txn_data.secondary_signers()), + MoveValue::Vector(secondary_auth_keys), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(txn_expiration_timestamp_secs), + MoveValue::U8(chain_id.id()), + MoveValue::Bool(is_simulation), + ]; + ( + &APTOS_TRANSACTION_VALIDATION.multi_agent_prologue_extended_name, + args, + ) + } else { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::U64(txn_sequence_number), + MoveValue::vector_u8(txn_authentication_key.unwrap_or_default()), + MoveValue::vector_address(txn_data.secondary_signers()), + MoveValue::Vector(secondary_auth_keys), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(txn_expiration_timestamp_secs), + MoveValue::U8(chain_id.id()), + ]; + ( + &APTOS_TRANSACTION_VALIDATION.multi_agent_prologue_name, + args, + ) + } } else { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::U64(txn_sequence_number), - MoveValue::vector_u8(txn_authentication_key), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(txn_expiration_timestamp_secs), - MoveValue::U8(chain_id.id()), - MoveValue::vector_u8(txn_data.script_hash.clone()), - ]; - (&APTOS_TRANSACTION_VALIDATION.script_prologue_name, args) - } - }; - session - .execute_function_bypass_visibility( - &APTOS_TRANSACTION_VALIDATION.module_id(), - prologue_function_name, - vec![], - serialize_values(&args), - &mut gas_meter, - traversal_context, - module_storage, - ) - .map(|_return_vals| ()) - .map_err(expect_no_verification_errors) - .or_else(|err| convert_prologue_error(err, log_context)) + #[allow(clippy::collapsible_else_if)] + if features.is_transaction_simulation_enhancement_enabled() { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::U64(txn_sequence_number), + MoveValue::vector_u8(txn_authentication_key.unwrap_or_default()), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(txn_expiration_timestamp_secs), + MoveValue::U8(chain_id.id()), + MoveValue::vector_u8(txn_data.script_hash.clone()), + MoveValue::Bool(is_simulation), + ]; + ( + &APTOS_TRANSACTION_VALIDATION.script_prologue_extended_name, + args, + ) + } else { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::U64(txn_sequence_number), + MoveValue::vector_u8(txn_authentication_key.unwrap_or_default()), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(txn_expiration_timestamp_secs), + MoveValue::U8(chain_id.id()), + MoveValue::vector_u8(txn_data.script_hash.clone()), + ]; + (&APTOS_TRANSACTION_VALIDATION.script_prologue_name, args) + } + }; + + session + .execute_function_bypass_visibility( + &APTOS_TRANSACTION_VALIDATION.module_id(), + prologue_function_name, + vec![], + serialize_values(&args), + &mut gas_meter, + traversal_context, + module_storage, + ) + .map(|_return_vals| ()) + .map_err(expect_no_verification_errors) + .or_else(|err| convert_prologue_error(err, log_context)) + } } /// Run the prologue for a multisig transaction. This needs to verify that: @@ -232,7 +346,7 @@ pub(crate) fn run_script_prologue( /// match that hash. pub(crate) fn run_multisig_prologue( session: &mut SessionExt, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, txn_data: &TransactionMetadata, payload: &Multisig, features: &Features, @@ -272,7 +386,8 @@ pub(crate) fn run_multisig_prologue( fn run_epilogue( session: &mut SessionExt, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, + serialized_signers: &SerializedSigners, gas_remaining: Gas, fee_statement: FeeStatement, txn_data: &TransactionMetadata, @@ -283,84 +398,115 @@ fn run_epilogue( let txn_gas_price = txn_data.gas_unit_price(); let txn_max_gas_units = txn_data.max_gas_amount(); - // We can unconditionally do this as this condition can only be true if the prologue - // accepted it, in which case the gas payer feature is enabled. - if let Some(fee_payer) = txn_data.fee_payer() { - let (func_name, args) = { - if features.is_transaction_simulation_enhancement_enabled() { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::Address(fee_payer), - MoveValue::U64(fee_statement.storage_fee_refund()), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(gas_remaining.into()), - MoveValue::Bool(is_simulation), - ]; - ( - &APTOS_TRANSACTION_VALIDATION.user_epilogue_gas_payer_extended_name, - args, - ) - } else { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::Address(fee_payer), - MoveValue::U64(fee_statement.storage_fee_refund()), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(gas_remaining.into()), - ]; - ( - &APTOS_TRANSACTION_VALIDATION.user_epilogue_gas_payer_name, - args, - ) - } - }; + if features.is_account_abstraction_enabled() { + let serialize_args = vec![ + serialized_signers.sender(), + serialized_signers + .fee_payer() + .unwrap_or(serialized_signers.sender()), + MoveValue::U64(fee_statement.storage_fee_refund()) + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_gas_price.into()) + .simple_serialize() + .unwrap(), + MoveValue::U64(txn_max_gas_units.into()) + .simple_serialize() + .unwrap(), + MoveValue::U64(gas_remaining.into()) + .simple_serialize() + .unwrap(), + MoveValue::Bool(is_simulation).simple_serialize().unwrap(), + ]; session.execute_function_bypass_visibility( &APTOS_TRANSACTION_VALIDATION.module_id(), - func_name, + &APTOS_TRANSACTION_VALIDATION.unified_epilogue_name, vec![], - serialize_values(&args), + serialize_args, &mut UnmeteredGasMeter, traversal_context, module_storage, ) } else { - // Regular tx, run the normal epilogue - let (func_name, args) = { - if features.is_transaction_simulation_enhancement_enabled() { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::U64(fee_statement.storage_fee_refund()), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(gas_remaining.into()), - MoveValue::Bool(is_simulation), - ]; - ( - &APTOS_TRANSACTION_VALIDATION.user_epilogue_extended_name, - args, - ) - } else { - let args = vec![ - MoveValue::Signer(txn_data.sender), - MoveValue::U64(fee_statement.storage_fee_refund()), - MoveValue::U64(txn_gas_price.into()), - MoveValue::U64(txn_max_gas_units.into()), - MoveValue::U64(gas_remaining.into()), - ]; - (&APTOS_TRANSACTION_VALIDATION.user_epilogue_name, args) - } - }; - session.execute_function_bypass_visibility( - &APTOS_TRANSACTION_VALIDATION.module_id(), - func_name, - vec![], - serialize_values(&args), - &mut UnmeteredGasMeter, - traversal_context, - module_storage, - ) + // We can unconditionally do this as this condition can only be true if the prologue + // accepted it, in which case the gas payer feature is enabled. + if let Some(fee_payer) = txn_data.fee_payer() { + let (func_name, args) = { + if features.is_transaction_simulation_enhancement_enabled() { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::Address(fee_payer), + MoveValue::U64(fee_statement.storage_fee_refund()), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(gas_remaining.into()), + MoveValue::Bool(is_simulation), + ]; + ( + &APTOS_TRANSACTION_VALIDATION.user_epilogue_gas_payer_extended_name, + args, + ) + } else { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::Address(fee_payer), + MoveValue::U64(fee_statement.storage_fee_refund()), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(gas_remaining.into()), + ]; + ( + &APTOS_TRANSACTION_VALIDATION.user_epilogue_gas_payer_name, + args, + ) + } + }; + session.execute_function_bypass_visibility( + &APTOS_TRANSACTION_VALIDATION.module_id(), + func_name, + vec![], + serialize_values(&args), + &mut UnmeteredGasMeter, + traversal_context, + module_storage, + ) + } else { + // Regular tx, run the normal epilogue + let (func_name, args) = { + if features.is_transaction_simulation_enhancement_enabled() { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::U64(fee_statement.storage_fee_refund()), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(gas_remaining.into()), + MoveValue::Bool(is_simulation), + ]; + ( + &APTOS_TRANSACTION_VALIDATION.user_epilogue_extended_name, + args, + ) + } else { + let args = vec![ + MoveValue::Signer(txn_data.sender), + MoveValue::U64(fee_statement.storage_fee_refund()), + MoveValue::U64(txn_gas_price.into()), + MoveValue::U64(txn_max_gas_units.into()), + MoveValue::U64(gas_remaining.into()), + ]; + (&APTOS_TRANSACTION_VALIDATION.user_epilogue_name, args) + } + }; + session.execute_function_bypass_visibility( + &APTOS_TRANSACTION_VALIDATION.module_id(), + func_name, + vec![], + serialize_values(&args), + &mut UnmeteredGasMeter, + traversal_context, + module_storage, + ) + } } .map(|_return_vals| ()) .map_err(expect_no_verification_errors)?; @@ -377,7 +523,7 @@ fn run_epilogue( fn emit_fee_statement( session: &mut SessionExt, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, fee_statement: FeeStatement, traversal_context: &mut TraversalContext, ) -> VMResult<()> { @@ -398,7 +544,8 @@ fn emit_fee_statement( /// in the `ACCOUNT_MODULE` on chain. pub(crate) fn run_success_epilogue( session: &mut SessionExt, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, + serialized_signers: &SerializedSigners, gas_remaining: Gas, fee_statement: FeeStatement, features: &Features, @@ -417,6 +564,7 @@ pub(crate) fn run_success_epilogue( run_epilogue( session, module_storage, + serialized_signers, gas_remaining, fee_statement, txn_data, @@ -431,7 +579,8 @@ pub(crate) fn run_success_epilogue( /// stored in the `ACCOUNT_MODULE` on chain. pub(crate) fn run_failure_epilogue( session: &mut SessionExt, - module_storage: &impl AptosModuleStorage, + module_storage: &impl ModuleStorage, + serialized_signers: &SerializedSigners, gas_remaining: Gas, fee_statement: FeeStatement, features: &Features, @@ -443,6 +592,7 @@ pub(crate) fn run_failure_epilogue( run_epilogue( session, module_storage, + serialized_signers, gas_remaining, fee_statement, txn_data, diff --git a/aptos-move/aptos-vm/src/verifier/transaction_arg_validation.rs b/aptos-move/aptos-vm/src/verifier/transaction_arg_validation.rs index 153f26da17ecf..d6a96952a88e7 100644 --- a/aptos-move/aptos-vm/src/verifier/transaction_arg_validation.rs +++ b/aptos-move/aptos-vm/src/verifier/transaction_arg_validation.rs @@ -6,7 +6,7 @@ //! TODO: we should not only validate the types but also the actual values, e.g. //! for strings whether they consist of correct characters. -use crate::{move_vm_ext::SessionExt, VMStatus}; +use crate::{aptos_vm::SerializedSigners, move_vm_ext::SessionExt, VMStatus}; use aptos_vm_types::module_and_script_storage::module_storage::AptosModuleStorage; use move_binary_format::{ errors::{Location, PartialVMError}, @@ -18,7 +18,6 @@ use move_core_types::{ ident_str, identifier::{IdentStr, Identifier}, language_storage::ModuleId, - value::MoveValue, vm_status::StatusCode, }; use move_vm_metrics::{Timer, VM_TIMER}; @@ -103,10 +102,10 @@ pub(crate) fn get_allowed_structs( /// 3. check arg types are allowed after signers /// /// after validation, add senders and non-signer arguments to generate the final args -pub fn validate_combine_signer_and_txn_args( +pub(crate) fn validate_combine_signer_and_txn_args( session: &mut SessionExt, module_storage: &impl AptosModuleStorage, - senders: Vec, + serialized_signers: &SerializedSigners, args: Vec>, func: &LoadedFunction, are_struct_constructors_enabled: bool, @@ -161,7 +160,8 @@ pub fn validate_combine_signer_and_txn_args( // signers actually passed is matching first to maintain backward compatibility before // moving on to the validation of non-signer args. // the number of txn senders should be the same number of signers - if signer_param_cnt > 0 && senders.len() != signer_param_cnt { + let sender_signers = serialized_signers.senders(); + if signer_param_cnt > 0 && sender_signers.len() != signer_param_cnt { return Err(VMStatus::error( StatusCode::NUMBER_OF_SIGNER_ARGUMENTS_MISMATCH, None, @@ -185,11 +185,7 @@ pub fn validate_combine_signer_and_txn_args( let combined_args = if signer_param_cnt == 0 { args } else { - senders - .into_iter() - .map(|s| MoveValue::Signer(s).simple_serialize().unwrap()) - .chain(args) - .collect() + sender_signers.into_iter().chain(args).collect() }; Ok(combined_args) } diff --git a/aptos-move/aptos-workspace-server/Cargo.toml b/aptos-move/aptos-workspace-server/Cargo.toml index eceb5a50af28a..edc3bf5309727 100644 --- a/aptos-move/aptos-workspace-server/Cargo.toml +++ b/aptos-move/aptos-workspace-server/Cargo.toml @@ -38,5 +38,5 @@ url = { workspace = true } uuid = { workspace = true } # indexer deps -processor = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "51a34901b40d7f75767ac907b4d2478104d6a515", default-features = false } -server-framework = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "51a34901b40d7f75767ac907b4d2478104d6a515" } +processor = { workspace = true } +server-framework = { workspace = true } diff --git a/aptos-move/block-executor/src/code_cache.rs b/aptos-move/block-executor/src/code_cache.rs index 14e5977d314d4..4b12acfa8e635 100644 --- a/aptos-move/block-executor/src/code_cache.rs +++ b/aptos-move/block-executor/src/code_cache.rs @@ -75,7 +75,7 @@ impl<'a, T: Transaction, S: TStateView> ModuleCache for LatestView deserialized_code: Self::Deserialized, extension: Arc, version: Self::Version, - ) -> VMResult<()> { + ) -> VMResult>> { self.as_module_cache().insert_deserialized_module( key, deserialized_code, diff --git a/aptos-move/e2e-benchmark/data/calibration_values.tsv b/aptos-move/e2e-benchmark/data/calibration_values.tsv index 4d4c322b862e3..8cc0431584196 100644 --- a/aptos-move/e2e-benchmark/data/calibration_values.tsv +++ b/aptos-move/e2e-benchmark/data/calibration_values.tsv @@ -8,8 +8,8 @@ InitializeVectorPicture { length: 128 } 34 0.942 1.061 169.4 VectorPicture { length: 128 } 34 0.917 1.058 47.6 VectorPictureRead { length: 128 } 34 0.909 1.075 46.3 InitializeVectorPicture { length: 30720 } 34 0.942 1.057 28928.4 -VectorPicture { length: 30720 } 34 0.924 1.081 6409.9 -VectorPictureRead { length: 30720 } 34 0.938 1.089 6409.9 +VectorPicture { length: 30720 } 34 0.924 1.081 6900.0 +VectorPictureRead { length: 30720 } 34 0.938 1.089 6900.0 SmartTablePicture { length: 30720, num_points_per_txn: 200 } 34 0.972 1.074 42970.1 SmartTablePicture { length: 1048576, num_points_per_txn: 300 } 34 0.960 1.066 73865.4 ResourceGroupsSenderWriteTag { string_length: 1024 } 34 0.898 1.062 16.2 diff --git a/aptos-move/e2e-move-tests/README.md b/aptos-move/e2e-move-tests/README.md new file mode 100644 index 0000000000000..f025e0ca31a9b --- /dev/null +++ b/aptos-move/e2e-move-tests/README.md @@ -0,0 +1,9 @@ +# e2e-move-tests + +## Keyless + +To run the keyless VM tests: + +``` +cargo test -- keyless +``` diff --git a/aptos-move/e2e-move-tests/src/tests/gas.rs b/aptos-move/e2e-move-tests/src/tests/gas.rs index ceab7b3508fa9..5af30e8956693 100644 --- a/aptos-move/e2e-move-tests/src/tests/gas.rs +++ b/aptos-move/e2e-move-tests/src/tests/gas.rs @@ -28,7 +28,7 @@ use aptos_types::{ transaction::{EntryFunction, TransactionPayload}, }; use aptos_vm_environment::prod_configs::set_paranoid_type_checks; -use move_core_types::{identifier::Identifier, language_storage::ModuleId}; +use move_core_types::{identifier::Identifier, language_storage::ModuleId, value::MoveValue}; use rand::{rngs::StdRng, SeedableRng}; use sha3::{Digest, Sha3_512}; use std::path::Path; @@ -55,7 +55,9 @@ fn test_modify_gas_schedule_check_hash() { "set_for_next_epoch_check_hash", vec![], vec![ - bcs::to_bytes(&CORE_CODE_ADDRESS).unwrap(), + MoveValue::Signer(CORE_CODE_ADDRESS) + .simple_serialize() + .unwrap(), bcs::to_bytes(&old_hash).unwrap(), bcs::to_bytes(&bcs::to_bytes(&gas_schedule).unwrap()).unwrap(), ], @@ -64,7 +66,9 @@ fn test_modify_gas_schedule_check_hash() { harness .executor .exec("reconfiguration_with_dkg", "finish", vec![], vec![ - bcs::to_bytes(&CORE_CODE_ADDRESS).unwrap(), + MoveValue::Signer(CORE_CODE_ADDRESS) + .simple_serialize() + .unwrap(), ]); let (_, gas_params) = harness.get_gas_params(); diff --git a/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs b/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs index 08d283cd67feb..2524f6fdffa3d 100644 --- a/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs +++ b/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs @@ -16,6 +16,7 @@ use aptos_types::{ }, AnyKeylessPublicKey, Configuration, EphemeralCertificate, FederatedKeylessPublicKey, Groth16VerificationKey, KeylessPublicKey, KeylessSignature, TransactionAndProof, + VERIFICATION_KEY_FOR_TESTING, }, on_chain_config::FeatureFlag, transaction::{ @@ -35,7 +36,7 @@ use move_core_types::{ }, }; -/// Initializes an Aptos VM and sets the keyless configuration via script (the VK is already set in genesis). +/// Initializes an Aptos VM and sets the keyless configuration via script. fn init_feature_gating( enabled_features: Vec, disabled_features: Vec, @@ -46,6 +47,12 @@ fn init_feature_gating( // initialize JWKs let core_resources = run_jwk_and_config_script(&mut h); + // initialize default VK + run_upgrade_vk_script( + &mut h, + core_resources.clone(), + Groth16VerificationKey::from(VERIFICATION_KEY_FOR_TESTING.clone()), + ); (h, recipient, core_resources) } @@ -256,6 +263,14 @@ fn test_federated_keyless_at_jwk_addr() { let jwk_addr = AccountAddress::from_hex_literal("0xadd").unwrap(); + // Step 0: Make sure the default VK is installed + let core_resources = h.new_account_at(AccountAddress::from_hex_literal("0xA550C18").unwrap()); + run_upgrade_vk_script( + &mut h, + core_resources.clone(), + Groth16VerificationKey::from(VERIFICATION_KEY_FOR_TESTING.clone()), + ); + // Step 1: Make sure TXN validation fails if JWKs are not installed at jwk_addr. let (sig, pk) = get_sample_groth16_sig_and_pk(); let sender = create_federated_keyless_account(&mut h, jwk_addr, pk); @@ -280,7 +295,7 @@ fn test_federated_keyless_at_jwk_addr() { // Step 1: Make sure TXN validation succeeds once JWKs are installed at jwk_addr. let iss = get_sample_iss(); let jwk = get_sample_jwk(); - let _core_resources = install_federated_jwks_and_set_keyless_config(&mut h, jwk_addr, iss, jwk); + let _ = install_federated_jwks_and_set_keyless_config(&mut h, jwk_addr, iss, jwk); let txn = spend_keyless_account(&mut h, sig, &sender, *recipient.address()); let output = h.run_raw(txn); @@ -308,7 +323,14 @@ fn test_federated_keyless_override_at_0x1() { let jwk_addr = AccountAddress::from_hex_literal("0xadd").unwrap(); let iss = get_sample_iss(); let jwk = secure_test_rsa_jwk(); // this will be the wrong JWK - let _core_resources = install_federated_jwks_and_set_keyless_config(&mut h, jwk_addr, iss, jwk); + let core_resources = install_federated_jwks_and_set_keyless_config(&mut h, jwk_addr, iss, jwk); + + // Step 0: Make sure the default VK is installed + run_upgrade_vk_script( + &mut h, + core_resources.clone(), + Groth16VerificationKey::from(VERIFICATION_KEY_FOR_TESTING.clone()), + ); // Step 1: Make sure the TXN does not validate, since the wrong JWK is installed at JWK addr let (sig, pk) = get_sample_groth16_sig_and_pk(); @@ -441,7 +463,7 @@ fn create_and_spend_keyless_account( spend_keyless_account(h, sig, &account, recipient) } -/// Sets the keyless configuration (Note: the VK is already set in genesis.) +/// Sets the keyless configuration fn run_jwk_and_config_script(h: &mut MoveHarness) -> Account { let core_resources = h.new_account_at(AccountAddress::from_hex_literal("0xA550C18").unwrap()); @@ -475,16 +497,14 @@ fn run_jwk_and_config_script(h: &mut MoveHarness) -> Account { .sign(); // NOTE: We cannot write the Configuration and Groth16Verification key via MoveHarness::set_resource - // because it does not (yet) work with resource groups. This is okay, because the VK will be - // there from genesis. + // because it does not (yet) work with resource groups. assert_success!(h.run(txn)); core_resources } -/// Sets the keyless configuration and installs the sample RSA JWK as a federated JWK -/// (Note: the VK is already set in genesis.) +/// Sets the keyless configuration and installs the sample RSA JWK as a federated JWK. fn install_federated_jwks_and_set_keyless_config( h: &mut MoveHarness, jwk_owner: AccountAddress, @@ -524,8 +544,7 @@ fn federated_keyless_init_config(h: &mut MoveHarness, core_resources: Account) { .sign(); // NOTE: We cannot write the Configuration and Groth16Verification key via MoveHarness::set_resource - // because it does not (yet) work with resource groups. This is okay, because the VK will be - // there from genesis. + // because it does not (yet) work with resource groups. assert_success!(h.run(txn)); } @@ -557,8 +576,7 @@ fn federated_keyless_install_jwk( .sign(); // NOTE: We cannot write the Configuration and Groth16Verification key via MoveHarness::set_resource - // because it does not (yet) work with resource groups. This is okay, because the VK will be - // there from genesis. + // because it does not (yet) work with resource groups. assert_success!(h.run(txn)); } diff --git a/aptos-move/e2e-move-tests/src/tests/move_feature_gating.rs b/aptos-move/e2e-move-tests/src/tests/move_feature_gating.rs index 0445fcc1a05ee..3c325c6b87064 100644 --- a/aptos-move/e2e-move-tests/src/tests/move_feature_gating.rs +++ b/aptos-move/e2e-move-tests/src/tests/move_feature_gating.rs @@ -15,7 +15,6 @@ use move_core_types::vm_status::StatusCode; use rstest::rstest; #[rstest(enabled, disabled, - case(vec![], vec![FeatureFlag::ENABLE_ENUM_TYPES]), case(vec![FeatureFlag::ENABLE_ENUM_TYPES], vec![]), )] fn enum_types(enabled: Vec, disabled: Vec) { diff --git a/aptos-move/e2e-move-tests/src/tests/script_with_signer.data/pack/Move.toml b/aptos-move/e2e-move-tests/src/tests/script_with_signer.data/pack/Move.toml new file mode 100644 index 0000000000000..55c9545287791 --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/script_with_signer.data/pack/Move.toml @@ -0,0 +1,5 @@ +[package] +name = "test" +version = "0.0.0" + +[dependencies] diff --git a/aptos-move/e2e-move-tests/src/tests/script_with_signer.data/pack/sources/test.move b/aptos-move/e2e-move-tests/src/tests/script_with_signer.data/pack/sources/test.move new file mode 100644 index 0000000000000..0282617af103e --- /dev/null +++ b/aptos-move/e2e-move-tests/src/tests/script_with_signer.data/pack/sources/test.move @@ -0,0 +1,3 @@ +script { + fun main(s1: &signer, u: u64, s2: &signer) {} +} diff --git a/aptos-move/e2e-move-tests/src/tests/scripts.rs b/aptos-move/e2e-move-tests/src/tests/scripts.rs index 40395dba22ea4..4970695c461ed 100644 --- a/aptos-move/e2e-move-tests/src/tests/scripts.rs +++ b/aptos-move/e2e-move-tests/src/tests/scripts.rs @@ -6,9 +6,9 @@ use aptos_language_e2e_tests::account::TransactionBuilder; use aptos_types::{ account_address::AccountAddress, on_chain_config::FeatureFlag, - transaction::{Script, TransactionArgument}, + transaction::{Script, TransactionArgument, TransactionStatus}, }; -use move_core_types::language_storage::TypeTag; +use move_core_types::{language_storage::TypeTag, value::MoveValue}; #[test] fn test_script_with_object_parameter() { @@ -146,6 +146,45 @@ fn test_script_with_type_parameter() { assert_success!(status); } +#[test] +fn test_script_with_signer_parameter() { + let mut h = MoveHarness::new(); + + let alice = h.new_account_at(AccountAddress::from_hex_literal("0xa11ce").unwrap()); + + let package = build_package( + common::test_dir_path("script_with_signer.data/pack"), + aptos_framework::BuildOptions::default(), + ) + .expect("building package must succeed"); + + let code = package.extract_script_code().into_iter().next().unwrap(); + + let txn = TransactionBuilder::new(alice.clone()) + .script(Script::new(code, vec![], vec![ + TransactionArgument::U64(0), + TransactionArgument::Serialized( + MoveValue::Signer(*alice.address()) + .simple_serialize() + .unwrap(), + ), + ])) + .sequence_number(10) + .max_gas_amount(1_000_000) + .gas_unit_price(1) + .sign(); + + let status = h.run(txn); + assert_eq!( + status, + TransactionStatus::Keep( + aptos_types::transaction::ExecutionStatus::MiscellaneousError(Some( + aptos_types::vm_status::StatusCode::INVALID_MAIN_FUNCTION_SIGNATURE + )) + ) + ); +} + #[test] fn test_two_to_two_transfer() { let mut h = MoveHarness::new(); diff --git a/aptos-move/e2e-tests/src/executor.rs b/aptos-move/e2e-tests/src/executor.rs index 2d3b78221b400..c2039a589d6d6 100644 --- a/aptos-move/e2e-tests/src/executor.rs +++ b/aptos-move/e2e-tests/src/executor.rs @@ -74,6 +74,7 @@ use move_core_types::{ identifier::Identifier, language_storage::{ModuleId, StructTag, TypeTag}, move_resource::{MoveResource, MoveStructType}, + value::MoveValue, }; use move_vm_runtime::{ module_traversal::{TraversalContext, TraversalStorage}, @@ -1042,13 +1043,23 @@ impl FakeExecutor { let mut arg = args.clone(); match &dynamic_args { ExecFuncTimerDynamicArgs::DistinctSigners => { - arg.insert(0, bcs::to_bytes(&extra_accounts.pop().unwrap()).unwrap()); + arg.insert( + 0, + MoveValue::Signer(extra_accounts.pop().unwrap()) + .simple_serialize() + .unwrap(), + ); }, ExecFuncTimerDynamicArgs::DistinctSignersAndFixed(signers) => { for signer in signers.iter().rev() { - arg.insert(0, bcs::to_bytes(&signer).unwrap()); + arg.insert(0, MoveValue::Signer(*signer).simple_serialize().unwrap()); } - arg.insert(0, bcs::to_bytes(&extra_accounts.pop().unwrap()).unwrap()); + arg.insert( + 0, + MoveValue::Signer(extra_accounts.pop().unwrap()) + .simple_serialize() + .unwrap(), + ); }, _ => {}, } diff --git a/aptos-move/framework/aptos-framework/doc/account.md b/aptos-move/framework/aptos-framework/doc/account.md index 9566844a0f739..79323892386bd 100644 --- a/aptos-move/framework/aptos-framework/doc/account.md +++ b/aptos-move/framework/aptos-framework/doc/account.md @@ -19,7 +19,12 @@ - [Struct `SignerCapabilityOfferProofChallenge`](#0x1_account_SignerCapabilityOfferProofChallenge) - [Struct `RotationCapabilityOfferProofChallengeV2`](#0x1_account_RotationCapabilityOfferProofChallengeV2) - [Struct `SignerCapabilityOfferProofChallengeV2`](#0x1_account_SignerCapabilityOfferProofChallengeV2) +- [Enum `AccountPermission`](#0x1_account_AccountPermission) - [Constants](#@Constants_0) +- [Function `check_rotation_permission`](#0x1_account_check_rotation_permission) +- [Function `check_offering_permission`](#0x1_account_check_offering_permission) +- [Function `grant_key_rotation_permission`](#0x1_account_grant_key_rotation_permission) +- [Function `grant_key_offering_permission`](#0x1_account_grant_key_offering_permission) - [Function `initialize`](#0x1_account_initialize) - [Function `create_account_if_does_not_exist`](#0x1_account_create_account_if_does_not_exist) - [Function `create_account`](#0x1_account_create_account) @@ -110,6 +115,7 @@ use 0x1::hash; use 0x1::multi_ed25519; use 0x1::option; +use 0x1::permissioned_signer; use 0x1::signer; use 0x1::system_addresses; use 0x1::table; @@ -639,6 +645,55 @@ This V2 struct adds the chain_id + + + + +## Enum `AccountPermission` + + + +
enum AccountPermission has copy, drop, store
+
+ + + +
+Variants + + +
+KeyRotation + + +
+Fields + + +
+
+ + +
+ +
+ +
+Offering + + +
+Fields + + +
+
+ + +
+ +
+
@@ -798,6 +853,16 @@ The current authentication key and the new authentication key are the same + + +Current permissioned signer cannot perform the privilaged operations. + + +
const ENO_ACCOUNT_PERMISSION: u64 = 23;
+
+ + + The caller does not have a digital-signature-based capability to call this function @@ -926,6 +991,115 @@ Scheme identifier for MultiEd25519 signatures used to derive authentication keys + + +## Function `check_rotation_permission` + +Permissions + + +
fun check_rotation_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_rotation_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, AccountPermission::KeyRotation {}),
+        error::permission_denied(ENO_ACCOUNT_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `check_offering_permission` + + + +
fun check_offering_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_offering_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, AccountPermission::Offering {}),
+        error::permission_denied(ENO_ACCOUNT_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_key_rotation_permission` + +Grant permission to perform key rotations on behalf of the master signer. + +This is **extremely dangerous** and should be granted only when it's absolutely needed. + + +
public fun grant_key_rotation_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_key_rotation_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, AccountPermission::KeyRotation {})
+}
+
+ + + +
+ + + +## Function `grant_key_offering_permission` + +Grant permission to use offered address's signer on behalf of the master signer. + +This is **extremely dangerous** and should be granted only when it's absolutely needed. + + +
public fun grant_key_offering_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_key_offering_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, AccountPermission::Offering {})
+}
+
+ + + +
+ ## Function `initialize` @@ -1256,6 +1430,7 @@ many contexts: vector::length(&new_auth_key) == 32, error::invalid_argument(EMALFORMED_AUTHENTICATION_KEY) ); + check_rotation_permission(account); let account_resource = borrow_global_mut<Account>(addr); account_resource.authentication_key = new_auth_key; } @@ -1351,6 +1526,7 @@ to rotate his address to Alice's address in the first place. ) acquires Account, OriginatingAddress { let addr = signer::address_of(account); assert!(exists_at(addr), error::not_found(EACCOUNT_DOES_NOT_EXIST)); + check_rotation_permission(account); let account_resource = borrow_global_mut<Account>(addr); // Verify the given `from_public_key_bytes` matches this account's current authentication key. @@ -1426,6 +1602,7 @@ to rotate his address to Alice's address in the first place. new_public_key_bytes: vector<u8>, cap_update_table: vector<u8> ) acquires Account, OriginatingAddress { + check_rotation_permission(delegate_signer); assert!(exists_at(rotation_cap_offerer_address), error::not_found(EOFFERER_ADDRESS_DOES_NOT_EXIST)); // Check that there exists a rotation capability offer at the offerer's account resource for the delegate. @@ -1505,6 +1682,7 @@ offer, calling this function will replace the previous recipient_addressvector<u8>, recipient_address: address, ) acquires Account { + check_rotation_permission(account); let addr = signer::address_of(account); assert!(exists_at(recipient_address), error::not_found(EACCOUNT_DOES_NOT_EXIST)); @@ -1683,6 +1861,7 @@ Revoke the rotation capability offer given to to_be_revoked_recipient_addr
public entry fun revoke_rotation_capability(account: &signer, to_be_revoked_address: address) acquires Account {
     assert!(exists_at(to_be_revoked_address), error::not_found(EACCOUNT_DOES_NOT_EXIST));
+    check_rotation_permission(account);
     let addr = signer::address_of(account);
     let account_resource = borrow_global<Account>(addr);
     assert!(
@@ -1714,6 +1893,7 @@ Revoke any rotation capability offer in the specified account.
 
 
 
public entry fun revoke_any_rotation_capability(account: &signer) acquires Account {
+    check_rotation_permission(account);
     let account_resource = borrow_global_mut<Account>(signer::address_of(account));
     option::extract(&mut account_resource.rotation_capability_offer.for);
 }
@@ -1754,6 +1934,7 @@ to the account owner's signer capability).
     account_public_key_bytes: vector<u8>,
     recipient_address: address
 ) acquires Account {
+    check_offering_permission(account);
     let source_address = signer::address_of(account);
     assert!(exists_at(recipient_address), error::not_found(EACCOUNT_DOES_NOT_EXIST));
 
@@ -1853,6 +2034,7 @@ has a signer capability offer from accoun
 
 
public entry fun revoke_signer_capability(account: &signer, to_be_revoked_address: address) acquires Account {
     assert!(exists_at(to_be_revoked_address), error::not_found(EACCOUNT_DOES_NOT_EXIST));
+    check_offering_permission(account);
     let addr = signer::address_of(account);
     let account_resource = borrow_global<Account>(addr);
     assert!(
@@ -1884,6 +2066,7 @@ Revoke any signer capability offer in the specified account.
 
 
 
public entry fun revoke_any_signer_capability(account: &signer) acquires Account {
+    check_offering_permission(account);
     let account_resource = borrow_global_mut<Account>(signer::address_of(account));
     option::extract(&mut account_resource.signer_capability_offer.for);
 }
@@ -1911,6 +2094,7 @@ at the offerer's address.
 
 
 
public fun create_authorized_signer(account: &signer, offerer_address: address): signer acquires Account {
+    check_offering_permission(account);
     assert!(exists_at(offerer_address), error::not_found(EOFFERER_ADDRESS_DOES_NOT_EXIST));
 
     // Check if there's an existing signer capability offer from the offerer.
@@ -2514,8 +2698,7 @@ Capability based functions for efficient use.
 ### Module-level Specification
 
 
-
pragma verify = true;
-pragma aborts_if_is_strict;
+
pragma verify = false;
 
diff --git a/aptos-move/framework/aptos-framework/doc/account_abstraction.md b/aptos-move/framework/aptos-framework/doc/account_abstraction.md new file mode 100644 index 0000000000000..ed670f841a159 --- /dev/null +++ b/aptos-move/framework/aptos-framework/doc/account_abstraction.md @@ -0,0 +1,581 @@ + + + +# Module `0x1::account_abstraction` + + + +- [Struct `UpdateDispatchableAuthenticator`](#0x1_account_abstraction_UpdateDispatchableAuthenticator) +- [Struct `RemoveDispatchableAuthenticator`](#0x1_account_abstraction_RemoveDispatchableAuthenticator) +- [Enum Resource `DispatchableAuthenticator`](#0x1_account_abstraction_DispatchableAuthenticator) +- [Constants](#@Constants_0) +- [Function `add_dispatchable_authentication_function`](#0x1_account_abstraction_add_dispatchable_authentication_function) +- [Function `remove_dispatchable_authentication_function`](#0x1_account_abstraction_remove_dispatchable_authentication_function) +- [Function `remove_dispatchable_authenticator`](#0x1_account_abstraction_remove_dispatchable_authenticator) +- [Function `resource_addr`](#0x1_account_abstraction_resource_addr) +- [Function `update_dispatchable_authenticator_impl`](#0x1_account_abstraction_update_dispatchable_authenticator_impl) +- [Function `using_dispatchable_authenticator`](#0x1_account_abstraction_using_dispatchable_authenticator) +- [Function `dispatchable_authenticator`](#0x1_account_abstraction_dispatchable_authenticator) +- [Function `dispatchable_authenticator_internal`](#0x1_account_abstraction_dispatchable_authenticator_internal) +- [Function `authenticate`](#0x1_account_abstraction_authenticate) +- [Function `dispatchable_authenticate`](#0x1_account_abstraction_dispatchable_authenticate) +- [Specification](#@Specification_1) + - [Function `dispatchable_authenticate`](#@Specification_1_dispatchable_authenticate) + + +
use 0x1::auth_data;
+use 0x1::create_signer;
+use 0x1::error;
+use 0x1::event;
+use 0x1::function_info;
+use 0x1::object;
+use 0x1::option;
+use 0x1::ordered_map;
+use 0x1::permissioned_signer;
+use 0x1::signer;
+use 0x1::string;
+
+ + + + + +## Struct `UpdateDispatchableAuthenticator` + + + +
#[event]
+struct UpdateDispatchableAuthenticator has drop, store
+
+ + + +
+Fields + + +
+
+account: address +
+
+ +
+
+update: vector<u8> +
+
+ +
+
+auth_function: function_info::FunctionInfo +
+
+ +
+
+ + +
+ + + +## Struct `RemoveDispatchableAuthenticator` + + + +
#[event]
+struct RemoveDispatchableAuthenticator has drop, store
+
+ + + +
+Fields + + +
+
+account: address +
+
+ +
+
+ + +
+ + + +## Enum Resource `DispatchableAuthenticator` + +The dispatchable authenticator that defines how to authenticates this account in the specified module. +An integral part of Account Abstraction. + + +
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
+enum DispatchableAuthenticator has copy, drop, key
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+auth_functions: ordered_map::OrderedMap<function_info::FunctionInfo, bool> +
+
+ +
+
+ + +
+ +
+ +
+ + + +## Constants + + + + + + +
const MAX_U64: u128 = 18446744073709551615;
+
+ + + + + + + +
const ENOT_MASTER_SIGNER: u64 = 4;
+
+ + + + + + + +
const EAUTH_FUNCTION_SIGNATURE_MISMATCH: u64 = 3;
+
+ + + + + + + +
const EDISPATCHABLE_AUTHENTICATOR_IS_NOT_USED: u64 = 1;
+
+ + + + + + + +
const EFUNCTION_INFO_EXISTENCE: u64 = 2;
+
+ + + + + +## Function `add_dispatchable_authentication_function` + +Update dispatchable authenticator that enables account abstraction. +Note: it is a private entry function that can only be called directly from transaction. + + +
public entry fun add_dispatchable_authentication_function(account: &signer, module_address: address, module_name: string::String, function_name: string::String)
+
+ + + +
+Implementation + + +
public entry fun add_dispatchable_authentication_function(
+    account: &signer,
+    module_address: address,
+    module_name: String,
+    function_name: String,
+) acquires DispatchableAuthenticator {
+    assert!(!is_permissioned_signer(account), error::permission_denied(ENOT_MASTER_SIGNER));
+    update_dispatchable_authenticator_impl(
+        account,
+        function_info::new_function_info_from_address(module_address, module_name, function_name),
+        true
+    );
+}
+
+ + + +
+ + + +## Function `remove_dispatchable_authentication_function` + + + +
public entry fun remove_dispatchable_authentication_function(account: &signer, module_address: address, module_name: string::String, function_name: string::String)
+
+ + + +
+Implementation + + +
public entry fun remove_dispatchable_authentication_function(
+    account: &signer,
+    module_address: address,
+    module_name: String,
+    function_name: String,
+) acquires DispatchableAuthenticator {
+    assert!(!is_permissioned_signer(account), error::permission_denied(ENOT_MASTER_SIGNER));
+    update_dispatchable_authenticator_impl(
+        account,
+        function_info::new_function_info_from_address(module_address, module_name, function_name),
+        false
+    );
+}
+
+ + + +
+ + + +## Function `remove_dispatchable_authenticator` + +Update dispatchable authenticator that disables account abstraction. +Note: it is a private entry function that can only be called directly from transaction. + + +
public entry fun remove_dispatchable_authenticator(account: &signer)
+
+ + + +
+Implementation + + +
public entry fun remove_dispatchable_authenticator(
+    account: &signer,
+) acquires DispatchableAuthenticator {
+    assert!(!is_permissioned_signer(account), error::permission_denied(ENOT_MASTER_SIGNER));
+    let addr = signer::address_of(account);
+    let resource_addr = resource_addr(addr);
+    if (exists<DispatchableAuthenticator>(resource_addr)) {
+        move_from<DispatchableAuthenticator>(resource_addr);
+        event::emit(RemoveDispatchableAuthenticator {
+            account: addr,
+        });
+    };
+}
+
+ + + +
+ + + +## Function `resource_addr` + + + +
fun resource_addr(source: address): address
+
+ + + +
+Implementation + + +
inline fun resource_addr(source: address): address {
+    object::create_user_derived_object_address(source, @aptos_fungible_asset)
+}
+
+ + + +
+ + + +## Function `update_dispatchable_authenticator_impl` + + + +
fun update_dispatchable_authenticator_impl(account: &signer, auth_function: function_info::FunctionInfo, is_add: bool)
+
+ + + +
+Implementation + + +
fun update_dispatchable_authenticator_impl(
+    account: &signer,
+    auth_function: FunctionInfo,
+    is_add: bool,
+) acquires DispatchableAuthenticator {
+    let addr = signer::address_of(account);
+    let resource_addr = resource_addr(addr);
+    let dispatcher_auth_function_info = function_info::new_function_info_from_address(
+        @aptos_framework,
+        string::utf8(b"account_abstraction"),
+        string::utf8(b"dispatchable_authenticate"),
+    );
+    assert!(
+        function_info::check_dispatch_type_compatibility(&dispatcher_auth_function_info, &auth_function),
+        error::invalid_argument(EAUTH_FUNCTION_SIGNATURE_MISMATCH)
+    );
+    if (is_add && !exists<DispatchableAuthenticator>(resource_addr)) {
+        move_to(
+            &create_signer::create_signer(resource_addr),
+            DispatchableAuthenticator::V1 { auth_functions: ordered_map::new() }
+        );
+    };
+    if (exists<DispatchableAuthenticator>(resource_addr)) {
+        let current_map = &mut borrow_global_mut<DispatchableAuthenticator>(resource_addr).auth_functions;
+        if (is_add) {
+            assert!(
+                !ordered_map::contains(current_map, &auth_function),
+                error::already_exists(EFUNCTION_INFO_EXISTENCE)
+            );
+            ordered_map::add(current_map, auth_function, true);
+        } else {
+            assert!(
+                ordered_map::contains(current_map, &auth_function),
+                error::not_found(EFUNCTION_INFO_EXISTENCE)
+            );
+            ordered_map::remove(current_map, &auth_function);
+        };
+        event::emit(
+            UpdateDispatchableAuthenticator {
+                account: addr,
+                update: if (is_add) { b"add" } else { b"remove" },
+                auth_function,
+            }
+        );
+        if (ordered_map::length(current_map) == 0) {
+            remove_dispatchable_authenticator(account);
+        }
+    };
+}
+
+ + + +
+ + + +## Function `using_dispatchable_authenticator` + +Return true if the account is an abstracted account that can be authenticated with dispatchable move authenticator. + + +
#[view]
+public fun using_dispatchable_authenticator(addr: address): bool
+
+ + + +
+Implementation + + +
public fun using_dispatchable_authenticator(addr: address): bool {
+    exists<DispatchableAuthenticator>(resource_addr(addr))
+}
+
+ + + +
+ + + +## Function `dispatchable_authenticator` + +Return the current dispatchable authenticator move function info. None means this authentication scheme is disabled. + + +
#[view]
+public fun dispatchable_authenticator(addr: address): option::Option<vector<function_info::FunctionInfo>>
+
+ + + +
+Implementation + + +
public fun dispatchable_authenticator(addr: address): Option<vector<FunctionInfo>> acquires DispatchableAuthenticator {
+    let resource_addr = resource_addr(addr);
+    if (exists<DispatchableAuthenticator>(resource_addr)) {
+        option::some(
+            ordered_map::keys(&borrow_global<DispatchableAuthenticator>(resource_addr).auth_functions)
+        )
+    } else { option::none() }
+}
+
+ + + +
+ + + +## Function `dispatchable_authenticator_internal` + + + +
fun dispatchable_authenticator_internal(addr: address): &ordered_map::OrderedMap<function_info::FunctionInfo, bool>
+
+ + + +
+Implementation + + +
inline fun dispatchable_authenticator_internal(addr: address): &OrderedMap<FunctionInfo, bool> {
+    assert!(using_dispatchable_authenticator(addr), error::not_found(EDISPATCHABLE_AUTHENTICATOR_IS_NOT_USED));
+    &borrow_global<DispatchableAuthenticator>(resource_addr(addr)).auth_functions
+}
+
+ + + +
+ + + +## Function `authenticate` + + + +
fun authenticate(account: signer, func_info: function_info::FunctionInfo, signing_data: auth_data::AbstractionAuthData): signer
+
+ + + +
+Implementation + + +
fun authenticate(
+    account: signer,
+    func_info: FunctionInfo,
+    signing_data: AbstractionAuthData,
+): signer acquires DispatchableAuthenticator {
+    let func_infos = dispatchable_authenticator_internal(signer::address_of(&account));
+    assert!(ordered_map::contains(func_infos, &func_info), error::not_found(EFUNCTION_INFO_EXISTENCE));
+    function_info::load_module_from_function(&func_info);
+    dispatchable_authenticate(account, signing_data, &func_info)
+}
+
+ + + +
+ + + +## Function `dispatchable_authenticate` + +The native function to dispatch customized move authentication function. + + +
fun dispatchable_authenticate(account: signer, signing_data: auth_data::AbstractionAuthData, function: &function_info::FunctionInfo): signer
+
+ + + +
+Implementation + + +
native fun dispatchable_authenticate(
+    account: signer,
+    signing_data: AbstractionAuthData,
+    function: &FunctionInfo
+): signer;
+
+ + + +
+ + + +## Specification + + + +
pragma verify = false;
+
+ + + + + + + +
fun spec_dispatchable_authenticate(
+   account: signer,
+   signing_data: AbstractionAuthData,
+   function: &FunctionInfo
+): signer;
+
+ + + + + +### Function `dispatchable_authenticate` + + +
fun dispatchable_authenticate(account: signer, signing_data: auth_data::AbstractionAuthData, function: &function_info::FunctionInfo): signer
+
+ + + + +
pragma opaque;
+ensures [abstract] result == spec_dispatchable_authenticate(account, signing_data, function);
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/aptos_account.md b/aptos-move/framework/aptos-framework/doc/aptos_account.md index ca0c0c6d96600..d3be0dbd22b85 100644 --- a/aptos-move/framework/aptos-framework/doc/aptos_account.md +++ b/aptos-move/framework/aptos-framework/doc/aptos_account.md @@ -707,6 +707,7 @@ to transfer APT) - if we want to allow APT PFS without account itself // as APT cannot be frozen or have dispatch, and PFS cannot be transfered // (PFS could potentially be burned. regular transfer would permanently unburn the store. // Ignoring the check here has the equivalent of unburning, transfers, and then burning again) + fungible_asset::withdraw_permission_check_by_address(source, sender_store, amount); fungible_asset::unchecked_deposit(recipient_store, fungible_asset::unchecked_withdraw(sender_store, amount)); }
diff --git a/aptos-move/framework/aptos-framework/doc/aptos_coin.md b/aptos-move/framework/aptos-framework/doc/aptos_coin.md index 30f3eae067ed8..14dc44ea1909d 100644 --- a/aptos-move/framework/aptos-framework/doc/aptos_coin.md +++ b/aptos-move/framework/aptos-framework/doc/aptos_coin.md @@ -513,7 +513,7 @@ Claim the delegated mint capability and destroy the delegated token.
pragma verify = true;
-pragma aborts_if_is_strict;
+pragma aborts_if_is_partial;
 
@@ -529,7 +529,9 @@ Claim the delegated mint capability and destroy the delegated token. -
let addr = signer::address_of(aptos_framework);
+
pragma verify = false;
+aborts_if permissioned_signer::spec_is_permissioned_signer(aptos_framework);
+let addr = signer::address_of(aptos_framework);
 aborts_if addr != @aptos_framework;
 aborts_if !string::spec_internal_check_utf8(b"Aptos Coin");
 aborts_if !string::spec_internal_check_utf8(b"APT");
diff --git a/aptos-move/framework/aptos-framework/doc/aptos_governance.md b/aptos-move/framework/aptos-framework/doc/aptos_governance.md
index 0edd157f955d2..1caea3d905f98 100644
--- a/aptos-move/framework/aptos-framework/doc/aptos_governance.md
+++ b/aptos-move/framework/aptos-framework/doc/aptos_governance.md
@@ -29,7 +29,10 @@ on a proposal multiple times as long as the total voting power of these votes do
 -  [Struct `CreateProposal`](#0x1_aptos_governance_CreateProposal)
 -  [Struct `Vote`](#0x1_aptos_governance_Vote)
 -  [Struct `UpdateConfig`](#0x1_aptos_governance_UpdateConfig)
+-  [Struct `GovernancePermission`](#0x1_aptos_governance_GovernancePermission)
 -  [Constants](#@Constants_0)
+-  [Function `check_governance_permission`](#0x1_aptos_governance_check_governance_permission)
+-  [Function `grant_permission`](#0x1_aptos_governance_grant_permission)
 -  [Function `store_signer_cap`](#0x1_aptos_governance_store_signer_cap)
 -  [Function `initialize`](#0x1_aptos_governance_initialize)
 -  [Function `update_governance_config`](#0x1_aptos_governance_update_governance_config)
@@ -109,6 +112,7 @@ on a proposal multiple times as long as the total voting power of these votes do
 use 0x1::governance_proposal;
 use 0x1::math64;
 use 0x1::option;
+use 0x1::permissioned_signer;
 use 0x1::randomness_config;
 use 0x1::reconfiguration_with_dkg;
 use 0x1::signer;
@@ -642,6 +646,33 @@ Event emitted when the governance configs are updated.
 
 
 
+
+
+
+
+## Struct `GovernancePermission`
+
+
+
+
struct GovernancePermission has copy, drop, store
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ +
@@ -738,6 +769,16 @@ The proposal in the argument is not a partial voting proposal. + + +Current permissioned signer cannot perform governance operations. + + +
const ENO_GOVERNANCE_PERMISSION: u64 = 16;
+
+ + + The specified stake pool must be part of the validator set @@ -827,6 +868,59 @@ Proposal metadata attribute keys. + + +## Function `check_governance_permission` + +Permissions + + +
fun check_governance_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_governance_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, GovernancePermission {}),
+        error::permission_denied(ENO_GOVERNANCE_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_permission` + +Grant permission to perform governance operations on behalf of the master signer. + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, GovernancePermission {})
+}
+
+ + + +
+ ## Function `store_signer_cap` @@ -1310,6 +1404,7 @@ Return proposal_id when a proposal is successfully created. metadata_hash: vector<u8>, is_multi_step_proposal: bool, ): u64 acquires GovernanceConfig, GovernanceEvents { + check_governance_permission(proposer); let proposer_address = signer::address_of(proposer); assert!( stake::get_delegated_voter(stake_pool) == proposer_address, @@ -1542,6 +1637,7 @@ cannot vote on the proposal even after partial governance voting is enabled. voting_power: u64, should_pass: bool, ) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents { + permissioned_signer::assert_master_signer(voter); let voter_address = signer::address_of(voter); assert!(stake::get_delegated_voter(stake_pool) == voter_address, error::invalid_argument(ENOT_DELEGATED_VOTER)); @@ -2118,7 +2214,20 @@ Return a signer for making changes to 0x1 as part of on-chain governance proposa
pragma verify = true;
-pragma aborts_if_is_strict;
+pragma aborts_if_is_partial;
+
+ + + + + + + +
schema AbortsIfPermissionedSigner {
+    s: signer;
+    let perm = GovernancePermission {};
+    aborts_if !permissioned_signer::spec_check_permission_exists(s, perm);
+}
 
diff --git a/aptos-move/framework/aptos-framework/doc/auth_data.md b/aptos-move/framework/aptos-framework/doc/auth_data.md new file mode 100644 index 0000000000000..d24ad59f5cc25 --- /dev/null +++ b/aptos-move/framework/aptos-framework/doc/auth_data.md @@ -0,0 +1,111 @@ + + + +# Module `0x1::auth_data` + + + +- [Enum `AbstractionAuthData`](#0x1_auth_data_AbstractionAuthData) +- [Function `digest`](#0x1_auth_data_digest) +- [Function `authenticator`](#0x1_auth_data_authenticator) + + +
+ + + + + +## Enum `AbstractionAuthData` + + + +
enum AbstractionAuthData has copy, drop
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+digest: vector<u8> +
+
+ +
+
+authenticator: vector<u8> +
+
+ +
+
+ + +
+ +
+ +
+ + + +## Function `digest` + + + +
public fun digest(signing_data: &auth_data::AbstractionAuthData): &vector<u8>
+
+ + + +
+Implementation + + +
public fun digest(signing_data: &AbstractionAuthData): &vector<u8> {
+    &signing_data.digest
+}
+
+ + + +
+ + + +## Function `authenticator` + + + +
public fun authenticator(signing_data: &auth_data::AbstractionAuthData): &vector<u8>
+
+ + + +
+Implementation + + +
public fun authenticator(signing_data: &AbstractionAuthData): &vector<u8> {
+    &signing_data.authenticator
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/bcs_stream.md b/aptos-move/framework/aptos-framework/doc/bcs_stream.md new file mode 100644 index 0000000000000..1de9a5914caf2 --- /dev/null +++ b/aptos-move/framework/aptos-framework/doc/bcs_stream.md @@ -0,0 +1,663 @@ + + + +# Module `0x1::bcs_stream` + +This module enables the deserialization of BCS-formatted byte arrays into Move primitive types. +Deserialization Strategies: +- Per-Byte Deserialization: Employed for most types to ensure lower gas consumption, this method processes each byte +individually to match the length and type requirements of target Move types. +- Exception: For the deserialize_address function, the function-based approach from aptos_std::from_bcs is used +due to type constraints, even though it is generally more gas-intensive. +- This can be optimized further by introducing native vector slices. +Application: +- This deserializer is particularly valuable for processing BCS serialized data within Move modules, +especially useful for systems requiring cross-chain message interpretation or off-chain data verification. + + +- [Struct `BCSStream`](#0x1_bcs_stream_BCSStream) +- [Constants](#@Constants_0) +- [Function `new`](#0x1_bcs_stream_new) +- [Function `deserialize_uleb128`](#0x1_bcs_stream_deserialize_uleb128) +- [Function `deserialize_bool`](#0x1_bcs_stream_deserialize_bool) +- [Function `deserialize_address`](#0x1_bcs_stream_deserialize_address) +- [Function `deserialize_u8`](#0x1_bcs_stream_deserialize_u8) +- [Function `deserialize_u16`](#0x1_bcs_stream_deserialize_u16) +- [Function `deserialize_u32`](#0x1_bcs_stream_deserialize_u32) +- [Function `deserialize_u64`](#0x1_bcs_stream_deserialize_u64) +- [Function `deserialize_u128`](#0x1_bcs_stream_deserialize_u128) +- [Function `deserialize_u256`](#0x1_bcs_stream_deserialize_u256) +- [Function `deserialize_u256_entry`](#0x1_bcs_stream_deserialize_u256_entry) +- [Function `deserialize_vector`](#0x1_bcs_stream_deserialize_vector) +- [Function `deserialize_string`](#0x1_bcs_stream_deserialize_string) +- [Function `deserialize_option`](#0x1_bcs_stream_deserialize_option) +- [Specification](#@Specification_1) + + +
use 0x1::error;
+use 0x1::from_bcs;
+use 0x1::string;
+use 0x1::vector;
+
+ + + + + +## Struct `BCSStream` + + + +
struct BCSStream has drop
+
+ + + +
+Fields + + +
+
+data: vector<u8> +
+
+ Byte buffer containing the serialized data. +
+
+cur: u64 +
+
+ Cursor indicating the current position in the byte buffer. +
+
+ + +
+ + + +## Constants + + + + +The data does not fit the expected format. + + +
const EMALFORMED_DATA: u64 = 1;
+
+ + + + + +There are not enough bytes to deserialize for the given type. + + +
const EOUT_OF_BYTES: u64 = 2;
+
+ + + + + +## Function `new` + +Constructs a new BCSStream instance from the provided byte array. + + +
public fun new(data: vector<u8>): bcs_stream::BCSStream
+
+ + + +
+Implementation + + +
public fun new(data: vector<u8>): BCSStream {
+    BCSStream {
+        data,
+        cur: 0,
+    }
+}
+
+ + + +
+ + + +## Function `deserialize_uleb128` + +Deserializes a ULEB128-encoded integer from the stream. +In the BCS format, lengths of vectors are represented using ULEB128 encoding. + + +
public fun deserialize_uleb128(stream: &mut bcs_stream::BCSStream): u64
+
+ + + +
+Implementation + + +
public fun deserialize_uleb128(stream: &mut BCSStream): u64 {
+    let res = 0;
+    let shift = 0;
+
+    while (stream.cur < vector::length(&stream.data)) {
+        let byte = *vector::borrow(&stream.data, stream.cur);
+        stream.cur = stream.cur + 1;
+
+        let val = ((byte & 0x7f) as u64);
+        if (((val << shift) >> shift) != val) {
+            abort error::invalid_argument(EMALFORMED_DATA)
+        };
+        res = res | (val << shift);
+
+        if ((byte & 0x80) == 0) {
+            if (shift > 0 && val == 0) {
+                abort error::invalid_argument(EMALFORMED_DATA)
+            };
+            return res
+        };
+
+        shift = shift + 7;
+        if (shift > 64) {
+            abort error::invalid_argument(EMALFORMED_DATA)
+        };
+    };
+
+    abort error::out_of_range(EOUT_OF_BYTES)
+}
+
+ + + +
+ + + +## Function `deserialize_bool` + +Deserializes a bool value from the stream. + + +
public fun deserialize_bool(stream: &mut bcs_stream::BCSStream): bool
+
+ + + +
+Implementation + + +
public fun deserialize_bool(stream: &mut BCSStream): bool {
+    assert!(stream.cur < vector::length(&stream.data), error::out_of_range(EOUT_OF_BYTES));
+    let byte = *vector::borrow(&stream.data, stream.cur);
+    stream.cur = stream.cur + 1;
+    if (byte == 0) {
+        false
+    } else if (byte == 1) {
+        true
+    } else {
+        abort error::invalid_argument(EMALFORMED_DATA)
+    }
+}
+
+ + + +
+ + + +## Function `deserialize_address` + +Deserializes an address value from the stream. +32-byte address values are serialized using little-endian byte order. +This function utilizes the to_address function from the aptos_std::from_bcs module, +because the Move type system does not permit per-byte referencing of addresses. + + +
public fun deserialize_address(stream: &mut bcs_stream::BCSStream): address
+
+ + + +
+Implementation + + +
public fun deserialize_address(stream: &mut BCSStream): address {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 32 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res = from_bcs::to_address(vector::slice(data, cur, cur + 32));
+
+    stream.cur = cur + 32;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u8` + +Deserializes a u8 value from the stream. +1-byte u8 values are serialized using little-endian byte order. + + +
public fun deserialize_u8(stream: &mut bcs_stream::BCSStream): u8
+
+ + + +
+Implementation + + +
public fun deserialize_u8(stream: &mut BCSStream): u8 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur < vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+
+    let res = *vector::borrow(data, cur);
+
+    stream.cur = cur + 1;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u16` + +Deserializes a u16 value from the stream. +2-byte u16 values are serialized using little-endian byte order. + + +
public fun deserialize_u16(stream: &mut bcs_stream::BCSStream): u16
+
+ + + +
+Implementation + + +
public fun deserialize_u16(stream: &mut BCSStream): u16 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 2 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u16) |
+            ((*vector::borrow(data, cur + 1) as u16) << 8)
+    ;
+
+    stream.cur = stream.cur + 2;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u32` + +Deserializes a u32 value from the stream. +4-byte u32 values are serialized using little-endian byte order. + + +
public fun deserialize_u32(stream: &mut bcs_stream::BCSStream): u32
+
+ + + +
+Implementation + + +
public fun deserialize_u32(stream: &mut BCSStream): u32 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 4 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u32) |
+            ((*vector::borrow(data, cur + 1) as u32) << 8) |
+            ((*vector::borrow(data, cur + 2) as u32) << 16) |
+            ((*vector::borrow(data, cur + 3) as u32) << 24)
+    ;
+
+    stream.cur = stream.cur + 4;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u64` + +Deserializes a u64 value from the stream. +8-byte u64 values are serialized using little-endian byte order. + + +
public fun deserialize_u64(stream: &mut bcs_stream::BCSStream): u64
+
+ + + +
+Implementation + + +
public fun deserialize_u64(stream: &mut BCSStream): u64 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 8 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u64) |
+            ((*vector::borrow(data, cur + 1) as u64) << 8) |
+            ((*vector::borrow(data, cur + 2) as u64) << 16) |
+            ((*vector::borrow(data, cur + 3) as u64) << 24) |
+            ((*vector::borrow(data, cur + 4) as u64) << 32) |
+            ((*vector::borrow(data, cur + 5) as u64) << 40) |
+            ((*vector::borrow(data, cur + 6) as u64) << 48) |
+            ((*vector::borrow(data, cur + 7) as u64) << 56)
+    ;
+
+    stream.cur = stream.cur + 8;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u128` + +Deserializes a u128 value from the stream. +16-byte u128 values are serialized using little-endian byte order. + + +
public fun deserialize_u128(stream: &mut bcs_stream::BCSStream): u128
+
+ + + +
+Implementation + + +
public fun deserialize_u128(stream: &mut BCSStream): u128 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 16 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u128) |
+            ((*vector::borrow(data, cur + 1) as u128) << 8) |
+            ((*vector::borrow(data, cur + 2) as u128) << 16) |
+            ((*vector::borrow(data, cur + 3) as u128) << 24) |
+            ((*vector::borrow(data, cur + 4) as u128) << 32) |
+            ((*vector::borrow(data, cur + 5) as u128) << 40) |
+            ((*vector::borrow(data, cur + 6) as u128) << 48) |
+            ((*vector::borrow(data, cur + 7) as u128) << 56) |
+            ((*vector::borrow(data, cur + 8) as u128) << 64) |
+            ((*vector::borrow(data, cur + 9) as u128) << 72) |
+            ((*vector::borrow(data, cur + 10) as u128) << 80) |
+            ((*vector::borrow(data, cur + 11) as u128) << 88) |
+            ((*vector::borrow(data, cur + 12) as u128) << 96) |
+            ((*vector::borrow(data, cur + 13) as u128) << 104) |
+            ((*vector::borrow(data, cur + 14) as u128) << 112) |
+            ((*vector::borrow(data, cur + 15) as u128) << 120)
+    ;
+
+    stream.cur = stream.cur + 16;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u256` + +Deserializes a u256 value from the stream. +32-byte u256 values are serialized using little-endian byte order. + + +
public fun deserialize_u256(stream: &mut bcs_stream::BCSStream): u256
+
+ + + +
+Implementation + + +
public fun deserialize_u256(stream: &mut BCSStream): u256 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 32 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u256) |
+            ((*vector::borrow(data, cur + 1) as u256) << 8) |
+            ((*vector::borrow(data, cur + 2) as u256) << 16) |
+            ((*vector::borrow(data, cur + 3) as u256) << 24) |
+            ((*vector::borrow(data, cur + 4) as u256) << 32) |
+            ((*vector::borrow(data, cur + 5) as u256) << 40) |
+            ((*vector::borrow(data, cur + 6) as u256) << 48) |
+            ((*vector::borrow(data, cur + 7) as u256) << 56) |
+            ((*vector::borrow(data, cur + 8) as u256) << 64) |
+            ((*vector::borrow(data, cur + 9) as u256) << 72) |
+            ((*vector::borrow(data, cur + 10) as u256) << 80) |
+            ((*vector::borrow(data, cur + 11) as u256) << 88) |
+            ((*vector::borrow(data, cur + 12) as u256) << 96) |
+            ((*vector::borrow(data, cur + 13) as u256) << 104) |
+            ((*vector::borrow(data, cur + 14) as u256) << 112) |
+            ((*vector::borrow(data, cur + 15) as u256) << 120) |
+            ((*vector::borrow(data, cur + 16) as u256) << 128) |
+            ((*vector::borrow(data, cur + 17) as u256) << 136) |
+            ((*vector::borrow(data, cur + 18) as u256) << 144) |
+            ((*vector::borrow(data, cur + 19) as u256) << 152) |
+            ((*vector::borrow(data, cur + 20) as u256) << 160) |
+            ((*vector::borrow(data, cur + 21) as u256) << 168) |
+            ((*vector::borrow(data, cur + 22) as u256) << 176) |
+            ((*vector::borrow(data, cur + 23) as u256) << 184) |
+            ((*vector::borrow(data, cur + 24) as u256) << 192) |
+            ((*vector::borrow(data, cur + 25) as u256) << 200) |
+            ((*vector::borrow(data, cur + 26) as u256) << 208) |
+            ((*vector::borrow(data, cur + 27) as u256) << 216) |
+            ((*vector::borrow(data, cur + 28) as u256) << 224) |
+            ((*vector::borrow(data, cur + 29) as u256) << 232) |
+            ((*vector::borrow(data, cur + 30) as u256) << 240) |
+            ((*vector::borrow(data, cur + 31) as u256) << 248)
+    ;
+
+    stream.cur = stream.cur + 32;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u256_entry` + +Deserializes a u256 value from the stream. + + +
public entry fun deserialize_u256_entry(data: vector<u8>, cursor: u64)
+
+ + + +
+Implementation + + +
public entry fun deserialize_u256_entry(data: vector<u8>, cursor: u64) {
+    let stream = BCSStream {
+        data: data,
+        cur: cursor,
+    };
+    deserialize_u256(&mut stream);
+}
+
+ + + +
+ + + +## Function `deserialize_vector` + +Deserializes an array of BCS deserializable elements from the stream. +First, reads the length of the vector, which is in uleb128 format. +After determining the length, it then reads the contents of the vector. +The elem_deserializer lambda expression is used sequentially to deserialize each element of the vector. + + +
public fun deserialize_vector<E>(stream: &mut bcs_stream::BCSStream, elem_deserializer: |&mut bcs_stream::BCSStream|E): vector<E>
+
+ + + +
+Implementation + + +
public inline fun deserialize_vector<E>(stream: &mut BCSStream, elem_deserializer: |&mut BCSStream| E): vector<E> {
+    let len = deserialize_uleb128(stream);
+    let v = vector::empty();
+
+    let i = 0;
+    while (i < len) {
+        vector::push_back(&mut v, elem_deserializer(stream));
+        i = i + 1;
+    };
+
+    v
+}
+
+ + + +
+ + + +## Function `deserialize_string` + +Deserializes utf-8 String from the stream. +First, reads the length of the String, which is in uleb128 format. +After determining the length, it then reads the contents of the String. + + +
public fun deserialize_string(stream: &mut bcs_stream::BCSStream): string::String
+
+ + + +
+Implementation + + +
public fun deserialize_string(stream: &mut BCSStream): String {
+    let len = deserialize_uleb128(stream);
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + len <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+
+    let res = string::utf8(vector::slice(data, cur, cur + len));
+    stream.cur = cur + len;
+
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_option` + +Deserializes Option from the stream. +First, reads a single byte representing the presence (0x01) or absence (0x00) of data. +After determining the presence of data, it then reads the actual data if present. +The elem_deserializer lambda expression is used to deserialize the element contained within the Option. + + +
public fun deserialize_option<E>(stream: &mut bcs_stream::BCSStream, elem_deserializer: |&mut bcs_stream::BCSStream|E): option::Option<E>
+
+ + + +
+Implementation + + +
public inline fun deserialize_option<E>(stream: &mut BCSStream, elem_deserializer: |&mut BCSStream| E): Option<E> {
+    let is_data = deserialize_bool(stream);
+    if (is_data) {
+        option::some(elem_deserializer(stream))
+    } else {
+        option::none()
+    }
+}
+
+ + + +
+ + + +## Specification + + + +
pragma verify = false;
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-stdlib/doc/big_ordered_map.md b/aptos-move/framework/aptos-framework/doc/big_ordered_map.md similarity index 79% rename from aptos-move/framework/aptos-stdlib/doc/big_ordered_map.md rename to aptos-move/framework/aptos-framework/doc/big_ordered_map.md index ca0f8f36c4577..2a32bfce29e72 100644 --- a/aptos-move/framework/aptos-stdlib/doc/big_ordered_map.md +++ b/aptos-move/framework/aptos-framework/doc/big_ordered_map.md @@ -53,6 +53,9 @@ allowing cleaner iterator APIs. - [Function `iter_borrow_mut`](#0x1_big_ordered_map_iter_borrow_mut) - [Function `iter_next`](#0x1_big_ordered_map_iter_next) - [Function `iter_prev`](#0x1_big_ordered_map_iter_prev) +- [Function `for_each`](#0x1_big_ordered_map_for_each) +- [Function `for_each_ref`](#0x1_big_ordered_map_for_each_ref) +- [Function `destroy`](#0x1_big_ordered_map_destroy) - [Function `borrow_node`](#0x1_big_ordered_map_borrow_node) - [Function `borrow_node_mut`](#0x1_big_ordered_map_borrow_node_mut) - [Function `add_or_upsert_impl`](#0x1_big_ordered_map_add_or_upsert_impl) @@ -82,14 +85,14 @@ allowing cleaner iterator APIs. - [Function `length_for_node`](#@Specification_1_length_for_node) -
use 0x1::bcs;
-use 0x1::cmp;
-use 0x1::error;
-use 0x1::math64;
-use 0x1::option;
+
use 0x1::bcs;
+use 0x1::cmp;
+use 0x1::error;
+use 0x1::math64;
+use 0x1::option;
 use 0x1::ordered_map;
-use 0x1::storage_slots_allocator;
-use 0x1::vector;
+use 0x1::storage_slots_allocator;
+use 0x1::vector;
 
@@ -171,7 +174,7 @@ Contents of a child node.
-node_index: storage_slots_allocator::StoredSlot +node_index: storage_slots_allocator::StoredSlot
@@ -310,7 +313,7 @@ The BigOrderedMap data structure. Root node. It is stored directly in the resource itself, unlike all other nodes.
-nodes: storage_slots_allocator::StorageSlotsAllocator<big_ordered_map::Node<K, V>> +nodes: storage_slots_allocator::StorageSlotsAllocator<big_ordered_map::Node<K, V>>
Storage of all non-root nodes. They are stored in separate storage slots. @@ -524,8 +527,8 @@ it is required to use new_with_config, to explicitly select automatic or specifi
public fun new<K: store, V: store>(): BigOrderedMap<K, V> {
     assert!(
-        bcs::constant_serialized_size<K>().is_some() && bcs::constant_serialized_size<V>().is_some(),
-        error::invalid_argument(EINVALID_CONFIG_PARAMETER)
+        bcs::constant_serialized_size<K>().is_some() && bcs::constant_serialized_size<V>().is_some(),
+        error::invalid_argument(EINVALID_CONFIG_PARAMETER)
     );
 
     new_with_config(0, 0, false, 0)
@@ -560,15 +563,15 @@ it is important to compute and pass inner_max_degree and leaf_max_degree based o
 
 
 
public fun new_with_config<K: store, V: store>(inner_max_degree: u16, leaf_max_degree: u16, reuse_slots: bool, num_to_preallocate: u32): BigOrderedMap<K, V> {
-    assert!(inner_max_degree == 0 || (inner_max_degree >= DEFAULT_INNER_MIN_DEGREE && (inner_max_degree as u64) <= MAX_DEGREE), error::invalid_argument(EINVALID_CONFIG_PARAMETER));
-    assert!(leaf_max_degree == 0 || (leaf_max_degree >= DEFAULT_LEAF_MIN_DEGREE && (leaf_max_degree as u64) <= MAX_DEGREE), error::invalid_argument(EINVALID_CONFIG_PARAMETER));
-    assert!(reuse_slots || num_to_preallocate == 0, error::invalid_argument(EINVALID_CONFIG_PARAMETER));
+    assert!(inner_max_degree == 0 || (inner_max_degree >= DEFAULT_INNER_MIN_DEGREE && (inner_max_degree as u64) <= MAX_DEGREE), error::invalid_argument(EINVALID_CONFIG_PARAMETER));
+    assert!(leaf_max_degree == 0 || (leaf_max_degree >= DEFAULT_LEAF_MIN_DEGREE && (leaf_max_degree as u64) <= MAX_DEGREE), error::invalid_argument(EINVALID_CONFIG_PARAMETER));
+    assert!(reuse_slots || num_to_preallocate == 0, error::invalid_argument(EINVALID_CONFIG_PARAMETER));
 
-    // Assert that storage_slots_allocator special indices are aligned:
-    assert!(storage_slots_allocator::is_null_index(NULL_INDEX), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
-    assert!(storage_slots_allocator::is_special_unused_index(ROOT_INDEX), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    // Assert that storage_slots_allocator special indices are aligned:
+    assert!(storage_slots_allocator::is_null_index(NULL_INDEX), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(storage_slots_allocator::is_special_unused_index(ROOT_INDEX), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
 
-    let nodes = storage_slots_allocator::new(storage_slots_allocator::new_config(reuse_slots, num_to_preallocate));
+    let nodes = storage_slots_allocator::new(storage_slots_allocator::new_config(reuse_slots, num_to_preallocate));
 
     let self = BigOrderedMap::BPlusTreeMap {
         root: new_node(/*is_leaf=*/true),
@@ -596,7 +599,7 @@ Create a BigOrderedMap from a vector of keys and values, with default configurat
 Aborts with EKEY_ALREADY_EXISTS if duplicate keys are passed in.
 
 
-
public fun new_from<K: copy, drop, store, V: store>(keys: vector<K>, values: vector<V>): big_ordered_map::BigOrderedMap<K, V>
+
public fun new_from<K: copy, drop, store, V: store>(keys: vector<K>, values: vector<V>): big_ordered_map::BigOrderedMap<K, V>
 
@@ -605,7 +608,7 @@ Aborts with EKEY_ALREADY_EXISTS if duplicate keys are passed in. Implementation -
public fun new_from<K: drop + copy + store, V: store>(keys: vector<K>, values: vector<V>): BigOrderedMap<K, V> {
+
public fun new_from<K: drop + copy + store, V: store>(keys: vector<K>, values: vector<V>): BigOrderedMap<K, V> {
     let map = new();
     map.add_all(keys, values);
     map
@@ -637,7 +640,7 @@ Destroys the map if it's empty, otherwise aborts.
     root.destroy_empty_node();
     // If root node is empty, then we know that no storage slots are used,
     // and so we can safely destroy all nodes.
-    nodes.destroy_known_empty_unsafe();
+    nodes.destroy_empty();
 }
 
@@ -679,7 +682,7 @@ If the key doesn't exist in the map, inserts the key/value, and returns none. Otherwise updates the value under the given key, and returns the old value. -
public fun upsert<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key: K, value: V): option::Option<V>
+
public fun upsert<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key: K, value: V): option::Option<V>
 
@@ -694,10 +697,10 @@ Otherwise updates the value under the given key, and returns the old value. let Child::Leaf { value: old_value, } = result.destroy_some(); - option::some(old_value) + option::some(old_value) } else { result.destroy_none(); - option::none() + option::none() } }
@@ -735,7 +738,7 @@ Aborts if there is no entry for key. let path_to_leaf = self.find_leaf_path(key); - assert!(!path_to_leaf.is_empty(), error::invalid_argument(EKEY_NOT_FOUND)); + assert!(!path_to_leaf.is_empty(), error::invalid_argument(EKEY_NOT_FOUND)); let Child::Leaf { value, @@ -756,7 +759,7 @@ Add multiple key/value pairs to the map. The keys must not already exist. Aborts with EKEY_ALREADY_EXISTS if key already exist, or duplicate keys are passed in. -
public fun add_all<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, keys: vector<K>, values: vector<V>)
+
public fun add_all<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, keys: vector<K>, values: vector<V>)
 
@@ -765,10 +768,10 @@ Aborts with EKEY_ALREADY_EXISTS if key already exist, or duplicate keys are pass Implementation -
public fun add_all<K: drop + copy + store, V: store>(self: &mut BigOrderedMap<K, V>, keys: vector<K>, values: vector<V>) {
+
public fun add_all<K: drop + copy + store, V: store>(self: &mut BigOrderedMap<K, V>, keys: vector<K>, values: vector<V>) {
     // TODO: Can be optimized, both in insertion order (largest first, then from smallest),
     // as well as on initializing inner_max_degree/leaf_max_degree better
-    vector::zip(keys, values, |key, value| {
+    vector::zip(keys, values, |key, value| {
         self.add(key, value);
     });
 }
@@ -802,7 +805,7 @@ key, or an end iterator if such element doesn't exist.
     };
 
     let node = self.borrow_node(leaf);
-    assert!(node.is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(node.is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
 
     let child_lower_bound = node.children.lower_bound(key);
     if (child_lower_bound.iter_is_end(&node.children)) {
@@ -901,8 +904,14 @@ Returns a reference to the element with its key, aborts if the key is not found.
 
 
public fun borrow<K: drop + copy + store, V: store>(self: &BigOrderedMap<K, V>, key: &K): &V {
     let iter = self.find(key);
-    assert!(!iter.iter_is_end(self), error::invalid_argument(EKEY_NOT_FOUND));
-    iter.iter_borrow(self)
+    assert!(!iter.iter_is_end(self), error::invalid_argument(EKEY_NOT_FOUND));
+
+    // TODO cannot call iter_borrow, because reference checks assume return has reference to iter that is being destroyed
+    // iter.iter_borrow(self)
+
+    assert!(!iter.iter_is_end(self), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    let children = &self.borrow_node(iter.node_index).children;
+    &iter.child_iter.iter_borrow(children).value
 }
 
@@ -928,7 +937,7 @@ Returns a mutable reference to the element with its key at the given index, abor
public fun borrow_mut<K: drop + copy + store, V: store>(self: &mut BigOrderedMap<K, V>, key: &K): &mut V {
     let iter = self.find(key);
-    assert!(!iter.iter_is_end(self), error::invalid_argument(EKEY_NOT_FOUND));
+    assert!(!iter.iter_is_end(self), error::invalid_argument(EKEY_NOT_FOUND));
     iter.iter_borrow_mut(self)
 }
 
@@ -959,7 +968,7 @@ Returns the begin iterator. }; let node = self.borrow_node(self.min_leaf_index); - assert!(!node.children.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN)); + assert!(!node.children.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN)); let begin_child_iter = node.children.new_begin_iter(); let begin_child_key = *begin_child_iter.iter_borrow_key(&node.children); new_iter(self.min_leaf_index, begin_child_iter, begin_child_key) @@ -1066,7 +1075,7 @@ Note: Requires that the map is not changed after the input iterator is generated
public(friend) fun iter_borrow_key<K>(self: &IteratorPtr<K>): &K {
-    assert!(!(self is IteratorPtr::End<K>), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!(self is IteratorPtr::End<K>), error::invalid_argument(EITER_OUT_OF_BOUNDS));
     &self.key
 }
 
@@ -1084,7 +1093,7 @@ Aborts with EITER_OUT_OF_BOUNDS if iterator is pointing to the end. Note: Requires that the map is not changed after the input iterator is generated. -
public(friend) fun iter_borrow<K: copy, drop, store, V: store>(self: big_ordered_map::IteratorPtr<K>, map: &big_ordered_map::BigOrderedMap<K, V>): &V
+
public(friend) fun iter_borrow<K: store, V: store>(self: &big_ordered_map::IteratorPtr<K>, map: &big_ordered_map::BigOrderedMap<K, V>): &V
 
@@ -1093,8 +1102,8 @@ Note: Requires that the map is not changed after the input iterator is generated Implementation -
public(friend) fun iter_borrow<K: drop + copy + store, V: store>(self: IteratorPtr<K>, map: &BigOrderedMap<K, V>): &V {
-    assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+
public(friend) fun iter_borrow<K: store, V: store>(self: &IteratorPtr<K>, map: &BigOrderedMap<K, V>): &V {
+    assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
     let children = &map.borrow_node(self.node_index).children;
     &self.child_iter.iter_borrow(children).value
 }
@@ -1115,7 +1124,7 @@ because if it doesn't - we need to call upsert to be able to check
 Note: Requires that the map is not changed after the input iterator is generated.
 
 
-
public(friend) fun iter_borrow_mut<K: copy, drop, store, V: store>(self: big_ordered_map::IteratorPtr<K>, map: &mut big_ordered_map::BigOrderedMap<K, V>): &mut V
+
public(friend) fun iter_borrow_mut<K: store, V: store>(self: &big_ordered_map::IteratorPtr<K>, map: &mut big_ordered_map::BigOrderedMap<K, V>): &mut V
 
@@ -1124,9 +1133,9 @@ Note: Requires that the map is not changed after the input iterator is generated Implementation -
public(friend) fun iter_borrow_mut<K: drop + copy + store, V: store>(self: IteratorPtr<K>, map: &mut BigOrderedMap<K, V>): &mut V {
-    assert!(map.constant_kv_size, error::invalid_argument(EBORROW_MUT_REQUIRES_CONSTANT_KV_SIZE));
-    assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+
public(friend) fun iter_borrow_mut<K: store, V: store>(self: &IteratorPtr<K>, map: &mut BigOrderedMap<K, V>): &mut V {
+    assert!(map.constant_kv_size, error::invalid_argument(EBORROW_MUT_REQUIRES_CONSTANT_KV_SIZE));
+    assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
     let children = &mut map.borrow_node_mut(self.node_index).children;
     &mut self.child_iter.iter_borrow_mut(children).value
 }
@@ -1155,7 +1164,7 @@ Requires the map is not changed after the input iterator is generated.
 
 
 
public(friend) fun iter_next<K: drop + copy + store, V: store>(self: IteratorPtr<K>, map: &BigOrderedMap<K, V>): IteratorPtr<K> {
-    assert!(!(self is IteratorPtr::End<K>), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!(self is IteratorPtr::End<K>), error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
     let node_index = self.node_index;
     let node = map.borrow_node(node_index);
@@ -1173,7 +1182,7 @@ Requires the map is not changed after the input iterator is generated.
         let next_node = map.borrow_node(next_index);
 
         let child_iter = next_node.children.new_begin_iter();
-        assert!(!child_iter.iter_is_end(&next_node.children), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+        assert!(!child_iter.iter_is_end(&next_node.children), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
         let iter_key = *child_iter.iter_borrow_key(&next_node.children);
         return new_iter(next_index, child_iter, iter_key);
     };
@@ -1220,7 +1229,7 @@ Requires the map is not changed after the input iterator is generated.
         node.prev
     };
 
-    assert!(prev_index != NULL_INDEX, error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(prev_index != NULL_INDEX, error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
     // next is in a different leaf node
     let prev_node = map.borrow_node(prev_index);
@@ -1234,6 +1243,96 @@ Requires the map is not changed after the input iterator is generated.
 
 
 
+
+
+
+
+## Function `for_each`
+
+Apply the function to each element in the vector, consuming it.
+
+
+
public(friend) fun for_each<K: copy, drop, store, V: store>(self: big_ordered_map::BigOrderedMap<K, V>, f: |(K, V)|)
+
+ + + +
+Implementation + + +
public(friend) inline fun for_each<K: drop + copy + store, V: store>(self: BigOrderedMap<K, V>, f: |K, V|) {
+    // TODO - this can be done more efficiently, by destroying the leaves directly
+    // but that requires more complicated code and testing.
+    let it = self.new_begin_iter();
+    while (!it.iter_is_end(&self)) {
+        let k = *it.iter_borrow_key();
+        let v = self.remove(&k);
+        f(k, v);
+        it = self.new_begin_iter();
+    };
+    destroy_empty(self)
+}
+
+ + + +
+ + + +## Function `for_each_ref` + +Apply the function to a reference of each element in the vector. + + +
public(friend) fun for_each_ref<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>, f: |(&K, &V)|)
+
+ + + +
+Implementation + + +
public(friend) inline fun for_each_ref<K: drop + copy + store, V: store>(self: &BigOrderedMap<K, V>, f: |&K, &V|) {
+    let it = self.new_begin_iter();
+    while (!it.iter_is_end(self)) {
+        f(it.iter_borrow_key(), it.iter_borrow(self));
+        it = it.iter_next(self);
+    };
+}
+
+ + + +
+ + + +## Function `destroy` + +Destroy a map, by destroying elements individually. + + +
public(friend) fun destroy<K: copy, drop, store, V: store>(self: big_ordered_map::BigOrderedMap<K, V>, dv: |V|)
+
+ + + +
+Implementation + + +
public(friend) inline fun destroy<K: drop + copy + store, V: store>(self: BigOrderedMap<K, V>, dv: |V|) {
+    for_each(self, |_k, v| {
+        dv(v);
+    });
+}
+
+ + +
@@ -1300,7 +1399,7 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an -
fun add_or_upsert_impl<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key: K, value: V, allow_overwrite: bool): option::Option<big_ordered_map::Child<V>>
+
fun add_or_upsert_impl<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, key: K, value: V, allow_overwrite: bool): option::Option<big_ordered_map::Child<V>>
 
@@ -1322,7 +1421,7 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an if (degree < (self.leaf_max_degree as u64)) { let result = children.upsert(key, new_leaf_child(value)); - assert!(allow_overwrite || result.is_none(), error::invalid_argument(EKEY_ALREADY_EXISTS)); + assert!(allow_overwrite || result.is_none(), error::invalid_argument(EKEY_ALREADY_EXISTS)); return result; }; }; @@ -1373,8 +1472,8 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an
fun validate_dynamic_size_and_init_max_degrees<K: store, V: store>(self: &mut BigOrderedMap<K, V>, key: &K, value: &V) {
-    let key_size = bcs::serialized_size(key);
-    let value_size = bcs::serialized_size(value);
+    let key_size = bcs::serialized_size(key);
+    let value_size = bcs::serialized_size(value);
     self.validate_size_and_init_max_degrees(key_size, value_size)
 }
 
@@ -1399,8 +1498,8 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an
fun validate_static_size_and_init_max_degrees<K: store, V: store>(self: &mut BigOrderedMap<K, V>) {
-    let key_size = bcs::constant_serialized_size<K>();
-    let value_size = bcs::constant_serialized_size<V>();
+    let key_size = bcs::constant_serialized_size<K>();
+    let value_size = bcs::constant_serialized_size<V>();
 
     if (key_size.is_some() && value_size.is_some()) {
         self.validate_size_and_init_max_degrees(key_size.destroy_some(), value_size.destroy_some());
@@ -1440,8 +1539,8 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an
     };
 
     // Make sure that no nodes can exceed the upper size limit.
-    assert!(key_size * (self.inner_max_degree as u64) <= MAX_NODE_BYTES, error::invalid_argument(EARGUMENT_BYTES_TOO_LARGE));
-    assert!(entry_size * (self.leaf_max_degree as u64) <= MAX_NODE_BYTES, error::invalid_argument(EARGUMENT_BYTES_TOO_LARGE));
+    assert!(key_size * (self.inner_max_degree as u64) <= MAX_NODE_BYTES, error::invalid_argument(EARGUMENT_BYTES_TOO_LARGE));
+    assert!(entry_size * (self.leaf_max_degree as u64) <= MAX_NODE_BYTES, error::invalid_argument(EARGUMENT_BYTES_TOO_LARGE));
 }
 
@@ -1455,7 +1554,7 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an -
fun destroy_inner_child<V: store>(self: big_ordered_map::Child<V>): storage_slots_allocator::StoredSlot
+
fun destroy_inner_child<V: store>(self: big_ordered_map::Child<V>): storage_slots_allocator::StoredSlot
 
@@ -1494,7 +1593,7 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an
fun destroy_empty_node<K: store, V: store>(self: Node<K, V>) {
     let Node { children, is_leaf: _, prev: _, next: _ } = self;
-    assert!(children.is_empty(), error::invalid_argument(EMAP_NOT_EMPTY));
+    assert!(children.is_empty(), error::invalid_argument(EMAP_NOT_EMPTY));
     children.destroy_empty();
 }
 
@@ -1567,7 +1666,7 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an -
fun new_inner_child<V: store>(node_index: storage_slots_allocator::StoredSlot): big_ordered_map::Child<V>
+
fun new_inner_child<V: store>(node_index: storage_slots_allocator::StoredSlot): big_ordered_map::Child<V>
 
@@ -1691,7 +1790,7 @@ Returns the path from root to that leaf (including the leaf itself) Returns empty path if key is larger than any key currently stored in the map. -
fun find_leaf_path<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>, key: &K): vector<u64>
+
fun find_leaf_path<K: copy, drop, store, V: store>(self: &big_ordered_map::BigOrderedMap<K, V>, key: &K): vector<u64>
 
@@ -1700,8 +1799,8 @@ Returns empty path if key is larger than any key currently stored i Implementation -
fun find_leaf_path<K: drop + copy + store, V: store>(self: &BigOrderedMap<K, V>, key: &K): vector<u64> {
-    let vec = vector::empty();
+
fun find_leaf_path<K: drop + copy + store, V: store>(self: &BigOrderedMap<K, V>, key: &K): vector<u64> {
+    let vec = vector::empty();
 
     let current = ROOT_INDEX;
     loop {
@@ -1714,7 +1813,7 @@ Returns empty path if key is larger than any key currently stored i
         let children = &node.children;
         let child_iter = children.lower_bound(key);
         if (child_iter.iter_is_end(children)) {
-            return vector::empty();
+            return vector::empty();
         } else {
             current = child_iter.iter_borrow(children).node_index.stored_to_index();
         };
@@ -1770,18 +1869,18 @@ Returns empty path if key is larger than any key currently stored i
 
 
 
fun replace_root<K: store, V: store>(self: &mut BigOrderedMap<K, V>, new_root: Node<K, V>): Node<K, V> {
-    // TODO: once mem::replace is made public/released, update to:
-    // mem::replace(&mut self.root, new_root_node)
+    // TODO: once mem::replace is made public/released, update to:
+    // mem::replace(&mut self.root, new_root_node)
 
     let root = &mut self.root;
     let tmp_is_leaf = root.is_leaf;
     root.is_leaf = new_root.is_leaf;
     new_root.is_leaf = tmp_is_leaf;
 
-    assert!(root.prev == NULL_INDEX, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
-    assert!(root.next == NULL_INDEX, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
-    assert!(new_root.prev == NULL_INDEX, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
-    assert!(new_root.next == NULL_INDEX, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(root.prev == NULL_INDEX, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(root.next == NULL_INDEX, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(new_root.prev == NULL_INDEX, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(new_root.next == NULL_INDEX, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
 
     // let tmp_prev = root.prev;
     // root.prev = new_root.prev;
@@ -1816,7 +1915,7 @@ Returns Child previously associated with the given key.
 If allow_overwrite is not set, function will abort if key is already present.
 
 
-
fun add_at<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, key: K, child: big_ordered_map::Child<V>, allow_overwrite: bool): option::Option<big_ordered_map::Child<V>>
+
fun add_at<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, key: K, child: big_ordered_map::Child<V>, allow_overwrite: bool): option::Option<big_ordered_map::Child<V>>
 
@@ -1825,11 +1924,11 @@ If allow_overwrite is not set, function will abort if keyImplementation -
fun add_at<K: drop + copy + store, V: store>(self: &mut BigOrderedMap<K, V>, path_to_node: vector<u64>, key: K, child: Child<V>, allow_overwrite: bool): Option<Child<V>> {
+
fun add_at<K: drop + copy + store, V: store>(self: &mut BigOrderedMap<K, V>, path_to_node: vector<u64>, key: K, child: Child<V>, allow_overwrite: bool): Option<Child<V>> {
     // Last node in the path is one where we need to add the child to.
     let node_index = path_to_node.pop_back();
     {
-        // First check if we can perform this operation, without changing structure of the tree (i.e. without adding any nodes).
+        // First check if we can perform this operation, without changing structure of the tree (i.e. without adding any nodes).
 
         // For that we can just borrow the single node
         let node = self.borrow_node_mut(node_index);
@@ -1848,10 +1947,10 @@ If allow_overwrite is not set, function will abort if keylet old_child = children.upsert(key, child);
 
             if (node.is_leaf) {
-                assert!(allow_overwrite || old_child.is_none(), error::invalid_argument(EKEY_ALREADY_EXISTS));
+                assert!(allow_overwrite || old_child.is_none(), error::invalid_argument(EKEY_ALREADY_EXISTS));
                 return old_child;
             } else {
-                assert!(!allow_overwrite && old_child.is_none(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+                assert!(!allow_overwrite && old_child.is_none(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
                 return old_child;
             };
         };
@@ -1860,10 +1959,10 @@ If allow_overwrite is not set, function will abort if keywith `key` already exists, we either need to replace or abort.
         let iter = children.find(&key);
         if (!iter.iter_is_end(children)) {
-            assert!(node.is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
-            assert!(allow_overwrite, error::invalid_argument(EKEY_ALREADY_EXISTS));
+            assert!(node.is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+            assert!(allow_overwrite, error::invalid_argument(EKEY_ALREADY_EXISTS));
 
-            return option::some(iter.iter_replace(children, child));
+            return option::some(iter.iter_replace(children, child));
         }
     };
 
@@ -1872,7 +1971,7 @@ If allow_overwrite is not set, function will abort if keyto move root node to become a child and have a new root node,
     // in order to be able to split the node on the level it is.
     let (reserved_slot, node) = if (node_index == ROOT_INDEX) {
-        assert!(path_to_node.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+        assert!(path_to_node.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
 
         // Splitting root now, need to create a new root.
         // Since root is stored direclty in the resource, we will swap-in the new node there.
@@ -1886,7 +1985,7 @@ If allow_overwrite is not set, function will abort if keylet max_key = *root_children.new_end_iter().iter_prev(root_children).iter_borrow_key(root_children);
             // need to check if key is largest, as invariant is that "parent's pointers" have been updated,
             // but key itself can be larger than all previous ones.
-            if (cmp::compare(&max_key, &key).is_lt()) {
+            if (cmp::compare(&max_key, &key).is_lt()) {
                 max_key = key;
             };
             max_key
@@ -1917,7 +2016,7 @@ If allow_overwrite is not set, function will abort if keymove node_index;
 
     // Now we can perform the split at the current level, as we know we are not at the root level.
-    assert!(!path_to_node.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(!path_to_node.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
 
     // Parent has a reference under max key to the current node, so existing index
     // needs to be the right node.
@@ -1951,8 +2050,8 @@ If allow_overwrite is not set, function will abort if keyadd(key, child);
     let right_node_children = left_children.trim(target_size);
 
-    assert!(left_children.length() <= max_degree, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
-    assert!(right_node_children.length() <= max_degree, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(left_children.length() <= max_degree, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(right_node_children.length() <= max_degree, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
 
     let right_node = new_node_with_children(is_leaf, right_node_children);
 
@@ -1969,10 +2068,10 @@ If allow_overwrite is not set, function will abort if keyto update next pointer of the previous node (if exists)
     if (*left_prev != NULL_INDEX) {
         self.nodes.borrow_mut(*left_prev).next = left_node_index;
-        assert!(right_node_index != self.min_leaf_index, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+        assert!(right_node_index != self.min_leaf_index, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
     } else if (right_node_index == self.min_leaf_index) {
         // Otherwise, if we were the smallest node on the level. if this is the leaf level, update the pointer.
-        assert!(is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+        assert!(is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
         self.min_leaf_index = left_node_index;
     };
 
@@ -1984,7 +2083,7 @@ If allow_overwrite is not set, function will abort if keyChild (i.e. pointer to the left node) in the parent.
     self.add_at(path_to_node, max_left_key, new_inner_child(left_node_slot), false).destroy_none();
-    option::none()
+    option::none()
 }
 
@@ -1999,7 +2098,7 @@ If allow_overwrite is not set, function will abort if keyfun update_key<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, old_key: &K, new_key: K) +
fun update_key<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, old_key: &K, new_key: K)
 
@@ -2008,7 +2107,7 @@ Given a path to node (excluding the node itself), which is currently stored unde Implementation -
fun update_key<K: drop + copy + store, V: store>(self: &mut BigOrderedMap<K, V>, path_to_node: vector<u64>, old_key: &K, new_key: K) {
+
fun update_key<K: drop + copy + store, V: store>(self: &mut BigOrderedMap<K, V>, path_to_node: vector<u64>, old_key: &K, new_key: K) {
     while (!path_to_node.is_empty()) {
         let node_index = path_to_node.pop_back();
         let node = self.borrow_node_mut(node_index);
@@ -2033,7 +2132,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
 
 
 
-
fun remove_at<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, key: &K): big_ordered_map::Child<V>
+
fun remove_at<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, key: &K): big_ordered_map::Child<V>
 
@@ -2042,11 +2141,11 @@ Given a path to node (excluding the node itself), which is currently stored unde Implementation -
fun remove_at<K: drop + copy + store, V: store>(self: &mut BigOrderedMap<K, V>, path_to_node: vector<u64>, key: &K): Child<V> {
+
fun remove_at<K: drop + copy + store, V: store>(self: &mut BigOrderedMap<K, V>, path_to_node: vector<u64>, key: &K): Child<V> {
     // Last node in the path is one where we need to remove the child from.
     let node_index = path_to_node.pop_back();
     let old_child = {
-        // First check if we can perform this operation, without changing structure of the tree (i.e. without rebalancing any nodes).
+        // First check if we can perform this operation, without changing structure of the tree (i.e. without rebalancing any nodes).
 
         // For that we can just borrow the single node
         let node = self.borrow_node_mut(node_index);
@@ -2059,7 +2158,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
             // If current node is root, lower limit of max_degree/2 nodes doesn't apply.
             // So we can adjust internally
 
-            assert!(path_to_node.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+            assert!(path_to_node.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
 
             if (!is_leaf && children.length() == 1) {
                 // If root is not leaf, but has a single child, promote only child to root,
@@ -2095,9 +2194,9 @@ Given a path to node (excluding the node itself), which is currently stored unde
         let new_max_key = *children.new_end_iter().iter_prev(children).iter_borrow_key(children);
 
         // See if max key was updated for the current node, and if so - update it on the path.
-        let max_key_updated = cmp::compare(&new_max_key, key).is_lt();
+        let max_key_updated = cmp::compare(&new_max_key, key).is_lt();
         if (max_key_updated) {
-            assert!(degree >= 1, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+            assert!(degree >= 1, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
 
             self.update_key(path_to_node, key, new_max_key);
         };
@@ -2124,9 +2223,9 @@ Given a path to node (excluding the node itself), which is currently stored unde
     // index of the node we will rebalance with.
     let sibling_index = {
         let parent_children = &self.borrow_node(*path_to_node.borrow(path_to_node.length() - 1)).children;
-        assert!(parent_children.length() >= 2, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+        assert!(parent_children.length() >= 2, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
         // If we are the largest node from the parent, we merge with the `prev`
-        // (which is then guaranteed to have the same parent, as any node has >1 children),
+        // (which is then guaranteed to have the same parent, as any node has >1 children),
         // otherwise we merge with `next`.
         if (parent_children.new_end_iter().iter_prev(parent_children).iter_borrow(parent_children).node_index.stored_to_index() == node_index) {
             prev
@@ -2138,7 +2237,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
     let children = &mut node.children;
 
     let (sibling_slot, sibling_node) = self.nodes.remove_and_reserve(sibling_index);
-    assert!(is_leaf == sibling_node.is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(is_leaf == sibling_node.is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
     let sibling_children = &mut sibling_node.children;
 
     if ((sibling_children.length() - 1) * 2 >= max_degree) {
@@ -2182,7 +2281,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
         node.next = sibling_next;
 
         if (node.next != NULL_INDEX) {
-            assert!(self.nodes.borrow_mut(node.next).prev == sibling_index, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+            assert!(self.nodes.borrow_mut(node.next).prev == sibling_index, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
         };
 
         // we are removing node_index, which previous's node's next was pointing to,
@@ -2192,7 +2291,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
         };
         // Otherwise, we were the smallest node on the level. if this is the leaf level, update the pointer.
         if (self.min_leaf_index == node_index) {
-            assert!(is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+            assert!(is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
             self.min_leaf_index = sibling_index;
         };
 
@@ -2207,7 +2306,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
         sibling_node.next = node_next;
 
         if (sibling_node.next != NULL_INDEX) {
-            assert!(self.nodes.borrow_mut(sibling_node.next).prev == node_index, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+            assert!(self.nodes.borrow_mut(sibling_node.next).prev == node_index, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
         };
         // we are removing sibling node_index, which previous's node's next was pointing to,
         // so update the pointer
@@ -2216,7 +2315,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
         };
         // Otherwise, sibling was the smallest node on the level. if this is the leaf level, update the pointer.
         if (self.min_leaf_index == sibling_index) {
-            assert!(is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+            assert!(is_leaf, error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
             self.min_leaf_index = node_index;
         };
 
@@ -2225,7 +2324,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
         (key_to_remove, sibling_slot)
     };
 
-    assert!(!path_to_node.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
+    assert!(!path_to_node.is_empty(), error::invalid_state(EINTERNAL_INVARIANT_BROKEN));
     let slot_to_remove = destroy_inner_child(self.remove_at(path_to_node, &key_to_remove));
     self.nodes.free_reserved_slot(reserved_slot_to_remove, slot_to_remove);
 
@@ -2284,7 +2383,7 @@ Returns the number of elements in the BigOrderedMap.
     } else {
         let size = 0;
 
-        node.children.for_each_ref(|_key, child| {
+        node.children.for_each_ref(|_key, child| {
             size = size + self.length_for_node(child.node_index.stored_to_index());
         });
         size
@@ -2339,7 +2438,7 @@ Returns true iff the BigOrderedMap is empty.
 ### Function `add_at`
 
 
-
fun add_at<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, key: K, child: big_ordered_map::Child<V>, allow_overwrite: bool): option::Option<big_ordered_map::Child<V>>
+
fun add_at<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, key: K, child: big_ordered_map::Child<V>, allow_overwrite: bool): option::Option<big_ordered_map::Child<V>>
 
@@ -2355,7 +2454,7 @@ Returns true iff the BigOrderedMap is empty. ### Function `remove_at` -
fun remove_at<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, key: &K): big_ordered_map::Child<V>
+
fun remove_at<K: copy, drop, store, V: store>(self: &mut big_ordered_map::BigOrderedMap<K, V>, path_to_node: vector<u64>, key: &K): big_ordered_map::Child<V>
 
diff --git a/aptos-move/framework/aptos-framework/doc/code.md b/aptos-move/framework/aptos-framework/doc/code.md index ce18af9e16fbc..fe773e27c0f99 100644 --- a/aptos-move/framework/aptos-framework/doc/code.md +++ b/aptos-move/framework/aptos-framework/doc/code.md @@ -12,8 +12,11 @@ This module supports functionality related to code management. - [Struct `ModuleMetadata`](#0x1_code_ModuleMetadata) - [Struct `UpgradePolicy`](#0x1_code_UpgradePolicy) - [Struct `PublishPackage`](#0x1_code_PublishPackage) +- [Struct `CodePublishingPermission`](#0x1_code_CodePublishingPermission) - [Struct `AllowedDep`](#0x1_code_AllowedDep) - [Constants](#@Constants_0) +- [Function `check_code_publishing_permission`](#0x1_code_check_code_publishing_permission) +- [Function `grant_permission`](#0x1_code_grant_permission) - [Function `upgrade_policy_arbitrary`](#0x1_code_upgrade_policy_arbitrary) - [Function `upgrade_policy_compat`](#0x1_code_upgrade_policy_compat) - [Function `upgrade_policy_immutable`](#0x1_code_upgrade_policy_immutable) @@ -50,6 +53,7 @@ This module supports functionality related to code management. use 0x1::features; use 0x1::object; use 0x1::option; +use 0x1::permissioned_signer; use 0x1::signer; use 0x1::string; use 0x1::system_addresses; @@ -300,6 +304,33 @@ Event emitted when code is published to an address.
+ + + + +## Struct `CodePublishingPermission` + + + +
struct CodePublishingPermission has copy, drop, store
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ +
@@ -413,6 +444,16 @@ Not the owner of the package registry. + + +Current permissioned signer cannot publish codes. + + +
const ENO_CODE_PERMISSION: u64 = 11;
+
+ + + Dependency could not be resolved to any published package. @@ -443,6 +484,59 @@ Cannot downgrade a package's upgradability policy + + +## Function `check_code_publishing_permission` + +Permissions + + +
public(friend) fun check_code_publishing_permission(s: &signer)
+
+ + + +
+Implementation + + +
public(friend) fun check_code_publishing_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, CodePublishingPermission {}),
+        error::permission_denied(ENO_CODE_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_permission` + +Grant permission to publish code on behalf of the master signer. + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, CodePublishingPermission {})
+}
+
+ + + +
+ ## Function `upgrade_policy_arbitrary` @@ -598,6 +692,7 @@ package.
public fun publish_package(owner: &signer, pack: PackageMetadata, code: vector<vector<u8>>) acquires PackageRegistry {
+    check_code_publishing_permission(owner);
     // Disallow incompatible upgrade mode. Governance can decide later if this should be reconsidered.
     assert!(
         pack.upgrade_policy.policy > upgrade_policy_arbitrary().policy,
@@ -679,6 +774,7 @@ package.
 
 
 
public fun freeze_code_object(publisher: &signer, code_object: Object<PackageRegistry>) acquires PackageRegistry {
+    check_code_publishing_permission(publisher);
     let code_object_addr = object::object_address(&code_object);
     assert!(exists<PackageRegistry>(code_object_addr), error::not_found(ECODE_OBJECT_DOES_NOT_EXIST));
     assert!(
@@ -1073,7 +1169,7 @@ Native function to initiate module loading, including a list of allowed dependen
 
 
 
pragma verify = true;
-pragma aborts_if_is_strict;
+pragma aborts_if_is_partial;
 
@@ -1253,4 +1349,17 @@ Native function to initiate module loading, including a list of allowed dependen
+ + + + + +
schema AbortsIfPermissionedSigner {
+    s: signer;
+    let perm = CodePublishingPermission {};
+    aborts_if !permissioned_signer::spec_check_permission_exists(s, perm);
+}
+
+ + [move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/coin.md b/aptos-move/framework/aptos-framework/doc/coin.md index bbd15e38568ae..5ff8a32e7e2b0 100644 --- a/aptos-move/framework/aptos-framework/doc/coin.md +++ b/aptos-move/framework/aptos-framework/doc/coin.md @@ -18,6 +18,7 @@ This module provides the foundation for typesafe Coins. - [Struct `DepositEvent`](#0x1_coin_DepositEvent) - [Struct `WithdrawEvent`](#0x1_coin_WithdrawEvent) - [Struct `CoinEventHandleDeletion`](#0x1_coin_CoinEventHandleDeletion) +- [Struct `CoinStoreDeletion`](#0x1_coin_CoinStoreDeletion) - [Struct `PairCreation`](#0x1_coin_PairCreation) - [Struct `MintCapability`](#0x1_coin_MintCapability) - [Struct `FreezeCapability`](#0x1_coin_FreezeCapability) @@ -56,6 +57,7 @@ This module provides the foundation for typesafe Coins. - [Function `allow_supply_upgrades`](#0x1_coin_allow_supply_upgrades) - [Function `calculate_amount_to_withdraw`](#0x1_coin_calculate_amount_to_withdraw) - [Function `maybe_convert_to_fungible_store`](#0x1_coin_maybe_convert_to_fungible_store) +- [Function `assert_signer_has_permission`](#0x1_coin_assert_signer_has_permission) - [Function `migrate_to_fungible_store`](#0x1_coin_migrate_to_fungible_store) - [Function `migrate_coin_store_to_fungible_store`](#0x1_coin_migrate_coin_store_to_fungible_store) - [Function `coin_address`](#0x1_coin_coin_address) @@ -73,6 +75,7 @@ This module provides the foundation for typesafe Coins. - [Function `burn`](#0x1_coin_burn) - [Function `burn_from`](#0x1_coin_burn_from) - [Function `deposit`](#0x1_coin_deposit) +- [Function `deposit_with_signer`](#0x1_coin_deposit_with_signer) - [Function `can_receive_paired_fungible_asset`](#0x1_coin_can_receive_paired_fungible_asset) - [Function `force_deposit`](#0x1_coin_force_deposit) - [Function `destroy_zero`](#0x1_coin_destroy_zero) @@ -146,6 +149,7 @@ This module provides the foundation for typesafe Coins. use 0x1::object; use 0x1::option; use 0x1::optional_aggregator; +use 0x1::permissioned_signer; use 0x1::primary_fungible_store; use 0x1::signer; use 0x1::string; @@ -555,8 +559,11 @@ Event emitted when some amount of a coin is withdrawn from an account. Module event emitted when the event handles related to coin store is deleted. +Deprecated: replaced with CoinStoreDeletion +
#[event]
+#[deprecated]
 struct CoinEventHandleDeletion has drop, store
 
@@ -588,6 +595,53 @@ Module event emitted when the event handles related to coin store is deleted. + + + + +## Struct `CoinStoreDeletion` + +Module event emitted when the event handles related to coin store is deleted. + + +
#[event]
+struct CoinStoreDeletion has drop, store
+
+ + + +
+Fields + + +
+
+coin_type: string::String +
+
+ +
+
+event_handle_creation_address: address +
+
+ +
+
+deleted_deposit_event_handle_creation_number: u64 +
+
+ +
+
+deleted_withdraw_event_handle_creation_number: u64 +
+
+ +
+
+ +
@@ -899,7 +953,6 @@ The flag the existence of which indicates the primary fungible store is created
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
-#[deprecated]
 struct MigrationFlag has key
 
@@ -2041,12 +2094,14 @@ or disallow upgradability of total supply. let metadata = ensure_paired_metadata<CoinType>(); let store = primary_fungible_store::ensure_primary_store_exists(account, metadata); + let store_address = object::object_address(&store); if (exists<CoinStore<CoinType>>(account)) { let CoinStore<CoinType> { coin, frozen, deposit_events, withdraw_events } = move_from<CoinStore<CoinType>>( account ); event::emit( - CoinEventHandleDeletion { + CoinStoreDeletion { + coin_type: type_info::type_name<CoinType>(), event_handle_creation_address: guid::creator_address( event::guid(&deposit_events) ), @@ -2070,6 +2125,42 @@ or disallow upgradability of total supply. fungible_asset::set_frozen_flag_internal(store, frozen); } }; + if (!exists<MigrationFlag>(store_address)) { + move_to(&create_signer::create_signer(store_address), MigrationFlag {}); + } +} +
+ + + + + + + +## Function `assert_signer_has_permission` + + + +
fun assert_signer_has_permission<CoinType>(account: &signer)
+
+ + + +
+Implementation + + +
inline fun assert_signer_has_permission<CoinType>(account: &signer) {
+    if(permissioned_signer::is_permissioned_signer(account)) {
+        fungible_asset::withdraw_permission_check_by_address(
+            account,
+            primary_fungible_store::primary_store_address(
+                signer::address_of(account),
+                ensure_paired_metadata<CoinType>()
+            ),
+            0
+        );
+    }
 }
 
@@ -2096,7 +2187,9 @@ Voluntarily migrate to fungible store for CoinType if not yet.
public entry fun migrate_to_fungible_store<CoinType>(
     account: &signer
 ) acquires CoinStore, CoinConversionMap, CoinInfo {
-    maybe_convert_to_fungible_store<CoinType>(signer::address_of(account));
+    let account_addr = signer::address_of(account);
+    assert_signer_has_permission<CoinType>(account);
+    maybe_convert_to_fungible_store<CoinType>(account_addr);
 }
 
@@ -2634,6 +2727,43 @@ Deposit the coin balance into the recipient's account and emit an event. +
+ + + +## Function `deposit_with_signer` + + + +
public fun deposit_with_signer<CoinType>(account: &signer, coin: coin::Coin<CoinType>)
+
+ + + +
+Implementation + + +
public fun deposit_with_signer<CoinType>(
+    account: &signer,
+    coin: Coin<CoinType>
+) acquires CoinStore, CoinConversionMap, CoinInfo {
+    let metadata = ensure_paired_metadata<CoinType>();
+    let account_address = signer::address_of(account);
+    fungible_asset::refill_permission(
+        account,
+        coin.value,
+        primary_fungible_store::primary_store_address_inlined(
+            account_address,
+            metadata,
+        )
+    );
+    deposit(account_address, coin);
+}
+
+ + +
@@ -2655,13 +2785,11 @@ Deposit the coin balance into the recipient's account and emit an event. account_address: address, metadata: Object<Metadata> ): bool { - (features::new_accounts_default_to_fa_apt_store_enabled() && object::object_address(&metadata) == @0xa) || { - let primary_store_address = primary_fungible_store::primary_store_address<Metadata>( - account_address, - metadata - ); - fungible_asset::store_exists(primary_store_address) - } + let primary_store_address = primary_fungible_store::primary_store_address<Metadata>(account_address, metadata); + fungible_asset::store_exists(primary_store_address) && ( + // migration flag is needed, until we start defaulting new accounts to APT PFS + features::new_accounts_default_to_fa_apt_store_enabled() || exists<MigrationFlag>(primary_store_address) + ) }
@@ -2701,7 +2829,7 @@ This is for internal use only and doesn't emit an DepositEvent. )) { let fa = coin_to_fungible_asset(coin); let metadata = fungible_asset::asset_metadata(&fa); - let store = primary_fungible_store::ensure_primary_store_exists(account_addr, metadata); + let store = primary_fungible_store::primary_store(account_addr, metadata); fungible_asset::unchecked_deposit_with_no_events(object::object_address(&store), fa); } else { abort error::not_found(ECOIN_STORE_NOT_PUBLISHED) @@ -2921,7 +3049,7 @@ The given signer also becomes the account hosting the information about the coi symbol: string::String, decimals: u8, monitor_supply: bool, -): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) { +): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) acquires CoinInfo, CoinConversionMap { initialize_internal(account, name, symbol, decimals, monitor_supply, false) }
@@ -2952,7 +3080,7 @@ Same as initialize but supply can be initialized to parallelizable symbol: string::String, decimals: u8, monitor_supply: bool, -): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) { +): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) acquires CoinInfo, CoinConversionMap { system_addresses::assert_aptos_framework(account); initialize_internal(account, name, symbol, decimals, monitor_supply, true) } @@ -2984,8 +3112,9 @@ Same as initialize but supply can be initialized to parallelizable decimals: u8, monitor_supply: bool, parallelizable: bool, -): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) { +): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) acquires CoinInfo, CoinConversionMap { let account_addr = signer::address_of(account); + assert_signer_has_permission<CoinType>(account); assert!( coin_address<CoinType>() == account_addr, @@ -3101,8 +3230,9 @@ Returns minted Coin. Implementation -
public fun register<CoinType>(account: &signer) acquires CoinConversionMap {
+
public fun register<CoinType>(account: &signer) acquires CoinInfo, CoinConversionMap {
     let account_addr = signer::address_of(account);
+    assert_signer_has_permission<CoinType>(account);
     // Short-circuit and do nothing if account is already registered for CoinType.
     if (is_account_registered<CoinType>(account_addr)) {
         return
@@ -3205,6 +3335,17 @@ Withdraw specified amount of coin CoinType from the si
         amount
     );
     let withdrawn_coin = if (coin_amount_to_withdraw > 0) {
+        let metadata = ensure_paired_metadata<CoinType>();
+        if(permissioned_signer::is_permissioned_signer(account)) {
+            // Perform the check only if the account is a permissioned signer to save the cost of
+            // computing the primary store location.
+            fungible_asset::withdraw_permission_check_by_address(
+                account,
+                primary_fungible_store::primary_store_address(account_addr, metadata),
+                coin_amount_to_withdraw
+            );
+        };
+
         let coin_store = borrow_global_mut<CoinStore<CoinType>>(account_addr);
         assert!(
             !coin_store.frozen,
@@ -3529,6 +3670,7 @@ Destroy a burn capability.
 
 
 
pragma verify = true;
+pragma aborts_if_is_partial;
 
 global supply<CoinType>: num;
 
@@ -4228,6 +4370,27 @@ The creator of CoinType must be @aptos_framework.
 
+Make sure name and symbol are legal length. +Only the creator of CoinType can initialize. + + + + + +
schema InitializeInternalSchema<CoinType> {
+    account: signer;
+    name: vector<u8>;
+    symbol: vector<u8>;
+    let account_addr = signer::address_of(account);
+    let coin_address = type_info::type_of<CoinType>().account_address;
+    aborts_if coin_address != account_addr;
+    aborts_if exists<CoinInfo<CoinType>>(account_addr);
+    aborts_if len(name) > MAX_COIN_NAME_LENGTH;
+    aborts_if len(symbol) > MAX_COIN_SYMBOL_LENGTH;
+}
+
+ + diff --git a/aptos-move/framework/aptos-framework/doc/create_signer.md b/aptos-move/framework/aptos-framework/doc/create_signer.md index a66df38b9c601..5c15eb6bec51f 100644 --- a/aptos-move/framework/aptos-framework/doc/create_signer.md +++ b/aptos-move/framework/aptos-framework/doc/create_signer.md @@ -127,6 +127,16 @@ Convert address to singer and return.
pragma opaque;
 aborts_if [abstract] false;
 ensures [abstract] signer::address_of(result) == addr;
+ensures [abstract] result == spec_create_signer(addr);
+
+ + + + + + + +
fun spec_create_signer(addr: address): signer;
 
diff --git a/aptos-move/framework/aptos-framework/doc/delegation_pool.md b/aptos-move/framework/aptos-framework/doc/delegation_pool.md index c17ab31779be0..99ed5b67a0d25 100644 --- a/aptos-move/framework/aptos-framework/doc/delegation_pool.md +++ b/aptos-move/framework/aptos-framework/doc/delegation_pool.md @@ -124,6 +124,7 @@ transferred to A - [Resource `BeneficiaryForOperator`](#0x1_delegation_pool_BeneficiaryForOperator) - [Resource `NextCommissionPercentage`](#0x1_delegation_pool_NextCommissionPercentage) - [Resource `DelegationPoolAllowlisting`](#0x1_delegation_pool_DelegationPoolAllowlisting) +- [Enum `DelegationPermission`](#0x1_delegation_pool_DelegationPermission) - [Struct `AddStake`](#0x1_delegation_pool_AddStake) - [Struct `AddStakeEvent`](#0x1_delegation_pool_AddStakeEvent) - [Struct `ReactivateStake`](#0x1_delegation_pool_ReactivateStake) @@ -171,6 +172,10 @@ transferred to A - [Function `allowlisting_enabled`](#0x1_delegation_pool_allowlisting_enabled) - [Function `delegator_allowlisted`](#0x1_delegation_pool_delegator_allowlisted) - [Function `get_delegators_allowlist`](#0x1_delegation_pool_get_delegators_allowlist) +- [Function `check_delegation_pool_management_permission`](#0x1_delegation_pool_check_delegation_pool_management_permission) +- [Function `grant_delegation_pool_management_permission`](#0x1_delegation_pool_grant_delegation_pool_management_permission) +- [Function `check_stake_management_permission`](#0x1_delegation_pool_check_stake_management_permission) +- [Function `grant_stake_management_permission`](#0x1_delegation_pool_grant_stake_management_permission) - [Function `initialize_delegation_pool`](#0x1_delegation_pool_initialize_delegation_pool) - [Function `beneficiary_for_operator`](#0x1_delegation_pool_beneficiary_for_operator) - [Function `enable_partial_governance_voting`](#0x1_delegation_pool_enable_partial_governance_voting) @@ -245,6 +250,7 @@ transferred to A use 0x1::error; use 0x1::event; use 0x1::features; +use 0x1::permissioned_signer; use 0x1::pool_u64_unbound; use 0x1::signer; use 0x1::smart_table; @@ -678,6 +684,55 @@ evicted later by the pool owner. + + + + +## Enum `DelegationPermission` + + + +
enum DelegationPermission has copy, drop, store
+
+ + + +
+Variants + + +
+DelegationPoolManagementPermission + + +
+Fields + + +
+
+ + +
+ +
+ +
+StakeManagementPermission + + +
+Fields + + +
+
+ + +
+ +
+
@@ -1828,6 +1883,16 @@ There is not enough active stake on the stake pool to unlock< + + +Signer does not have permission to perform delegation logic. + + +
const ENO_DELEGATION_PERMISSION: u64 = 28;
+
+ + + Changing beneficiaries for operators is not supported. @@ -2756,6 +2821,109 @@ Return allowlist or revert if allowlisting is not enabled for the provided deleg + + + + +## Function `check_delegation_pool_management_permission` + +Permissions + + +
fun check_delegation_pool_management_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_delegation_pool_management_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, DelegationPermission::DelegationPoolManagementPermission {}),
+        error::permission_denied(ENO_DELEGATION_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_delegation_pool_management_permission` + + + +
public fun grant_delegation_pool_management_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_delegation_pool_management_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, DelegationPermission::DelegationPoolManagementPermission {})
+}
+
+ + + +
+ + + +## Function `check_stake_management_permission` + + + +
fun check_stake_management_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_stake_management_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, DelegationPermission::StakeManagementPermission {}),
+        error::permission_denied(ENO_DELEGATION_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_stake_management_permission` + + + +
public fun grant_stake_management_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_stake_management_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, DelegationPermission::StakeManagementPermission {})
+}
+
+ + +
@@ -2782,6 +2950,7 @@ Ownership over setting the operator/voter is granted to owner who h operator_commission_percentage: u64, delegation_pool_creation_seed: vector<u8>, ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_delegation_pool_management_permission(owner); assert!(features::delegation_pools_enabled(), error::invalid_state(EDELEGATION_POOLS_DISABLED)); let owner_address = signer::address_of(owner); assert!(!owner_cap_exists(owner_address), error::already_exists(EOWNER_CAP_ALREADY_EXISTS)); @@ -2942,6 +3111,7 @@ Vote on a proposal with a voter's voting power. To successfully vote, the follow voting_power: u64, should_pass: bool ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_stake_management_permission(voter); assert_partial_governance_voting_enabled(pool_address); // synchronize delegation and stake pools before any user operation. synchronize_delegation_pool(pool_address); @@ -3022,6 +3192,7 @@ voting power in THIS delegation pool must be not less than the minimum required metadata_hash: vector<u8>, is_multi_step_proposal: bool, ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_stake_management_permission(voter); assert_partial_governance_voting_enabled(pool_address); // synchronize delegation and stake pools before any user operation @@ -3794,6 +3965,7 @@ Allows an owner to change the operator of the underlying stake pool. owner: &signer, new_operator: address ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_delegation_pool_management_permission(owner); let pool_address = get_owned_pool_address(signer::address_of(owner)); // synchronize delegation and stake pools before any user operation // ensure the old operator is paid its uncommitted commission rewards @@ -3829,6 +4001,7 @@ one for each pool. operator: &signer, new_beneficiary: address ) acquires BeneficiaryForOperator { + check_stake_management_permission(operator); assert!(features::operator_beneficiary_change_enabled(), std::error::invalid_state( EOPERATOR_BENEFICIARY_CHANGE_NOT_SUPPORTED )); @@ -3874,6 +4047,7 @@ Allows an owner to update the commission percentage for the operator of the unde owner: &signer, new_commission_percentage: u64 ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_delegation_pool_management_permission(owner); assert!(features::commission_change_delegation_pool_enabled(), error::invalid_state( ECOMMISSION_RATE_CHANGE_NOT_SUPPORTED )); @@ -3939,6 +4113,7 @@ Allows an owner to change the delegated voter of the underlying stake pool. owner: &signer, new_voter: address ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_delegation_pool_management_permission(owner); // No one can change delegated_voter once the partial governance voting feature is enabled. assert!( !features::delegation_pool_partial_governance_voting_enabled(), @@ -3977,6 +4152,7 @@ this change won't take effects until the next lockup period. pool_address: address, new_voter: address ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_stake_management_permission(delegator); assert_partial_governance_voting_enabled(pool_address); // synchronize delegation and stake pools before any user operation @@ -4054,6 +4230,7 @@ Enable delegators allowlisting as the pool owner.
public entry fun enable_delegators_allowlisting(
     owner: &signer,
 ) acquires DelegationPoolOwnership, DelegationPool {
+    check_delegation_pool_management_permission(owner);
     assert!(
         features::delegation_pool_allowlisting_enabled(),
         error::invalid_state(EDELEGATORS_ALLOWLISTING_NOT_SUPPORTED)
@@ -4092,6 +4269,7 @@ Disable delegators allowlisting as the pool owner. The existing allowlist will b
 
public entry fun disable_delegators_allowlisting(
     owner: &signer,
 ) acquires DelegationPoolOwnership, DelegationPoolAllowlisting {
+    check_delegation_pool_management_permission(owner);
     let pool_address = get_owned_pool_address(signer::address_of(owner));
     assert_allowlisting_enabled(pool_address);
 
@@ -4127,6 +4305,7 @@ Allowlist a delegator as the pool owner.
     owner: &signer,
     delegator_address: address,
 ) acquires DelegationPoolOwnership, DelegationPoolAllowlisting {
+    check_delegation_pool_management_permission(owner);
     let pool_address = get_owned_pool_address(signer::address_of(owner));
     assert_allowlisting_enabled(pool_address);
 
@@ -4162,6 +4341,7 @@ Remove a delegator from the allowlist as the pool owner, but do not unlock their
     owner: &signer,
     delegator_address: address,
 ) acquires DelegationPoolOwnership, DelegationPoolAllowlisting {
+    check_delegation_pool_management_permission(owner);
     let pool_address = get_owned_pool_address(signer::address_of(owner));
     assert_allowlisting_enabled(pool_address);
 
@@ -4197,6 +4377,7 @@ Evict a delegator that is not allowlisted by unlocking their entire stake.
     owner: &signer,
     delegator_address: address,
 ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting {
+    check_delegation_pool_management_permission(owner);
     let pool_address = get_owned_pool_address(signer::address_of(owner));
     assert_allowlisting_enabled(pool_address);
     assert!(
@@ -4241,6 +4422,7 @@ Add amount of coins to the delegation pool pool_addressaddress,
     amount: u64
 ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting {
+    check_stake_management_permission(delegator);
     // short-circuit if amount to add is 0 so no event is emitted
     if (amount == 0) { return };
 
@@ -4318,6 +4500,7 @@ at most how much active stake there is on the stake pool.
     pool_address: address,
     amount: u64
 ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
+    check_stake_management_permission(delegator);
     // short-circuit if amount to unlock is 0 so no event is emitted
     if (amount == 0) { return };
 
@@ -4419,6 +4602,7 @@ Move amount of coins from pending_inactive to active.
     pool_address: address,
     amount: u64
 ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting {
+    check_stake_management_permission(delegator);
     // short-circuit if amount to reactivate is 0 so no event is emitted
     if (amount == 0) { return };
 
@@ -4489,6 +4673,7 @@ Withdraw amount of owned inactive stake from the delegation pool at
     pool_address: address,
     amount: u64
 ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
+    check_stake_management_permission(delegator);
     assert!(amount > 0, error::invalid_argument(EWITHDRAW_ZERO_STAKE));
     // synchronize delegation and stake pools before any user operation
     synchronize_delegation_pool(pool_address);
diff --git a/aptos-move/framework/aptos-framework/doc/dispatchable_fungible_asset.md b/aptos-move/framework/aptos-framework/doc/dispatchable_fungible_asset.md
index 944c283025880..bfe682fe63ce4 100644
--- a/aptos-move/framework/aptos-framework/doc/dispatchable_fungible_asset.md
+++ b/aptos-move/framework/aptos-framework/doc/dispatchable_fungible_asset.md
@@ -221,6 +221,7 @@ The semantics of deposit will be governed by the function specified in DispatchF
     amount: u64,
 ): FungibleAsset acquires TransferRefStore {
     fungible_asset::withdraw_sanity_check(owner, store, false);
+    fungible_asset::withdraw_permission_check(owner, store, amount);
     let func_opt = fungible_asset::withdraw_dispatch_function(store);
     if (option::is_some(&func_opt)) {
         assert!(
diff --git a/aptos-move/framework/aptos-framework/doc/fungible_asset.md b/aptos-move/framework/aptos-framework/doc/fungible_asset.md
index af27435844e3d..9b9cfc806050a 100644
--- a/aptos-move/framework/aptos-framework/doc/fungible_asset.md
+++ b/aptos-move/framework/aptos-framework/doc/fungible_asset.md
@@ -22,6 +22,7 @@ metadata object can be any object that equipped with use 0x1::function_info;
 use 0x1::object;
 use 0x1::option;
+use 0x1::permissioned_signer;
 use 0x1::signer;
 use 0x1::string;
 
@@ -626,6 +635,45 @@ MutateMetadataRef can be used to directly modify the fungible asset's Metadata. + + + + +## Enum `WithdrawPermission` + + + +
enum WithdrawPermission has copy, drop, store
+
+ + + +
+Variants + + +
+ByStore + + +
+Fields + + +
+
+store_address: address +
+
+ +
+
+ + +
+ +
+
@@ -1139,7 +1187,7 @@ The balance ref and the fungible asset do not match. The supply ref and the fungible asset do not match. -
const ERAW_SUPPLY_REF_AND_FUNGIBLE_ASSET_MISMATCH: u64 = 34;
+
const ERAW_SUPPLY_REF_AND_FUNGIBLE_ASSET_MISMATCH: u64 = 35;
 
@@ -1224,6 +1272,16 @@ Provided withdraw function type doesn't meet the signature requirement. + + +signer don't have the permission to perform withdraw operation + + +
const EWITHDRAW_PERMISSION_DENIED: u64 = 36;
+
+ + + @@ -2948,12 +3006,75 @@ that function unless you DO NOT want to support fungible assets with dispatchabl amount: u64, ): FungibleAsset acquires FungibleStore, DispatchFunctionStore, ConcurrentFungibleBalance { withdraw_sanity_check(owner, store, true); + withdraw_permission_check(owner, store, amount); unchecked_withdraw(object::object_address(&store), amount) }
+ + + + +## Function `withdraw_permission_check` + +Check the permission for withdraw operation. + + +
public(friend) fun withdraw_permission_check<T: key>(owner: &signer, store: object::Object<T>, amount: u64)
+
+ + + +
+Implementation + + +
public(friend) fun withdraw_permission_check<T: key>(
+    owner: &signer,
+    store: Object<T>,
+    amount: u64,
+) {
+    assert!(permissioned_signer::check_permission_consume(owner, amount as u256, WithdrawPermission::ByStore {
+        store_address: object::object_address(&store),
+    }), error::permission_denied(EWITHDRAW_PERMISSION_DENIED));
+}
+
+ + + +
+ + + +## Function `withdraw_permission_check_by_address` + +Check the permission for withdraw operation. + + +
public(friend) fun withdraw_permission_check_by_address(owner: &signer, store_address: address, amount: u64)
+
+ + + +
+Implementation + + +
public(friend) fun withdraw_permission_check_by_address(
+    owner: &signer,
+    store_address: address,
+    amount: u64,
+) {
+    assert!(permissioned_signer::check_permission_consume(owner, amount as u256, WithdrawPermission::ByStore {
+        store_address,
+    }), error::permission_denied(EWITHDRAW_PERMISSION_DENIED));
+}
+
+ + +
@@ -2977,7 +3098,39 @@ Check the permission for withdraw operation. store: Object<T>, abort_on_dispatch: bool, ) acquires FungibleStore, DispatchFunctionStore { - assert!(object::owns(store, signer::address_of(owner)), error::permission_denied(ENOT_STORE_OWNER)); + withdraw_sanity_check_impl( + signer::address_of(owner), + store, + abort_on_dispatch, + ) +} +
+ + + + + + + +## Function `withdraw_sanity_check_impl` + + + +
fun withdraw_sanity_check_impl<T: key>(owner_address: address, store: object::Object<T>, abort_on_dispatch: bool)
+
+ + + +
+Implementation + + +
inline fun withdraw_sanity_check_impl<T: key>(
+    owner_address: address,
+    store: Object<T>,
+    abort_on_dispatch: bool,
+) acquires FungibleStore, DispatchFunctionStore {
+    assert!(object::owns(store, owner_address), error::permission_denied(ENOT_STORE_OWNER));
     let fa_store = borrow_store_resource(&store);
     assert!(
         !abort_on_dispatch || !has_withdraw_dispatch_function(fa_store.metadata),
@@ -4112,6 +4265,138 @@ Ensure a known 
+
+## Function `grant_permission_by_store`
+
+Permission management
+
+Master signer grant permissioned signer ability to withdraw a given amount of fungible asset.
+
+
+
public fun grant_permission_by_store<T: key>(master: &signer, permissioned: &signer, store: object::Object<T>, amount: u64)
+
+ + + +
+Implementation + + +
public fun grant_permission_by_store<T: key>(
+    master: &signer,
+    permissioned: &signer,
+    store: Object<T>,
+    amount: u64
+) {
+    permissioned_signer::authorize_increase(
+        master,
+        permissioned,
+        amount as u256,
+        WithdrawPermission::ByStore {
+            store_address: object::object_address(&store),
+        }
+    )
+}
+
+ + + +
+ + + +## Function `grant_permission_by_address` + + + +
public(friend) fun grant_permission_by_address(master: &signer, permissioned: &signer, store_address: address, amount: u64)
+
+ + + +
+Implementation + + +
public(friend) fun grant_permission_by_address(
+    master: &signer,
+    permissioned: &signer,
+    store_address: address,
+    amount: u64
+) {
+    permissioned_signer::authorize_increase(
+        master,
+        permissioned,
+        amount as u256,
+        WithdrawPermission::ByStore { store_address }
+    )
+}
+
+ + + +
+ + + +## Function `refill_permission` + + + +
public(friend) fun refill_permission(permissioned: &signer, amount: u64, store_address: address)
+
+ + + +
+Implementation + + +
public(friend) fun refill_permission(
+    permissioned: &signer,
+    amount: u64,
+    store_address: address,
+) {
+    permissioned_signer::increase_limit(
+        permissioned,
+        amount as u256,
+        WithdrawPermission::ByStore { store_address }
+    )
+}
+
+ + + +
+ + + +## Function `revoke_permission` + +Removing permissions from permissioned signer. + + +
public fun revoke_permission(permissioned: &signer, token_type: object::Object<fungible_asset::Metadata>)
+
+ + + +
+Implementation + + +
public fun revoke_permission(permissioned: &signer, token_type: Object<Metadata>) {
+    permissioned_signer::revoke_permission(permissioned, WithdrawPermission::ByStore {
+        store_address: object::object_address(&token_type),
+    })
+}
+
+ + +
diff --git a/aptos-move/framework/aptos-framework/doc/lite_account.md b/aptos-move/framework/aptos-framework/doc/lite_account.md new file mode 100644 index 0000000000000..fe595f286e68b --- /dev/null +++ b/aptos-move/framework/aptos-framework/doc/lite_account.md @@ -0,0 +1,547 @@ + + + +# Module `0x1::lite_account` + + + +- [Struct `UpdateDispatchableAuthenticator`](#0x1_lite_account_UpdateDispatchableAuthenticator) +- [Struct `RemoveDispatchableAuthenticator`](#0x1_lite_account_RemoveDispatchableAuthenticator) +- [Resource `DispatchableAuthenticator`](#0x1_lite_account_DispatchableAuthenticator) +- [Constants](#@Constants_0) +- [Function `add_dispatchable_authentication_function`](#0x1_lite_account_add_dispatchable_authentication_function) +- [Function `remove_dispatchable_authentication_function`](#0x1_lite_account_remove_dispatchable_authentication_function) +- [Function `remove_dispatchable_authenticator`](#0x1_lite_account_remove_dispatchable_authenticator) +- [Function `resource_addr`](#0x1_lite_account_resource_addr) +- [Function `update_dispatchable_authenticator_impl`](#0x1_lite_account_update_dispatchable_authenticator_impl) +- [Function `using_dispatchable_authenticator`](#0x1_lite_account_using_dispatchable_authenticator) +- [Function `dispatchable_authenticator`](#0x1_lite_account_dispatchable_authenticator) +- [Function `dispatchable_authenticator_internal`](#0x1_lite_account_dispatchable_authenticator_internal) +- [Function `authenticate`](#0x1_lite_account_authenticate) +- [Function `dispatchable_authenticate`](#0x1_lite_account_dispatchable_authenticate) +- [Specification](#@Specification_1) + - [Function `dispatchable_authenticate`](#@Specification_1_dispatchable_authenticate) + + +
use 0x1::create_signer;
+use 0x1::error;
+use 0x1::event;
+use 0x1::function_info;
+use 0x1::object;
+use 0x1::option;
+use 0x1::signer;
+use 0x1::signing_data;
+use 0x1::simple_map;
+use 0x1::string;
+
+ + + + + +## Struct `UpdateDispatchableAuthenticator` + + + +
#[event]
+struct UpdateDispatchableAuthenticator has drop, store
+
+ + + +
+Fields + + +
+
+account: address +
+
+ +
+
+update: vector<u8> +
+
+ +
+
+auth_function: function_info::FunctionInfo +
+
+ +
+
+ + +
+ + + +## Struct `RemoveDispatchableAuthenticator` + + + +
#[event]
+struct RemoveDispatchableAuthenticator has drop, store
+
+ + + +
+Fields + + +
+
+account: address +
+
+ +
+
+ + +
+ + + +## Resource `DispatchableAuthenticator` + +The dispatchable authenticator that defines how to authenticates this account in the specified module. +An integral part of Account Abstraction. + + +
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
+struct DispatchableAuthenticator has copy, drop, key
+
+ + + +
+Fields + + +
+
+auth_functions: simple_map::SimpleMap<function_info::FunctionInfo, bool> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const MAX_U64: u128 = 18446744073709551615;
+
+ + + + + + + +
const EAUTH_FUNCTION_SIGNATURE_MISMATCH: u64 = 3;
+
+ + + + + + + +
const EDISPATCHABLE_AUTHENTICATOR_IS_NOT_USED: u64 = 1;
+
+ + + + + + + +
const EFUNCTION_INFO_EXISTENCE: u64 = 2;
+
+ + + + + + + +
const ENOT_MASTER_SIGNER: u64 = 4;
+
+ + + + + +## Function `add_dispatchable_authentication_function` + +Update dispatchable authenticator that enables account abstraction. +Note: it is a private entry function that can only be called directly from transaction. + + +
public entry fun add_dispatchable_authentication_function(account: &signer, module_address: address, module_name: string::String, function_name: string::String)
+
+ + + +
+Implementation + + +
public entry fun add_dispatchable_authentication_function(
+    account: &signer,
+    module_address: address,
+    module_name: String,
+    function_name: String,
+) acquires DispatchableAuthenticator {
+    //assert!(!is_permissioned_signer(account), error::permission_denied(ENOT_MASTER_SIGNER));
+    update_dispatchable_authenticator_impl(
+        account,
+        function_info::new_function_info_from_address(module_address, module_name, function_name),
+        true
+    );
+}
+
+ + + +
+ + + +## Function `remove_dispatchable_authentication_function` + + + +
public entry fun remove_dispatchable_authentication_function(account: &signer, module_address: address, module_name: string::String, function_name: string::String)
+
+ + + +
+Implementation + + +
public entry fun remove_dispatchable_authentication_function(
+    account: &signer,
+    module_address: address,
+    module_name: String,
+    function_name: String,
+) acquires DispatchableAuthenticator {
+    //assert!(!is_permissioned_signer(account), error::permission_denied(ENOT_MASTER_SIGNER));
+    update_dispatchable_authenticator_impl(
+        account,
+        function_info::new_function_info_from_address(module_address, module_name, function_name),
+        false
+    );
+}
+
+ + + +
+ + + +## Function `remove_dispatchable_authenticator` + +Update dispatchable authenticator that disables account abstraction. +Note: it is a private entry function that can only be called directly from transaction. + + +
public entry fun remove_dispatchable_authenticator(account: &signer)
+
+ + + +
+Implementation + + +
public entry fun remove_dispatchable_authenticator(
+    account: &signer,
+) acquires DispatchableAuthenticator {
+    //assert!(!is_permissioned_signer(account), error::permission_denied(ENOT_MASTER_SIGNER));
+    let addr = signer::address_of(account);
+    let resource_addr = resource_addr(addr);
+    if (exists<DispatchableAuthenticator>(resource_addr)) {
+        move_from<DispatchableAuthenticator>(resource_addr);
+        event::emit(RemoveDispatchableAuthenticator {
+            account: addr,
+        });
+    };
+}
+
+ + + +
+ + + +## Function `resource_addr` + + + +
fun resource_addr(source: address): address
+
+ + + +
+Implementation + + +
inline fun resource_addr(source: address): address {
+    object::create_user_derived_object_address(source, @aptos_fungible_asset)
+}
+
+ + + +
+ + + +## Function `update_dispatchable_authenticator_impl` + + + +
public(friend) fun update_dispatchable_authenticator_impl(account: &signer, auth_function: function_info::FunctionInfo, is_add: bool)
+
+ + + +
+Implementation + + +
public(friend) fun update_dispatchable_authenticator_impl(
+    account: &signer,
+    auth_function: FunctionInfo,
+    is_add: bool,
+) acquires DispatchableAuthenticator {
+    let addr = signer::address_of(account);
+    let resource_addr = resource_addr(addr);
+        let dispatcher_auth_function_info = function_info::new_function_info_from_address(
+            @aptos_framework,
+            string::utf8(b"lite_account"),
+            string::utf8(b"dispatchable_authenticate"),
+        );
+        assert!(
+            function_info::check_dispatch_type_compatibility(&dispatcher_auth_function_info, &auth_function),
+            error::invalid_argument(EAUTH_FUNCTION_SIGNATURE_MISMATCH)
+        );
+    if (is_add && !exists<DispatchableAuthenticator>(resource_addr)) {
+            move_to(&create_signer::create_signer(resource_addr), DispatchableAuthenticator {
+                auth_functions: simple_map::new()
+            });
+        };
+        if (exists<DispatchableAuthenticator>(resource_addr)) {
+            let current_map = &mut borrow_global_mut<DispatchableAuthenticator>(resource_addr).auth_functions;
+            if (is_add) {
+                assert!(!simple_map::contains_key(current_map, &auth_function), error::already_exists(EFUNCTION_INFO_EXISTENCE));
+                simple_map::add(current_map, auth_function, true);
+            } else {
+                assert!(simple_map::contains_key(current_map, &auth_function), error::not_found(EFUNCTION_INFO_EXISTENCE));
+                simple_map::remove(current_map, &auth_function);
+            };
+            event::emit(
+                UpdateDispatchableAuthenticator {
+                    account: addr,
+                    update: if (is_add) {b"add"} else {b"remove"},
+                    auth_function,
+                }
+            );
+            if (simple_map::length(current_map) == 0) {
+                remove_dispatchable_authenticator(account);
+            }
+        };
+}
+
+ + + +
+ + + +## Function `using_dispatchable_authenticator` + +Return true if the account is an abstracted account that can be authenticated with dispatchable move authenticator. + + +
#[view]
+public fun using_dispatchable_authenticator(addr: address): bool
+
+ + + +
+Implementation + + +
public fun using_dispatchable_authenticator(addr: address): bool {
+    exists<DispatchableAuthenticator>(resource_addr(addr))
+}
+
+ + + +
+ + + +## Function `dispatchable_authenticator` + +Return the current dispatchable authenticator move function info. None means this authentication scheme is disabled. + + +
#[view]
+public fun dispatchable_authenticator(addr: address): option::Option<vector<function_info::FunctionInfo>>
+
+ + + +
+Implementation + + +
public fun dispatchable_authenticator(addr: address): Option<vector<FunctionInfo>> acquires DispatchableAuthenticator {
+    let resource_addr = resource_addr(addr);
+    if (exists<DispatchableAuthenticator>(resource_addr)) {
+        option::some(
+            simple_map::keys(&borrow_global<DispatchableAuthenticator>(resource_addr).auth_functions)
+        )
+    } else { option::none() }
+}
+
+ + + +
+ + + +## Function `dispatchable_authenticator_internal` + + + +
fun dispatchable_authenticator_internal(addr: address): &simple_map::SimpleMap<function_info::FunctionInfo, bool>
+
+ + + +
+Implementation + + +
inline fun dispatchable_authenticator_internal(addr: address): &SimpleMap<FunctionInfo, bool> {
+    assert!(using_dispatchable_authenticator(addr), error::not_found(EDISPATCHABLE_AUTHENTICATOR_IS_NOT_USED));
+    &borrow_global<DispatchableAuthenticator>(resource_addr(addr)).auth_functions
+}
+
+ + + +
+ + + +## Function `authenticate` + + + +
fun authenticate(account: signer, func_info: function_info::FunctionInfo, signing_data: signing_data::SigningData): signer
+
+ + + +
+Implementation + + +
fun authenticate(
+    account: signer,
+    func_info: FunctionInfo,
+    signing_data: SigningData,
+): signer acquires DispatchableAuthenticator {
+    let func_infos = dispatchable_authenticator_internal(signer::address_of(&account));
+    assert!(simple_map::contains_key(func_infos, &func_info), error::not_found(EFUNCTION_INFO_EXISTENCE));
+    function_info::load_module_from_function(&func_info);
+    dispatchable_authenticate(account, signing_data, &func_info)
+}
+
+ + + +
+ + + +## Function `dispatchable_authenticate` + +The native function to dispatch customized move authentication function. + + +
fun dispatchable_authenticate(account: signer, signing_data: signing_data::SigningData, function: &function_info::FunctionInfo): signer
+
+ + + +
+Implementation + + +
native fun dispatchable_authenticate(
+    account: signer,
+    signing_data: SigningData,
+    function: &FunctionInfo
+): signer;
+
+ + + +
+ + + +## Specification + + + +
pragma verify = false;
+
+ + + + + +### Function `dispatchable_authenticate` + + +
fun dispatchable_authenticate(account: signer, signing_data: signing_data::SigningData, function: &function_info::FunctionInfo): signer
+
+ + + + +
pragma opaque;
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/managed_coin.md b/aptos-move/framework/aptos-framework/doc/managed_coin.md index 50c2383fd111d..ede3c87a278f2 100644 --- a/aptos-move/framework/aptos-framework/doc/managed_coin.md +++ b/aptos-move/framework/aptos-framework/doc/managed_coin.md @@ -378,7 +378,7 @@ Removes capabilities from the account to be stored or destroyed elsewhere
pragma verify = true;
-pragma aborts_if_is_strict;
+pragma aborts_if_is_partial;
 
diff --git a/aptos-move/framework/aptos-framework/doc/multisig_account.md b/aptos-move/framework/aptos-framework/doc/multisig_account.md index 0b6aa0e44dd7a..4e9e9de51191b 100644 --- a/aptos-move/framework/aptos-framework/doc/multisig_account.md +++ b/aptos-move/framework/aptos-framework/doc/multisig_account.md @@ -4166,7 +4166,8 @@ Add new owners, remove owners to remove, update signatures required. -
aborts_if !exists<account::Account>(creator);
+
pragma aborts_if_is_partial;
+aborts_if !exists<account::Account>(creator);
 let owner_nonce = global<account::Account>(creator).sequence_number;
 
diff --git a/aptos-move/framework/aptos-framework/doc/object.md b/aptos-move/framework/aptos-framework/doc/object.md index 7ae33a425ee25..48279c737cf73 100644 --- a/aptos-move/framework/aptos-framework/doc/object.md +++ b/aptos-move/framework/aptos-framework/doc/object.md @@ -32,6 +32,7 @@ make it so that a reference to a global object can be returned from a function. - [Struct `TransferRef`](#0x1_object_TransferRef) - [Struct `LinearTransferRef`](#0x1_object_LinearTransferRef) - [Struct `DeriveRef`](#0x1_object_DeriveRef) +- [Struct `TransferPermission`](#0x1_object_TransferPermission) - [Struct `TransferEvent`](#0x1_object_TransferEvent) - [Struct `Transfer`](#0x1_object_Transfer) - [Constants](#@Constants_0) @@ -89,6 +90,8 @@ make it so that a reference to a global object can be returned from a function. - [Function `is_owner`](#0x1_object_is_owner) - [Function `owns`](#0x1_object_owns) - [Function `root_owner`](#0x1_object_root_owner) +- [Function `grant_permission`](#0x1_object_grant_permission) +- [Function `grant_permission_with_transfer_ref`](#0x1_object_grant_permission_with_transfer_ref) - [Specification](#@Specification_1) - [High-level Requirements](#high-level-req) - [Module-level Specification](#module-level-spec) @@ -133,6 +136,7 @@ make it so that a reference to a global object can be returned from a function. - [Function `is_owner`](#@Specification_1_is_owner) - [Function `owns`](#@Specification_1_owns) - [Function `root_owner`](#@Specification_1_root_owner) + - [Function `grant_permission`](#@Specification_1_grant_permission)
use 0x1::account;
@@ -144,6 +148,7 @@ make it so that a reference to a global object can be returned from a function.
 use 0x1::from_bcs;
 use 0x1::guid;
 use 0x1::hash;
+use 0x1::permissioned_signer;
 use 0x1::signer;
 use 0x1::transaction_context;
 use 0x1::vector;
@@ -496,6 +501,34 @@ Used to create derived objects from a given objects.
 
 
 
+
+ + + +## Struct `TransferPermission` + +Permission to transfer object with permissioned signer. + + +
struct TransferPermission has copy, drop, store
+
+ + + +
+Fields + + +
+
+object: address +
+
+ +
+
+ +
@@ -1999,6 +2032,10 @@ hierarchy. to: address, ) acquires ObjectCore { let owner_address = signer::address_of(owner); + assert!( + permissioned_signer::check_permission_exists(owner, TransferPermission { object }), + error::permission_denied(EOBJECT_NOT_TRANSFERRABLE) + ); verify_ungated_and_descendant(owner_address, object); transfer_raw_inner(object, to); } @@ -2188,6 +2225,10 @@ Allow origin owners to reclaim any objects they previous burnt. ) acquires TombStone, ObjectCore { let object_addr = object.inner; assert!(exists<TombStone>(object_addr), error::invalid_argument(EOBJECT_NOT_BURNT)); + assert!( + permissioned_signer::check_permission_exists(original_owner, TransferPermission { object: object_addr }), + error::permission_denied(EOBJECT_NOT_TRANSFERRABLE) + ); let TombStone { original_owner: original_owner_addr } = move_from<TombStone>(object_addr); assert!(original_owner_addr == signer::address_of(original_owner), error::permission_denied(ENOT_OBJECT_OWNER)); @@ -2361,6 +2402,70 @@ to determine the identity of the starting point of ownership. + + + + +## Function `grant_permission` + +Master signer offers a transfer permission of an object to a permissioned signer. + + +
public fun grant_permission<T>(master: &signer, permissioned_signer: &signer, object: object::Object<T>)
+
+ + + +
+Implementation + + +
public fun grant_permission<T>(
+    master: &signer,
+    permissioned_signer: &signer,
+    object: Object<T>,
+) {
+    permissioned_signer::authorize_unlimited(
+        master,
+        permissioned_signer,
+        TransferPermission { object: object.inner }
+    )
+}
+
+ + + +
+ + + +## Function `grant_permission_with_transfer_ref` + +Grant a transfer permission to the permissioned signer using TransferRef. + + +
public fun grant_permission_with_transfer_ref(permissioned_signer: &signer, ref: &object::TransferRef)
+
+ + + +
+Implementation + + +
public fun grant_permission_with_transfer_ref(
+    permissioned_signer: &signer,
+    ref: &TransferRef,
+) {
+    permissioned_signer::grant_unlimited_with_permissioned_signer(
+        permissioned_signer,
+        TransferPermission { object: ref.self }
+    )
+}
+
+ + +
@@ -2437,16 +2542,7 @@ to determine the identity of the starting point of ownership. ### Module-level Specification -
pragma aborts_if_is_strict;
-
- - - - - - - -
fun spec_exists_at<T: key>(object: address): bool;
+
pragma aborts_if_is_partial;
 
@@ -3402,4 +3498,32 @@ to determine the identity of the starting point of ownership.
+ + + +### Function `grant_permission` + + +
public fun grant_permission<T>(master: &signer, permissioned_signer: &signer, object: object::Object<T>)
+
+ + + + +
pragma aborts_if_is_partial;
+aborts_if !permissioned_signer::spec_is_permissioned_signer(permissioned_signer);
+aborts_if permissioned_signer::spec_is_permissioned_signer(master);
+aborts_if signer::address_of(master) != signer::address_of(permissioned_signer);
+
+ + + + + + + +
fun spec_exists_at<T: key>(object: address): bool;
+
+ + [move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/object_code_deployment.md b/aptos-move/framework/aptos-framework/doc/object_code_deployment.md index e4caf56a77c74..db2ac6c296522 100644 --- a/aptos-move/framework/aptos-framework/doc/object_code_deployment.md +++ b/aptos-move/framework/aptos-framework/doc/object_code_deployment.md @@ -190,6 +190,16 @@ Event emitted when code in an existing object is made immutable. + + +Current permissioned signer cannot deploy object code. + + +
const ENO_CODE_PERMISSION: u64 = 4;
+
+ + + Not the owner of the code_object @@ -243,6 +253,7 @@ the code to be published via code. T metadata_serialized: vector<u8>, code: vector<vector<u8>>, ) { + code::check_code_publishing_permission(publisher); assert!( features::is_object_code_deployment_enabled(), error::unavailable(EOBJECT_CODE_DEPLOYMENT_NOT_SUPPORTED), @@ -319,6 +330,7 @@ Requires the publisher to be the owner of the code_object. code: vector<vector<u8>>, code_object: Object<PackageRegistry>, ) acquires ManagingRefs { + code::check_code_publishing_permission(publisher); let publisher_address = signer::address_of(publisher); assert!( object::is_owner(code_object, publisher_address), diff --git a/aptos-move/framework/aptos-stdlib/doc/ordered_map.md b/aptos-move/framework/aptos-framework/doc/ordered_map.md similarity index 81% rename from aptos-move/framework/aptos-stdlib/doc/ordered_map.md rename to aptos-move/framework/aptos-framework/doc/ordered_map.md index 4a3a1d56b0733..cd90763cdbfe8 100644 --- a/aptos-move/framework/aptos-stdlib/doc/ordered_map.md +++ b/aptos-move/framework/aptos-framework/doc/ordered_map.md @@ -76,10 +76,10 @@ allowing cleaner iterator APIs. - [Specification](#@Specification_1) -
use 0x1::cmp;
-use 0x1::error;
-use 0x1::option;
-use 0x1::vector;
+
use 0x1::cmp;
+use 0x1::error;
+use 0x1::option;
+use 0x1::vector;
 
@@ -144,7 +144,7 @@ The OrderedMap datastructure.
-entries: vector<ordered_map::Entry<K, V>> +entries: vector<ordered_map::Entry<K, V>>
List of entries, sorted by key. @@ -278,7 +278,7 @@ Create a new empty OrderedMap, using default (SortedVectorMap) implementation.
public fun new<K, V>(): OrderedMap<K, V> {
     OrderedMap::SortedVectorMap {
-        entries: vector::empty(),
+        entries: vector::empty(),
     }
 }
 
@@ -295,7 +295,7 @@ Create a OrderedMap from a vector of keys and values. Aborts with EKEY_ALREADY_EXISTS if duplicate keys are passed in. -
public fun new_from<K, V>(keys: vector<K>, values: vector<V>): ordered_map::OrderedMap<K, V>
+
public fun new_from<K, V>(keys: vector<K>, values: vector<V>): ordered_map::OrderedMap<K, V>
 
@@ -304,7 +304,7 @@ Aborts with EKEY_ALREADY_EXISTS if duplicate keys are passed in. Implementation -
public fun new_from<K, V>(keys: vector<K>, values: vector<V>): OrderedMap<K, V> {
+
public fun new_from<K, V>(keys: vector<K>, values: vector<V>): OrderedMap<K, V> {
     let map = new();
     add_all(&mut map, keys, values);
     map
@@ -387,7 +387,7 @@ Aborts with EKEY_ALREADY_EXISTS if key already exist.
     let index = binary_search(&key, &self.entries, 0, len);
 
     // key must not already be inside.
-    assert!(index >= len || &self.entries[index].key != &key, error::invalid_argument(EKEY_ALREADY_EXISTS));
+    assert!(index >= len || &self.entries[index].key != &key, error::invalid_argument(EKEY_ALREADY_EXISTS));
     self.entries.insert(index, Entry { key, value });
 }
 
@@ -404,7 +404,7 @@ If the key doesn't exist in the map, inserts the key/value, and returns none. Otherwise, updates the value under the given key, and returns the old value. -
public fun upsert<K: drop, V>(self: &mut ordered_map::OrderedMap<K, V>, key: K, value: V): option::Option<V>
+
public fun upsert<K: drop, V>(self: &mut ordered_map::OrderedMap<K, V>, key: K, value: V): option::Option<V>
 
@@ -422,10 +422,10 @@ Otherwise, updates the value under the given key, and returns the old value. key: _, value: old_value, } = self.entries.replace(index, Entry { key, value }); - option::some(old_value) + option::some(old_value) } else { self.entries.insert(index, Entry { key, value }); - option::none() + option::none() } }
@@ -454,9 +454,9 @@ Aborts with EKEY_NOT_FOUND if key doesn't exist.
public fun remove<K: drop, V>(self: &mut OrderedMap<K, V>, key: &K): V {
     let len = self.entries.length();
     let index = binary_search(key, &self.entries, 0, len);
-    assert!(index < len, error::invalid_argument(EKEY_NOT_FOUND));
+    assert!(index < len, error::invalid_argument(EKEY_NOT_FOUND));
     let Entry { key: old_key, value } = self.entries.remove(index);
-    assert!(key == &old_key, error::invalid_argument(EKEY_NOT_FOUND));
+    assert!(key == &old_key, error::invalid_argument(EKEY_NOT_FOUND));
     value
 }
 
@@ -559,17 +559,17 @@ Aborts with ENEW_KEY_NOT_IN_ORDER if new_key doesn't keep the order
public(friend) fun replace_key_inplace<K: drop, V>(self: &mut OrderedMap<K, V>, old_key: &K, new_key: K) {
     let len = self.entries.length();
     let index = binary_search(old_key, &self.entries, 0, len);
-    assert!(index < len, error::invalid_argument(EKEY_NOT_FOUND));
+    assert!(index < len, error::invalid_argument(EKEY_NOT_FOUND));
 
-    assert!(old_key == &self.entries[index].key, error::invalid_argument(EKEY_NOT_FOUND));
+    assert!(old_key == &self.entries[index].key, error::invalid_argument(EKEY_NOT_FOUND));
 
     // check that after we update the key, order is going to be respected
     if (index > 0) {
-        assert!(cmp::compare(&self.entries[index - 1].key, &new_key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
+        assert!(cmp::compare(&self.entries[index - 1].key, &new_key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
     };
 
     if (index + 1 < len) {
-        assert!(cmp::compare(&new_key, &self.entries[index + 1].key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
+        assert!(cmp::compare(&new_key, &self.entries[index + 1].key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
     };
 
     self.entries[index].key = new_key;
@@ -588,7 +588,7 @@ Add multiple key/value pairs to the map. The keys must not already exist.
 Aborts with EKEY_ALREADY_EXISTS if key already exist, or duplicate keys are passed in.
 
 
-
public fun add_all<K, V>(self: &mut ordered_map::OrderedMap<K, V>, keys: vector<K>, values: vector<V>)
+
public fun add_all<K, V>(self: &mut ordered_map::OrderedMap<K, V>, keys: vector<K>, values: vector<V>)
 
@@ -597,9 +597,9 @@ Aborts with EKEY_ALREADY_EXISTS if key already exist, or duplicate keys are pass Implementation -
public fun add_all<K, V>(self: &mut OrderedMap<K, V>, keys: vector<K>, values: vector<V>) {
+
public fun add_all<K, V>(self: &mut OrderedMap<K, V>, keys: vector<K>, values: vector<V>) {
     // TODO: Can be optimized, by sorting keys and values, and then creating map.
-    vector::zip(keys, values, |key, value| {
+    vector::zip(keys, values, |key, value| {
         self.add(key, value);
     });
 }
@@ -617,7 +617,7 @@ Add multiple key/value pairs to the map, overwrites values if they exist already
 or if duplicate keys are passed in.
 
 
-
public fun upsert_all<K: drop, V: drop>(self: &mut ordered_map::OrderedMap<K, V>, keys: vector<K>, values: vector<V>)
+
public fun upsert_all<K: drop, V: drop>(self: &mut ordered_map::OrderedMap<K, V>, keys: vector<K>, values: vector<V>)
 
@@ -626,9 +626,9 @@ or if duplicate keys are passed in. Implementation -
public fun upsert_all<K: drop, V: drop>(self: &mut OrderedMap<K, V>, keys: vector<K>, values: vector<V>) {
+
public fun upsert_all<K: drop, V: drop>(self: &mut OrderedMap<K, V>, keys: vector<K>, values: vector<V>) {
     // TODO: Can be optimized, by sorting keys and values, and then creating map.
-    vector::zip(keys, values, |key, value| {
+    vector::zip(keys, values, |key, value| {
         self.upsert(key, value);
     });
 }
@@ -683,7 +683,7 @@ Aborts with EKEY_ALREADY_EXISTS if other has a key already present
 
 
public fun append_disjoint<K, V>(self: &mut OrderedMap<K, V>, other: OrderedMap<K, V>) {
     let overwritten = self.append_impl(other);
-    assert!(overwritten.length() == 0, error::invalid_argument(EKEY_ALREADY_EXISTS));
+    assert!(overwritten.length() == 0, error::invalid_argument(EKEY_ALREADY_EXISTS));
     overwritten.destroy_empty();
 }
 
@@ -699,7 +699,7 @@ Aborts with EKEY_ALREADY_EXISTS if other has a key already present Takes all elements from other and adds them to self, returning list of entries in self that were overwritten. -
fun append_impl<K, V>(self: &mut ordered_map::OrderedMap<K, V>, other: ordered_map::OrderedMap<K, V>): vector<ordered_map::Entry<K, V>>
+
fun append_impl<K, V>(self: &mut ordered_map::OrderedMap<K, V>, other: ordered_map::OrderedMap<K, V>): vector<ordered_map::Entry<K, V>>
 
@@ -708,11 +708,11 @@ Takes all elements from other and adds them to self, r Implementation -
fun append_impl<K, V>(self: &mut OrderedMap<K, V>, other: OrderedMap<K, V>): vector<Entry<K,V>> {
+
fun append_impl<K, V>(self: &mut OrderedMap<K, V>, other: OrderedMap<K, V>): vector<Entry<K,V>> {
     let OrderedMap::SortedVectorMap {
         entries: other_entries,
     } = other;
-    let overwritten = vector::empty();
+    let overwritten = vector::empty();
 
     if (other_entries.is_empty()) {
         other_entries.destroy_empty();
@@ -725,25 +725,25 @@ Takes all elements from other and adds them to self, r
     };
 
     // Optimization: if all elements in `other` are larger than all elements in `self`, we can just move them over.
-    if (cmp::compare(&self.entries.borrow(self.entries.length() - 1).key, &other_entries.borrow(0).key).is_lt()) {
+    if (cmp::compare(&self.entries.borrow(self.entries.length() - 1).key, &other_entries.borrow(0).key).is_lt()) {
         self.entries.append(other_entries);
         return overwritten;
     };
 
     // In O(n), traversing from the back, build reverse sorted result, and then reverse it back
-    let reverse_result = vector::empty();
+    let reverse_result = vector::empty();
     let cur_i = self.entries.length() - 1;
     let other_i = other_entries.length() - 1;
 
-    // after the end of the loop, other_entries is empty, and any leftover is in entries
+    // after the end of the loop, other_entries is empty, and any leftover is in entries
     loop {
-        let ord = cmp::compare(&self.entries[cur_i].key, &other_entries[other_i].key);
+        let ord = cmp::compare(&self.entries[cur_i].key, &other_entries[other_i].key);
         if (ord.is_gt()) {
             reverse_result.push_back(self.entries.pop_back());
             if (cur_i == 0) {
                 // make other_entries empty, and rest in entries.
-                // TODO cannot use mem::swap until it is public/released
-                // mem::swap(&mut self.entries, &mut other_entries);
+                // TODO cannot use mem::swap until it is public/released
+                // mem::swap(&mut self.entries, &mut other_entries);
                 self.entries.append(other_entries);
                 break;
             } else {
@@ -946,7 +946,7 @@ Note: Requires that the map is not changed after the input iterator is generated
 
 
 
public(friend) fun iter_next<K, V>(self: IteratorPtr, map: &OrderedMap<K, V>): IteratorPtr {
-    assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
     let index = self.index + 1;
     if (index < map.entries.length()) {
@@ -979,7 +979,7 @@ Note: Requires that the map is not changed after the input iterator is generated
 
 
 
public(friend) fun iter_prev<K, V>(self: IteratorPtr, map: &OrderedMap<K, V>): IteratorPtr {
-    assert!(!self.iter_is_begin(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!self.iter_is_begin(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
     let index = if (self is IteratorPtr::End) {
         map.entries.length() - 1
@@ -1099,7 +1099,7 @@ Note: Requires that the map is not changed after the input iterator is generated
 
 
 
public(friend) fun iter_borrow_key<K, V>(self: &IteratorPtr, map: &OrderedMap<K, V>): &K {
-    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
     &map.entries.borrow(self.index).key
 }
@@ -1128,7 +1128,7 @@ Note: Requires that the map is not changed after the input iterator is generated
 
 
 
public(friend) fun iter_borrow<K, V>(self: IteratorPtr, map: &OrderedMap<K, V>): &V {
-    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
     &map.entries.borrow(self.index).value
 }
 
@@ -1156,7 +1156,7 @@ Note: Requires that the map is not changed after the input iterator is generated
public(friend) fun iter_borrow_mut<K, V>(self: IteratorPtr, map: &mut OrderedMap<K, V>): &mut V {
-    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
     &mut map.entries.borrow_mut(self.index).value
 }
 
@@ -1184,7 +1184,7 @@ Note: Requires that the map is not changed after the input iterator is generated
public(friend) fun iter_remove<K: drop, V>(self: IteratorPtr, map: &mut OrderedMap<K, V>): V {
-    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
     let Entry { key: _, value } = map.entries.remove(self.index);
     value
@@ -1214,11 +1214,11 @@ Note: Requires that the map is not changed after the input iterator is generated
 
 
 
public(friend) fun iter_replace<K: copy + drop, V>(self: IteratorPtr, map: &mut OrderedMap<K, V>, value: V): V {
-    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!(self is IteratorPtr::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
-    // TODO once mem::replace is public/released, update to:
+    // TODO once mem::replace is public/released, update to:
     // let entry = map.entries.borrow_mut(self.index);
-    // mem::replace(&mut entry.value, value)
+    // mem::replace(&mut entry.value, value)
     let key = map.entries[self.index].key;
     let Entry {
         key: _,
@@ -1259,11 +1259,11 @@ or smaller than the key at the iterator position.
     };
 
     if (insert_index > 0) {
-        assert!(cmp::compare(&map.entries[insert_index - 1].key, &key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
+        assert!(cmp::compare(&map.entries[insert_index - 1].key, &key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
     };
 
     if (insert_index < len) {
-        assert!(cmp::compare(&key, &map.entries[insert_index].key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
+        assert!(cmp::compare(&key, &map.entries[insert_index].key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
     };
 
     map.entries.insert(insert_index, Entry { key, value });
@@ -1309,7 +1309,7 @@ Aborts if self is not empty.
 Return all keys in the map. This requires keys to be copyable.
 
 
-
public fun keys<K: copy, V>(self: &ordered_map::OrderedMap<K, V>): vector<K>
+
public fun keys<K: copy, V>(self: &ordered_map::OrderedMap<K, V>): vector<K>
 
@@ -1318,8 +1318,8 @@ Return all keys in the map. This requires keys to be copyable. Implementation -
public fun keys<K: copy, V>(self: &OrderedMap<K, V>): vector<K> {
-    vector::map_ref(&self.entries, |e| {
+
public fun keys<K: copy, V>(self: &OrderedMap<K, V>): vector<K> {
+    vector::map_ref(&self.entries, |e| {
         let e: &Entry<K, V> = e;
         e.key
     })
@@ -1337,7 +1337,7 @@ Return all keys in the map. This requires keys to be copyable.
 Return all values in the map. This requires values to be copyable.
 
 
-
public fun values<K, V: copy>(self: &ordered_map::OrderedMap<K, V>): vector<V>
+
public fun values<K, V: copy>(self: &ordered_map::OrderedMap<K, V>): vector<V>
 
@@ -1346,8 +1346,8 @@ Return all values in the map. This requires values to be copyable. Implementation -
public fun values<K, V: copy>(self: &OrderedMap<K, V>): vector<V> {
-    vector::map_ref(&self.entries, |e| {
+
public fun values<K, V: copy>(self: &OrderedMap<K, V>): vector<V> {
+    vector::map_ref(&self.entries, |e| {
         let e: &Entry<K, V> = e;
         e.value
     })
@@ -1366,7 +1366,7 @@ Transform the map into two vectors with the keys and values respectively
 Primarily used to destroy a map
 
 
-
public fun to_vec_pair<K, V>(self: ordered_map::OrderedMap<K, V>): (vector<K>, vector<V>)
+
public fun to_vec_pair<K, V>(self: ordered_map::OrderedMap<K, V>): (vector<K>, vector<V>)
 
@@ -1375,14 +1375,14 @@ Primarily used to destroy a map Implementation -
public fun to_vec_pair<K, V>(self: OrderedMap<K, V>): (vector<K>, vector<V>) {
-    let keys: vector<K> = vector::empty();
-    let values: vector<V> = vector::empty();
+
public fun to_vec_pair<K, V>(self: OrderedMap<K, V>): (vector<K>, vector<V>) {
+    let keys: vector<K> = vector::empty();
+    let values: vector<V> = vector::empty();
     let OrderedMap::SortedVectorMap { entries } = self;
-    vector::for_each(entries, |e| {
+    vector::for_each(entries, |e| {
         let Entry { key, value } = e;
-        vector::push_back(&mut keys, key);
-        vector::push_back(&mut values, value);
+        vector::push_back(&mut keys, key);
+        vector::push_back(&mut values, value);
     });
     (keys, values)
 }
@@ -1415,8 +1415,8 @@ using lambdas to destroy the individual keys and values.
     dv: |V|
 ) {
     let (keys, values) = to_vec_pair(self);
-    vector::destroy(keys, |_k| dk(_k));
-    vector::destroy(values, |_v| dv(_v));
+    vector::destroy(keys, |_k| dk(_k));
+    vector::destroy(values, |_v| dv(_v));
 }
 
@@ -1447,7 +1447,7 @@ Apply the function to a reference of each key-value pair in the table. iter = iter.iter_next(self); } // TODO: once move supports private functions udpate to: - // vector::for_each_ref( + // vector::for_each_ref( // &self.entries, // |entry| { // f(&entry.key, &entry.value) @@ -1484,7 +1484,7 @@ Apply the function to a mutable reference of each key-value pair in the table. iter = iter.iter_next(self); } // TODO: once move supports private functions udpate to: - // vector::for_each_mut( + // vector::for_each_mut( // &mut self.entries, // |entry| { // f(&mut entry.key, &mut entry.value) @@ -1529,7 +1529,7 @@ Apply the function to a mutable reference of each key-value pair in the table. -
fun binary_search<K, V>(key: &K, entries: &vector<ordered_map::Entry<K, V>>, start: u64, end: u64): u64
+
fun binary_search<K, V>(key: &K, entries: &vector<ordered_map::Entry<K, V>>, start: u64, end: u64): u64
 
@@ -1538,12 +1538,12 @@ Apply the function to a mutable reference of each key-value pair in the table. Implementation -
fun binary_search<K, V>(key: &K, entries: &vector<Entry<K, V>>, start: u64, end: u64): u64 {
+
fun binary_search<K, V>(key: &K, entries: &vector<Entry<K, V>>, start: u64, end: u64): u64 {
     let l = start;
     let r = end;
     while (l != r) {
         let mid = l + ((r - l) >> 1);
-        let comparison = cmp::compare(&entries.borrow(mid).key, key);
+        let comparison = cmp::compare(&entries.borrow(mid).key, key);
         if (comparison.is_lt()) {
             l = mid + 1;
         } else {
diff --git a/aptos-move/framework/aptos-framework/doc/overview.md b/aptos-move/framework/aptos-framework/doc/overview.md
index 314baa3612ba9..4e7b3a475209b 100644
--- a/aptos-move/framework/aptos-framework/doc/overview.md
+++ b/aptos-move/framework/aptos-framework/doc/overview.md
@@ -13,12 +13,15 @@ This is the reference documentation of the Aptos framework.
 
 
 -  [`0x1::account`](account.md#0x1_account)
+-  [`0x1::account_abstraction`](account_abstraction.md#0x1_account_abstraction)
 -  [`0x1::aggregator`](aggregator.md#0x1_aggregator)
 -  [`0x1::aggregator_factory`](aggregator_factory.md#0x1_aggregator_factory)
 -  [`0x1::aggregator_v2`](aggregator_v2.md#0x1_aggregator_v2)
 -  [`0x1::aptos_account`](aptos_account.md#0x1_aptos_account)
 -  [`0x1::aptos_coin`](aptos_coin.md#0x1_aptos_coin)
 -  [`0x1::aptos_governance`](aptos_governance.md#0x1_aptos_governance)
+-  [`0x1::auth_data`](auth_data.md#0x1_auth_data)
+-  [`0x1::big_ordered_map`](big_ordered_map.md#0x1_big_ordered_map)
 -  [`0x1::block`](block.md#0x1_block)
 -  [`0x1::chain_id`](chain_id.md#0x1_chain_id)
 -  [`0x1::chain_status`](chain_status.md#0x1_chain_status)
@@ -46,6 +49,8 @@ This is the reference documentation of the Aptos framework.
 -  [`0x1::object`](object.md#0x1_object)
 -  [`0x1::object_code_deployment`](object_code_deployment.md#0x1_object_code_deployment)
 -  [`0x1::optional_aggregator`](optional_aggregator.md#0x1_optional_aggregator)
+-  [`0x1::ordered_map`](ordered_map.md#0x1_ordered_map)
+-  [`0x1::permissioned_signer`](permissioned_signer.md#0x1_permissioned_signer)
 -  [`0x1::primary_fungible_store`](primary_fungible_store.md#0x1_primary_fungible_store)
 -  [`0x1::randomness`](randomness.md#0x1_randomness)
 -  [`0x1::randomness_api_v0_config`](randomness_api_v0_config.md#0x1_randomness_api_v0_config)
diff --git a/aptos-move/framework/aptos-framework/doc/permissioned_delegation.md b/aptos-move/framework/aptos-framework/doc/permissioned_delegation.md
new file mode 100644
index 0000000000000..2edb6975559be
--- /dev/null
+++ b/aptos-move/framework/aptos-framework/doc/permissioned_delegation.md
@@ -0,0 +1,361 @@
+
+
+
+# Module `0x1::permissioned_delegation`
+
+
+
+-  [Resource `Delegation`](#0x1_permissioned_delegation_Delegation)
+-  [Constants](#@Constants_0)
+-  [Function `add_permissioned_handle`](#0x1_permissioned_delegation_add_permissioned_handle)
+-  [Function `remove_permissioned_handle`](#0x1_permissioned_delegation_remove_permissioned_handle)
+-  [Function `permissioned_signer_by_key`](#0x1_permissioned_delegation_permissioned_signer_by_key)
+-  [Function `remove_permissioned_handle_by_delegate`](#0x1_permissioned_delegation_remove_permissioned_handle_by_delegate)
+-  [Function `handle_address_by_key`](#0x1_permissioned_delegation_handle_address_by_key)
+-  [Function `authenticate`](#0x1_permissioned_delegation_authenticate)
+-  [Function `get_permissioned_signer`](#0x1_permissioned_delegation_get_permissioned_signer)
+
+
+
use 0x1::bcs_stream;
+use 0x1::ed25519;
+use 0x1::error;
+use 0x1::permissioned_signer;
+use 0x1::signer;
+use 0x1::table;
+
+ + + + + +## Resource `Delegation` + + + +
struct Delegation has key
+
+ + + +
+Fields + + +
+
+handles: table::Table<ed25519::UnvalidatedPublicKey, permissioned_signer::StorablePermissionedHandle> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const ENOT_MASTER_SIGNER: u64 = 1;
+
+ + + + + + + +
const EINVALID_PUBLIC_KEY: u64 = 2;
+
+ + + + + + + +
const EHANDLE_EXISTENCE: u64 = 5;
+
+ + + + + + + +
const EINVALID_SIGNATURE: u64 = 4;
+
+ + + + + + + +
const EPUBLIC_KEY_NOT_FOUND: u64 = 3;
+
+ + + + + +## Function `add_permissioned_handle` + + + +
public fun add_permissioned_handle(master: &signer, key: vector<u8>, expiration_time: u64): signer
+
+ + + +
+Implementation + + +
public fun add_permissioned_handle(
+    master: &signer,
+    key: vector<u8>,
+    expiration_time: u64,
+): signer acquires Delegation {
+    assert!(!is_permissioned_signer(master), error::permission_denied(ENOT_MASTER_SIGNER));
+    let addr = signer::address_of(master);
+    let pubkey = ed25519::new_unvalidated_public_key_from_bytes(key);
+    if (!exists<Delegation>(addr)) {
+        move_to(master, Delegation {
+            handles: table::new()
+        });
+    };
+    let handles = &mut borrow_global_mut<Delegation>(addr).handles;
+    assert!(!table::contains(handles, pubkey), error::already_exists(EHANDLE_EXISTENCE));
+    let handle = permissioned_signer::create_storable_permissioned_handle(master, expiration_time);
+    let permissioned_signer = permissioned_signer::signer_from_storable_permissioned(&handle);
+    table::add(handles, pubkey, handle);
+    permissioned_signer
+}
+
+ + + +
+ + + +## Function `remove_permissioned_handle` + + + +
public fun remove_permissioned_handle(master: &signer, key: vector<u8>)
+
+ + + +
+Implementation + + +
public fun remove_permissioned_handle(
+    master: &signer,
+    key: vector<u8>,
+) acquires Delegation {
+    assert!(!is_permissioned_signer(master), error::permission_denied(ENOT_MASTER_SIGNER));
+    let addr = signer::address_of(master);
+    let pubkey = ed25519::new_unvalidated_public_key_from_bytes(key);
+    let handles = &mut borrow_global_mut<Delegation>(addr).handles;
+    assert!(table::contains(handles, pubkey), error::not_found(EHANDLE_EXISTENCE));
+    permissioned_signer::destroy_storable_permissioned_handle(table::remove(handles, pubkey));
+}
+
+ + + +
+ + + +## Function `permissioned_signer_by_key` + + + +
public fun permissioned_signer_by_key(master: &signer, key: vector<u8>): signer
+
+ + + +
+Implementation + + +
public fun permissioned_signer_by_key(
+    master: &signer,
+    key: vector<u8>,
+): signer acquires Delegation {
+    assert!(!is_permissioned_signer(master), error::permission_denied(ENOT_MASTER_SIGNER));
+    let addr = signer::address_of(master);
+    let pubkey = ed25519::new_unvalidated_public_key_from_bytes(key);
+    get_permissioned_signer(addr, pubkey)
+}
+
+ + + +
+ + + +## Function `remove_permissioned_handle_by_delegate` + + + +
public fun remove_permissioned_handle_by_delegate(master: address, signature: vector<u8>): permissioned_signer::StorablePermissionedHandle
+
+ + + +
+Implementation + + +
public fun remove_permissioned_handle_by_delegate(
+    master: address,
+    signature: vector<u8>,
+): StorablePermissionedHandle acquires Delegation {
+    let stream = bcs_stream::new(signature);
+    let public_key = new_unvalidated_public_key_from_bytes(
+        bcs_stream::deserialize_vector<u8>(&mut stream, |x| deserialize_u8(x))
+    );
+    let signature = new_signature_from_bytes(
+        bcs_stream::deserialize_vector<u8>(&mut stream, |x| deserialize_u8(x))
+    );
+    assert!(
+        ed25519::signature_verify_strict(
+            &signature,
+            &public_key,
+            vector[1, 2, 3],
+        ),
+        error::permission_denied(EINVALID_SIGNATURE)
+    );
+    let handles = &mut borrow_global_mut<Delegation>(master).handles;
+    assert!(table::contains(handles, public_key), error::not_found(EHANDLE_EXISTENCE));
+    table::remove(handles, public_key)
+}
+
+ + + +
+ + + +## Function `handle_address_by_key` + + + +
#[view]
+public fun handle_address_by_key(master: address, key: vector<u8>): address
+
+ + + +
+Implementation + + +
public fun handle_address_by_key(master: address, key: vector<u8>): address acquires Delegation {
+    let pubkey = ed25519::new_unvalidated_public_key_from_bytes(key);
+    let handles = &borrow_global<Delegation>(master).handles;
+    assert!(table::contains(handles, pubkey), error::not_found(EHANDLE_EXISTENCE));
+    permissioned_signer::permission_address(table::borrow(handles, pubkey))
+}
+
+ + + +
+ + + +## Function `authenticate` + +Authorization function for account abstraction. + + +
public fun authenticate(account: signer, transaction_hash: vector<u8>, signature: vector<u8>): signer
+
+ + + +
+Implementation + + +
public fun authenticate(
+    account: signer,
+    transaction_hash: vector<u8>,
+    signature: vector<u8>
+): signer acquires Delegation {
+    let addr = signer::address_of(&account);
+    let stream = bcs_stream::new(signature);
+    let public_key = new_unvalidated_public_key_from_bytes(
+        bcs_stream::deserialize_vector<u8>(&mut stream, |x| deserialize_u8(x))
+    );
+    let signature = new_signature_from_bytes(
+        bcs_stream::deserialize_vector<u8>(&mut stream, |x| deserialize_u8(x))
+    );
+    assert!(
+        ed25519::signature_verify_strict(
+            &signature,
+            &public_key,
+            transaction_hash,
+        ),
+        error::permission_denied(EINVALID_SIGNATURE)
+    );
+    get_permissioned_signer(addr, public_key)
+}
+
+ + + +
+ + + +## Function `get_permissioned_signer` + + + +
fun get_permissioned_signer(master: address, pubkey: ed25519::UnvalidatedPublicKey): signer
+
+ + + +
+Implementation + + +
inline fun get_permissioned_signer(master: address, pubkey: UnvalidatedPublicKey): signer {
+    if (exists<Delegation>(master)) {
+        let handles = &borrow_global<Delegation>(master).handles;
+        if (table::contains(handles, pubkey)) {
+            let signer = permissioned_signer::signer_from_storable_permissioned(table::borrow(handles, pubkey));
+            signer
+        } else {
+            abort error::permission_denied(EINVALID_SIGNATURE)
+        }
+    } else {
+        abort error::permission_denied(EINVALID_SIGNATURE)
+    }
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/permissioned_signer.md b/aptos-move/framework/aptos-framework/doc/permissioned_signer.md new file mode 100644 index 0000000000000..9fb317115c7f3 --- /dev/null +++ b/aptos-move/framework/aptos-framework/doc/permissioned_signer.md @@ -0,0 +1,1940 @@ + + + +# Module `0x1::permissioned_signer` + +A _permissioned signer_ consists of a pair of the original signer and a generated +address which is used to store information about associated permissions. + +A permissioned signer is a restricted version of a signer. Functions move_to and +address_of behave the same, and can be passed wherever signer is needed. However, +code can internally query for the permissions to assert additional restrictions on +the use of the signer. + +A client which is interested in restricting access granted via a signer can create a permissioned signer +and pass on to other existing code without changes to existing APIs. Core functions in the framework, for +example account functions, can then assert availability of permissions, effectively restricting +existing code in a compatible way. + +After introducing the core functionality, examples are provided for withdraw limit on accounts, and +for blind signing. + + +- [Struct `RevokePermissionHandlePermission`](#0x1_permissioned_signer_RevokePermissionHandlePermission) +- [Resource `GrantedPermissionHandles`](#0x1_permissioned_signer_GrantedPermissionHandles) +- [Enum `PermissionedHandle`](#0x1_permissioned_signer_PermissionedHandle) +- [Enum `StorablePermissionedHandle`](#0x1_permissioned_signer_StorablePermissionedHandle) +- [Enum Resource `PermissionStorage`](#0x1_permissioned_signer_PermissionStorage) +- [Enum `StoredPermission`](#0x1_permissioned_signer_StoredPermission) +- [Constants](#@Constants_0) +- [Function `create_permissioned_handle`](#0x1_permissioned_signer_create_permissioned_handle) +- [Function `destroy_permissioned_handle`](#0x1_permissioned_signer_destroy_permissioned_handle) +- [Function `signer_from_permissioned_handle`](#0x1_permissioned_signer_signer_from_permissioned_handle) +- [Function `is_permissioned_signer`](#0x1_permissioned_signer_is_permissioned_signer) +- [Function `grant_revoke_permission`](#0x1_permissioned_signer_grant_revoke_permission) +- [Function `revoke_permission_storage_address`](#0x1_permissioned_signer_revoke_permission_storage_address) +- [Function `revoke_all_handles`](#0x1_permissioned_signer_revoke_all_handles) +- [Function `initialize_permission_address`](#0x1_permissioned_signer_initialize_permission_address) +- [Function `create_storable_permissioned_handle`](#0x1_permissioned_signer_create_storable_permissioned_handle) +- [Function `destroy_storable_permissioned_handle`](#0x1_permissioned_signer_destroy_storable_permissioned_handle) +- [Function `destroy_permissions_storage_address`](#0x1_permissioned_signer_destroy_permissions_storage_address) +- [Function `signer_from_storable_permissioned_handle`](#0x1_permissioned_signer_signer_from_storable_permissioned_handle) +- [Function `permissions_storage_address`](#0x1_permissioned_signer_permissions_storage_address) +- [Function `assert_master_signer`](#0x1_permissioned_signer_assert_master_signer) +- [Function `is_above`](#0x1_permissioned_signer_is_above) +- [Function `consume_capacity`](#0x1_permissioned_signer_consume_capacity) +- [Function `increase_capacity`](#0x1_permissioned_signer_increase_capacity) +- [Function `merge`](#0x1_permissioned_signer_merge) +- [Function `map_or`](#0x1_permissioned_signer_map_or) +- [Function `insert_or`](#0x1_permissioned_signer_insert_or) +- [Function `authorize_increase`](#0x1_permissioned_signer_authorize_increase) +- [Function `authorize_unlimited`](#0x1_permissioned_signer_authorize_unlimited) +- [Function `grant_unlimited_with_permissioned_signer`](#0x1_permissioned_signer_grant_unlimited_with_permissioned_signer) +- [Function `increase_limit`](#0x1_permissioned_signer_increase_limit) +- [Function `check_permission_exists`](#0x1_permissioned_signer_check_permission_exists) +- [Function `check_permission_capacity_above`](#0x1_permissioned_signer_check_permission_capacity_above) +- [Function `check_permission_consume`](#0x1_permissioned_signer_check_permission_consume) +- [Function `capacity`](#0x1_permissioned_signer_capacity) +- [Function `revoke_permission`](#0x1_permissioned_signer_revoke_permission) +- [Function `is_permissioned_signer_impl`](#0x1_permissioned_signer_is_permissioned_signer_impl) +- [Function `permission_address`](#0x1_permissioned_signer_permission_address) +- [Function `signer_from_permissioned_handle_impl`](#0x1_permissioned_signer_signer_from_permissioned_handle_impl) +- [Specification](#@Specification_1) + - [Function `create_permissioned_handle`](#@Specification_1_create_permissioned_handle) + - [Function `destroy_permissioned_handle`](#@Specification_1_destroy_permissioned_handle) + - [Function `is_permissioned_signer`](#@Specification_1_is_permissioned_signer) + - [Function `revoke_permission_storage_address`](#@Specification_1_revoke_permission_storage_address) + - [Function `create_storable_permissioned_handle`](#@Specification_1_create_storable_permissioned_handle) + - [Function `destroy_storable_permissioned_handle`](#@Specification_1_destroy_storable_permissioned_handle) + - [Function `authorize_increase`](#@Specification_1_authorize_increase) + - [Function `check_permission_exists`](#@Specification_1_check_permission_exists) + - [Function `check_permission_capacity_above`](#@Specification_1_check_permission_capacity_above) + - [Function `check_permission_consume`](#@Specification_1_check_permission_consume) + - [Function `capacity`](#@Specification_1_capacity) + - [Function `permission_address`](#@Specification_1_permission_address) + - [Function `signer_from_permissioned_handle_impl`](#@Specification_1_signer_from_permissioned_handle_impl) + + +
use 0x1::big_ordered_map;
+use 0x1::copyable_any;
+use 0x1::create_signer;
+use 0x1::error;
+use 0x1::features;
+use 0x1::option;
+use 0x1::signer;
+use 0x1::timestamp;
+use 0x1::transaction_context;
+use 0x1::vector;
+
+ + + + + +## Struct `RevokePermissionHandlePermission` + +If a permissioned signer has this permission, it would be able to revoke other granted +permission handles in the same signer. + + +
struct RevokePermissionHandlePermission has copy, drop, store
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Resource `GrantedPermissionHandles` + +Stores the list of granted permission handles for a given account. + + +
struct GrantedPermissionHandles has key
+
+ + + +
+Fields + + +
+
+active_handles: vector<address> +
+
+ Each address refers to a permissions_storage_addr that stores the PermissionStorage. +
+
+ + +
+ + + +## Enum `PermissionedHandle` + +A ephermeral permission handle that can be used to generate a permissioned signer with permission +configuration stored within. + + +
enum PermissionedHandle
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+master_account_addr: address +
+
+ Address of the signer that creates this handle. +
+
+permissions_storage_addr: address +
+
+ Address that stores PermissionStorage. +
+
+ + +
+ +
+ +
+ + + +## Enum `StorablePermissionedHandle` + +A permission handle that can be used to generate a permissioned signer. + +This handle is storable and thus should be treated very carefully as it serves similar functionality +as signer delegation. + + +
enum StorablePermissionedHandle has store
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+master_account_addr: address +
+
+ Address of the signer that creates this handle. +
+
+permissions_storage_addr: address +
+
+ Address that stores PermissionStorage. +
+
+expiration_time: u64 +
+
+ Permissioned signer can no longer be generated from this handle after expiration_time. +
+
+ + +
+ +
+ +
+ + + +## Enum Resource `PermissionStorage` + +The actual permission configuration stored on-chain. + +The address that holds PermissionStorage will be generated freshly every time a permission +handle gets created. + + +
enum PermissionStorage has key
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+perms: big_ordered_map::BigOrderedMap<copyable_any::Any, permissioned_signer::StoredPermission> +
+
+ A hetherogenous map from Permission structs defined by each different modules to + its permission capacity. +
+
+ + +
+ +
+ +
+ + + +## Enum `StoredPermission` + +Types of permission capacity stored on chain. + + +
enum StoredPermission has copy, drop, store
+
+ + + +
+Variants + + +
+Unlimited + + +
+Fields + + +
+
+ + +
+ +
+ +
+Capacity + + +
+Fields + + +
+
+0: u256 +
+
+ +
+
+ + +
+ +
+ +
+ + + +## Constants + + + + +Cannot authorize a permission. + + +
const ECANNOT_AUTHORIZE: u64 = 2;
+
+ + + + + +signer doesn't have enough capacity to extract permission. + + +
const ECANNOT_EXTRACT_PERMISSION: u64 = 4;
+
+ + + + + +Trying to grant permission using non-master signer. + + +
const ENOT_MASTER_SIGNER: u64 = 1;
+
+ + + + + +Access permission information from a master signer. + + +
const ENOT_PERMISSIONED_SIGNER: u64 = 3;
+
+ + + + + +Permissioned signer feature is not activated. + + +
const EPERMISSION_SIGNER_DISABLED: u64 = 9;
+
+ + + + + +destroying permission handle that has already been revoked or not owned by the +given master signer. + + +
const E_NOT_ACTIVE: u64 = 8;
+
+ + + + + +permission handle has expired. + + +
const E_PERMISSION_EXPIRED: u64 = 5;
+
+ + + + + +storing extracted permission into a different signer. + + +
const E_PERMISSION_MISMATCH: u64 = 6;
+
+ + + + + +permission handle has been revoked by the original signer. + + +
const E_PERMISSION_REVOKED: u64 = 7;
+
+ + + + + + + +
const U256_MAX: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;
+
+ + + + + +## Function `create_permissioned_handle` + +Create an ephermeral permission handle based on the master signer. + +This handle can be used to derive a signer that can be used in the context of +the current transaction. + + +
public fun create_permissioned_handle(master: &signer): permissioned_signer::PermissionedHandle
+
+ + + +
+Implementation + + +
public fun create_permissioned_handle(master: &signer): PermissionedHandle {
+    assert!(
+        features::is_permissioned_signer_enabled(),
+        error::permission_denied(EPERMISSION_SIGNER_DISABLED)
+    );
+
+    assert_master_signer(master);
+    let permissions_storage_addr = generate_auid_address();
+    let master_account_addr = signer::address_of(master);
+
+    initialize_permission_address(permissions_storage_addr);
+
+    PermissionedHandle::V1 { master_account_addr, permissions_storage_addr }
+}
+
+ + + +
+ + + +## Function `destroy_permissioned_handle` + +Destroys an ephermeral permission handle. Clean up the permission stored in that handle + + +
public fun destroy_permissioned_handle(p: permissioned_signer::PermissionedHandle)
+
+ + + +
+Implementation + + +
public fun destroy_permissioned_handle(p: PermissionedHandle) acquires PermissionStorage {
+    assert!(
+        features::is_permissioned_signer_enabled(),
+        error::permission_denied(EPERMISSION_SIGNER_DISABLED)
+    );
+    let PermissionedHandle::V1 { master_account_addr: _, permissions_storage_addr } =
+        p;
+    destroy_permissions_storage_address(permissions_storage_addr);
+}
+
+ + + +
+ + + +## Function `signer_from_permissioned_handle` + +Generate the permissioned signer based on the ephermeral permission handle. + +This signer can be used as a regular signer for other smart contracts. However when such +signer interacts with various framework functions, it would subject to permission checks +and would abort if check fails. + + +
public fun signer_from_permissioned_handle(p: &permissioned_signer::PermissionedHandle): signer
+
+ + + +
+Implementation + + +
public fun signer_from_permissioned_handle(p: &PermissionedHandle): signer {
+    assert!(
+        features::is_permissioned_signer_enabled(),
+        error::permission_denied(EPERMISSION_SIGNER_DISABLED)
+    );
+    signer_from_permissioned_handle_impl(
+        p.master_account_addr, p.permissions_storage_addr
+    )
+}
+
+ + + +
+ + + +## Function `is_permissioned_signer` + +Returns true if s is a permissioned signer. + + +
public fun is_permissioned_signer(s: &signer): bool
+
+ + + +
+Implementation + + +
public fun is_permissioned_signer(s: &signer): bool {
+    // When the permissioned signer is disabled, no one is able to construct a permissioned
+    // signer. Thus we should return false here, as other on chain permission checks will
+    // depend on this checks.
+    if(!features::is_permissioned_signer_enabled()) {
+        return false;
+    };
+    is_permissioned_signer_impl(s)
+}
+
+ + + +
+ + + +## Function `grant_revoke_permission` + +Grant the permissioned signer the permission to revoke granted permission handles under +its address. + + +
public fun grant_revoke_permission(master: &signer, permissioned: &signer)
+
+ + + +
+Implementation + + +
public fun grant_revoke_permission(
+    master: &signer,
+    permissioned: &signer,
+) acquires PermissionStorage {
+    assert!(
+        features::is_permissioned_signer_enabled(),
+        error::permission_denied(EPERMISSION_SIGNER_DISABLED)
+    );
+    authorize_unlimited(master, permissioned, RevokePermissionHandlePermission {});
+}
+
+ + + +
+ + + +## Function `revoke_permission_storage_address` + +Revoke a specific storable permission handle immediately. This will disallow owner of +the storable permission handle to derive signer from it anymore. + + +
public entry fun revoke_permission_storage_address(s: &signer, permissions_storage_addr: address)
+
+ + + +
+Implementation + + +
public entry fun revoke_permission_storage_address(
+    s: &signer, permissions_storage_addr: address
+) acquires GrantedPermissionHandles, PermissionStorage {
+    assert!(
+        features::is_permissioned_signer_enabled(),
+        error::permission_denied(EPERMISSION_SIGNER_DISABLED)
+    );
+    assert!(
+        check_permission_exists(s, RevokePermissionHandlePermission {}),
+        error::permission_denied(ENOT_MASTER_SIGNER)
+    );
+    let master_account_addr = signer::address_of(s);
+
+    assert!(
+        exists<GrantedPermissionHandles>(master_account_addr),
+        error::permission_denied(E_PERMISSION_REVOKED),
+    );
+    let active_handles = &mut GrantedPermissionHandles[master_account_addr].active_handles;
+    let (found, idx) = active_handles.index_of(&permissions_storage_addr);
+
+    // The address has to be in the activated list in the master account address.
+    assert!(found, error::permission_denied(E_NOT_ACTIVE));
+    active_handles.swap_remove(idx);
+    destroy_permissions_storage_address(permissions_storage_addr);
+}
+
+ + + +
+ + + +## Function `revoke_all_handles` + +Revoke all storable permission handle of the signer immediately. + + +
public entry fun revoke_all_handles(s: &signer)
+
+ + + +
+Implementation + + +
public entry fun revoke_all_handles(s: &signer) acquires GrantedPermissionHandles, PermissionStorage {
+    assert!(
+        features::is_permissioned_signer_enabled(),
+        error::permission_denied(EPERMISSION_SIGNER_DISABLED)
+    );
+    assert!(
+        check_permission_exists(s, RevokePermissionHandlePermission {}),
+        error::permission_denied(ENOT_MASTER_SIGNER)
+    );
+    let master_account_addr = signer::address_of(s);
+    if (!exists<GrantedPermissionHandles>(master_account_addr)) { return };
+
+    let granted_permissions =
+        borrow_global_mut<GrantedPermissionHandles>(master_account_addr);
+    let delete_list = vector::trim_reverse(
+        &mut granted_permissions.active_handles, 0
+    );
+    vector::destroy(
+        delete_list,
+        |address| {
+            destroy_permissions_storage_address(address);
+        }
+    )
+}
+
+ + + +
+ + + +## Function `initialize_permission_address` + +initialize permission storage by putting an empty storage under the address. + + +
fun initialize_permission_address(permissions_storage_addr: address)
+
+ + + +
+Implementation + + +
inline fun initialize_permission_address(permissions_storage_addr: address) {
+    move_to(
+        &create_signer(permissions_storage_addr),
+        // Each key is ~100bytes, the value is 12 bytes.
+        PermissionStorage::V1 { perms: big_ordered_map::new_with_config(40, 35, false, 0) }
+    );
+}
+
+ + + +
+ + + +## Function `create_storable_permissioned_handle` + +Create an storable permission handle based on the master signer. + +This handle can be used to derive a signer that can be stored by a smart contract. +This is as dangerous as key delegation, thus it remains public(package) for now. + +The caller should check if expiration_time is not too far in the future. + + +
public(friend) fun create_storable_permissioned_handle(master: &signer, expiration_time: u64): permissioned_signer::StorablePermissionedHandle
+
+ + + +
+Implementation + + +
public(package) fun create_storable_permissioned_handle(
+    master: &signer, expiration_time: u64
+): StorablePermissionedHandle acquires GrantedPermissionHandles {
+    assert!(
+        features::is_permissioned_signer_enabled(),
+        error::permission_denied(EPERMISSION_SIGNER_DISABLED)
+    );
+
+    assert_master_signer(master);
+    let permissions_storage_addr = generate_auid_address();
+    let master_account_addr = signer::address_of(master);
+
+    assert!(
+        timestamp::now_seconds() < expiration_time,
+        error::permission_denied(E_PERMISSION_EXPIRED)
+    );
+
+    if (!exists<GrantedPermissionHandles>(master_account_addr)) {
+        move_to<GrantedPermissionHandles>(
+            master, GrantedPermissionHandles { active_handles: vector::empty() }
+        );
+    };
+
+    GrantedPermissionHandles[master_account_addr]
+        .active_handles.push_back(permissions_storage_addr);
+
+    initialize_permission_address(permissions_storage_addr);
+
+    StorablePermissionedHandle::V1 {
+        master_account_addr,
+        permissions_storage_addr,
+        expiration_time
+    }
+}
+
+ + + +
+ + + +## Function `destroy_storable_permissioned_handle` + +Destroys a storable permission handle. Clean up the permission stored in that handle + + +
public(friend) fun destroy_storable_permissioned_handle(p: permissioned_signer::StorablePermissionedHandle)
+
+ + + +
+Implementation + + +
public(package) fun destroy_storable_permissioned_handle(
+    p: StorablePermissionedHandle
+) acquires PermissionStorage, GrantedPermissionHandles {
+    let StorablePermissionedHandle::V1 {
+        master_account_addr,
+        permissions_storage_addr,
+        expiration_time: _
+    } = p;
+
+    assert!(
+        exists<GrantedPermissionHandles>(master_account_addr),
+        error::permission_denied(E_PERMISSION_REVOKED),
+    );
+    let active_handles = &mut GrantedPermissionHandles[master_account_addr].active_handles;
+
+    let (found, idx) = active_handles.index_of(&permissions_storage_addr);
+
+    // Removing the address from the active handle list if it's still active.
+    if(found) {
+        active_handles.swap_remove(idx);
+    };
+
+    destroy_permissions_storage_address(permissions_storage_addr);
+}
+
+ + + +
+ + + +## Function `destroy_permissions_storage_address` + + + +
fun destroy_permissions_storage_address(permissions_storage_addr: address)
+
+ + + +
+Implementation + + +
inline fun destroy_permissions_storage_address(
+    permissions_storage_addr: address
+) acquires PermissionStorage {
+    if (exists<PermissionStorage>(permissions_storage_addr)) {
+        let PermissionStorage::V1 { perms } =
+            move_from<PermissionStorage>(permissions_storage_addr);
+        big_ordered_map::destroy(
+            perms,
+            |_dv| {},
+        );
+    }
+}
+
+ + + +
+ + + +## Function `signer_from_storable_permissioned_handle` + +Generate the permissioned signer based on the storable permission handle. + + +
public(friend) fun signer_from_storable_permissioned_handle(p: &permissioned_signer::StorablePermissionedHandle): signer
+
+ + + +
+Implementation + + +
public(package) fun signer_from_storable_permissioned_handle(
+    p: &StorablePermissionedHandle
+): signer {
+    assert!(
+        features::is_permissioned_signer_enabled(),
+        error::permission_denied(EPERMISSION_SIGNER_DISABLED)
+    );
+    assert!(
+        timestamp::now_seconds() < p.expiration_time,
+        error::permission_denied(E_PERMISSION_EXPIRED)
+    );
+    assert!(
+        exists<PermissionStorage>(p.permissions_storage_addr),
+        error::permission_denied(E_PERMISSION_REVOKED)
+    );
+    signer_from_permissioned_handle_impl(
+        p.master_account_addr, p.permissions_storage_addr
+    )
+}
+
+ + + +
+ + + +## Function `permissions_storage_address` + +Return the permission handle address so that it could be used for revocation purpose. + + +
public(friend) fun permissions_storage_address(p: &permissioned_signer::StorablePermissionedHandle): address
+
+ + + +
+Implementation + + +
public(package) fun permissions_storage_address(
+    p: &StorablePermissionedHandle
+): address {
+    p.permissions_storage_addr
+}
+
+ + + +
+ + + +## Function `assert_master_signer` + +Helper function that would abort if the signer passed in is a permissioned signer. + + +
public(friend) fun assert_master_signer(s: &signer)
+
+ + + +
+Implementation + + +
public(package) fun assert_master_signer(s: &signer) {
+    assert!(
+        !is_permissioned_signer(s), error::permission_denied(ENOT_MASTER_SIGNER)
+    );
+}
+
+ + + +
+ + + +## Function `is_above` + +===================================================================================================== +StoredPermission operations + +check if StoredPermission has at least threshold capacity. + + +
fun is_above(perm: &permissioned_signer::StoredPermission, threshold: u256): bool
+
+ + + +
+Implementation + + +
fun is_above(perm: &StoredPermission, threshold: u256): bool {
+    match (perm) {
+        StoredPermission::Capacity(capacity) => *capacity >= threshold,
+        StoredPermission::Unlimited => true,
+    }
+}
+
+ + + +
+ + + +## Function `consume_capacity` + +consume threshold capacity from StoredPermission + + +
fun consume_capacity(perm: &mut permissioned_signer::StoredPermission, threshold: u256): bool
+
+ + + +
+Implementation + + +
fun consume_capacity(perm: &mut StoredPermission, threshold: u256): bool {
+    match (perm) {
+        StoredPermission::Capacity(current_capacity) => {
+            if (*current_capacity >= threshold) {
+                *current_capacity = *current_capacity - threshold;
+                true
+            } else { false }
+        }
+        StoredPermission::Unlimited => true
+    }
+}
+
+ + + +
+ + + +## Function `increase_capacity` + +increase threshold capacity from StoredPermission + + +
fun increase_capacity(perm: &mut permissioned_signer::StoredPermission, threshold: u256)
+
+ + + +
+Implementation + + +
fun increase_capacity(perm: &mut StoredPermission, threshold: u256) {
+    match (perm) {
+        StoredPermission::Capacity(current_capacity) => {
+            *current_capacity = *current_capacity + threshold;
+        }
+        StoredPermission::Unlimited => (),
+    }
+}
+
+ + + +
+ + + +## Function `merge` + +merge the two stored permission + + +
fun merge(lhs: &mut permissioned_signer::StoredPermission, rhs: permissioned_signer::StoredPermission)
+
+ + + +
+Implementation + + +
fun merge(lhs: &mut StoredPermission, rhs: StoredPermission) {
+    match (rhs) {
+        StoredPermission::Capacity(new_capacity) => {
+            match (lhs) {
+                StoredPermission::Capacity(current_capacity) => {
+                    *current_capacity = *current_capacity + new_capacity;
+                }
+                StoredPermission::Unlimited => (),
+            }
+        }
+        StoredPermission::Unlimited => *lhs = StoredPermission::Unlimited,
+    }
+}
+
+ + + +
+ + + +## Function `map_or` + +===================================================================================================== +Permission Management + +Authorizes permissioned with the given permission. This requires to have access to the master +signer. + + +
fun map_or<PermKey: copy, drop, store, T>(permissioned: &signer, perm: PermKey, mutate: |&mut permissioned_signer::StoredPermission|T, default: T): T
+
+ + + +
+Implementation + + +
inline fun map_or<PermKey: copy + drop + store, T>(
+    permissioned: &signer,
+    perm: PermKey,
+    mutate: |&mut StoredPermission| T,
+    default: T,
+): T {
+    let permission_signer_addr = permission_address(permissioned);
+    assert!(
+        exists<PermissionStorage>(permission_signer_addr),
+        error::permission_denied(E_NOT_ACTIVE)
+    );
+    let perms =
+        &mut borrow_global_mut<PermissionStorage>(permission_signer_addr).perms;
+    let key = copyable_any::pack(perm);
+    if (big_ordered_map::contains(perms, &key)) {
+        let value = perms.remove(&key);
+        let return_ = mutate(&mut value);
+        perms.add(key, value);
+        return_
+    } else {
+        default
+    }
+}
+
+ + + +
+ + + +## Function `insert_or` + + + +
fun insert_or<PermKey: copy, drop, store>(permissioned: &signer, perm: PermKey, mutate: |&mut permissioned_signer::StoredPermission|, default: permissioned_signer::StoredPermission)
+
+ + + +
+Implementation + + +
inline fun insert_or<PermKey: copy + drop + store>(
+    permissioned: &signer,
+    perm: PermKey,
+    mutate: |&mut StoredPermission|,
+    default: StoredPermission,
+) {
+    let permission_signer_addr = permission_address(permissioned);
+    assert!(
+        exists<PermissionStorage>(permission_signer_addr),
+        error::permission_denied(E_NOT_ACTIVE)
+    );
+    let perms =
+        &mut borrow_global_mut<PermissionStorage>(permission_signer_addr).perms;
+    let key = copyable_any::pack(perm);
+    if (perms.contains(&key)) {
+        let value = perms.remove(&key);
+        mutate(&mut value);
+        perms.add(key, value);
+    } else {
+        perms.add(key, default);
+    }
+}
+
+ + + +
+ + + +## Function `authorize_increase` + +Authorizes permissioned with a given capacity and increment the existing capacity if present. + +Consumption using check_permission_consume will deduct the capacity. + + +
public(friend) fun authorize_increase<PermKey: copy, drop, store>(master: &signer, permissioned: &signer, capacity: u256, perm: PermKey)
+
+ + + +
+Implementation + + +
public(package) fun authorize_increase<PermKey: copy + drop + store>(
+    master: &signer,
+    permissioned: &signer,
+    capacity: u256,
+    perm: PermKey
+) acquires PermissionStorage {
+    assert!(
+        is_permissioned_signer(permissioned)
+            && !is_permissioned_signer(master)
+            && signer::address_of(master) == signer::address_of(permissioned),
+        error::permission_denied(ECANNOT_AUTHORIZE)
+    );
+    insert_or(
+        permissioned,
+        perm,
+        |stored_permission| {
+            increase_capacity(stored_permission, capacity);
+        },
+        StoredPermission::Capacity(capacity),
+    )
+}
+
+ + + +
+ + + +## Function `authorize_unlimited` + +Authorizes permissioned with the given unlimited permission. +Unlimited permission can be consumed however many times. + + +
public(friend) fun authorize_unlimited<PermKey: copy, drop, store>(master: &signer, permissioned: &signer, perm: PermKey)
+
+ + + +
+Implementation + + +
public(package) fun authorize_unlimited<PermKey: copy + drop + store>(
+    master: &signer,
+    permissioned: &signer,
+    perm: PermKey
+) acquires PermissionStorage {
+    assert!(
+        is_permissioned_signer(permissioned)
+            && !is_permissioned_signer(master)
+            && signer::address_of(master) == signer::address_of(permissioned),
+        error::permission_denied(ECANNOT_AUTHORIZE)
+    );
+    insert_or(
+        permissioned,
+        perm,
+        |stored_permission| {
+            *stored_permission = StoredPermission::Unlimited;
+        },
+        StoredPermission::Unlimited,
+    )
+}
+
+ + + +
+ + + +## Function `grant_unlimited_with_permissioned_signer` + +Grant an unlimited permission to a permissioned signer **without** master signer's approvoal. + + +
public(friend) fun grant_unlimited_with_permissioned_signer<PermKey: copy, drop, store>(permissioned: &signer, perm: PermKey)
+
+ + + +
+Implementation + + +
public(package) fun grant_unlimited_with_permissioned_signer<PermKey: copy + drop + store>(
+    permissioned: &signer,
+    perm: PermKey
+) acquires PermissionStorage {
+    if(!is_permissioned_signer(permissioned)) {
+        return;
+    };
+    insert_or(
+        permissioned,
+        perm,
+        |stored_permission| {
+            *stored_permission = StoredPermission::Unlimited;
+        },
+        StoredPermission::Unlimited,
+    )
+}
+
+ + + +
+ + + +## Function `increase_limit` + +Increase the capacity of a permissioned signer **without** master signer's approvoal. + +The caller of the module will need to make sure the witness type PermKey can only be +constructed within its own module, otherwise attackers can refill the permission for itself +to bypass the checks. + + +
public(friend) fun increase_limit<PermKey: copy, drop, store>(permissioned: &signer, capacity: u256, perm: PermKey)
+
+ + + +
+Implementation + + +
public(package) fun increase_limit<PermKey: copy + drop + store>(
+    permissioned: &signer,
+    capacity: u256,
+    perm: PermKey
+) acquires PermissionStorage {
+    if(!is_permissioned_signer(permissioned)) {
+        return;
+    };
+    insert_or(
+        permissioned,
+        perm,
+        |stored_permission| {
+            increase_capacity(stored_permission, capacity);
+        },
+        StoredPermission::Capacity(capacity),
+    )
+}
+
+ + + +
+ + + +## Function `check_permission_exists` + + + +
public(friend) fun check_permission_exists<PermKey: copy, drop, store>(s: &signer, perm: PermKey): bool
+
+ + + +
+Implementation + + +
public(package) fun check_permission_exists<PermKey: copy + drop + store>(
+    s: &signer, perm: PermKey
+): bool acquires PermissionStorage {
+    // 0 capacity permissions will be treated as non-existant.
+    check_permission_capacity_above(s, 1, perm)
+}
+
+ + + +
+ + + +## Function `check_permission_capacity_above` + + + +
public(friend) fun check_permission_capacity_above<PermKey: copy, drop, store>(s: &signer, threshold: u256, perm: PermKey): bool
+
+ + + +
+Implementation + + +
public(package) fun check_permission_capacity_above<PermKey: copy + drop + store>(
+    s: &signer, threshold: u256, perm: PermKey
+): bool acquires PermissionStorage {
+    if (!is_permissioned_signer(s)) {
+        // master signer has all permissions
+        return true
+    };
+    map_or(
+        s,
+        perm,
+        |stored_permission| {
+            is_above(stored_permission, threshold)
+        },
+        false,
+    )
+}
+
+ + + +
+ + + +## Function `check_permission_consume` + + + +
public(friend) fun check_permission_consume<PermKey: copy, drop, store>(s: &signer, threshold: u256, perm: PermKey): bool
+
+ + + +
+Implementation + + +
public(package) fun check_permission_consume<PermKey: copy + drop + store>(
+    s: &signer, threshold: u256, perm: PermKey
+): bool acquires PermissionStorage {
+    if (!is_permissioned_signer(s)) {
+        // master signer has all permissions
+        return true
+    };
+    map_or(
+        s,
+        perm,
+        |stored_permission| {
+             consume_capacity(stored_permission, threshold)
+        },
+        false,
+    )
+}
+
+ + + +
+ + + +## Function `capacity` + + + +
public(friend) fun capacity<PermKey: copy, drop, store>(s: &signer, perm: PermKey): option::Option<u256>
+
+ + + +
+Implementation + + +
public(package) fun capacity<PermKey: copy + drop + store>(
+    s: &signer, perm: PermKey
+): Option<u256> acquires PermissionStorage {
+    if (!is_permissioned_signer(s)) {
+        return option::some(U256_MAX)
+    };
+    map_or(
+        s,
+        perm,
+        |stored_permission: &mut StoredPermission| {
+            option::some(match (stored_permission) {
+                StoredPermission::Capacity(capacity) => *capacity,
+                StoredPermission::Unlimited => U256_MAX,
+            })
+        },
+        option::none(),
+    )
+}
+
+ + + +
+ + + +## Function `revoke_permission` + + + +
public(friend) fun revoke_permission<PermKey: copy, drop, store>(permissioned: &signer, perm: PermKey)
+
+ + + +
+Implementation + + +
public(package) fun revoke_permission<PermKey: copy + drop + store>(
+    permissioned: &signer, perm: PermKey
+) acquires PermissionStorage {
+    if (!is_permissioned_signer(permissioned)) {
+        // Master signer has no permissions associated with it.
+        return
+    };
+    let addr = permission_address(permissioned);
+    if (!exists<PermissionStorage>(addr)) { return };
+    let perm_storage = &mut PermissionStorage[addr].perms;
+    let key = copyable_any::pack(perm);
+    if (perm_storage.contains(&key)) {
+        perm_storage.remove(&key);
+    }
+}
+
+ + + +
+ + + +## Function `is_permissioned_signer_impl` + + +Check whether this is a permissioned signer. + + +
fun is_permissioned_signer_impl(s: &signer): bool
+
+ + + +
+Implementation + + +
native fun is_permissioned_signer_impl(s: &signer): bool;
+
+ + + +
+ + + +## Function `permission_address` + +Return the address used for storing permissions. Aborts if not a permissioned signer. + + +
fun permission_address(permissioned: &signer): address
+
+ + + +
+Implementation + + +
native fun permission_address(permissioned: &signer): address;
+
+ + + +
+ + + +## Function `signer_from_permissioned_handle_impl` + +Creates a permissioned signer from an existing universal signer. The function aborts if the +given signer is already a permissioned signer. + +The implementation of this function requires to extend the value representation for signers in the VM. +invariants: +signer::address_of(master) == signer::address_of(signer_from_permissioned_handle(create_permissioned_handle(master))), + + +
fun signer_from_permissioned_handle_impl(master_account_addr: address, permissions_storage_addr: address): signer
+
+ + + +
+Implementation + + +
native fun signer_from_permissioned_handle_impl(
+    master_account_addr: address, permissions_storage_addr: address
+): signer;
+
+ + + +
+ + + +## Specification + + + +
pragma verify = false;
+axiom forall a: GrantedPermissionHandles:
+    (
+        forall i in 0..len(a.active_handles):
+            forall j in 0..len(a.active_handles):
+                i != j ==>
+                    a.active_handles[i] != a.active_handles[j]
+    );
+
+ + + + + + + +
fun spec_is_permissioned_signer(s: signer): bool;
+
+ + + + + +### Function `create_permissioned_handle` + + +
public fun create_permissioned_handle(master: &signer): permissioned_signer::PermissionedHandle
+
+ + + + +
pragma opaque;
+aborts_if [abstract] spec_is_permissioned_signer(master);
+let permissions_storage_addr = transaction_context::spec_generate_unique_address();
+modifies global<PermissionStorage>(permissions_storage_addr);
+let master_account_addr = signer::address_of(master);
+ensures result.master_account_addr == master_account_addr;
+ensures result.permissions_storage_addr == permissions_storage_addr;
+
+ + + + + +### Function `destroy_permissioned_handle` + + +
public fun destroy_permissioned_handle(p: permissioned_signer::PermissionedHandle)
+
+ + + + +
ensures !exists<PermissionStorage>(p.permissions_storage_addr);
+
+ + + + + +### Function `is_permissioned_signer` + + +
public fun is_permissioned_signer(s: &signer): bool
+
+ + + + +
pragma opaque;
+aborts_if [abstract] false;
+ensures [abstract] result == spec_is_permissioned_signer(s);
+
+ + + + + + + +
fun spec_permission_address(s: signer): address;
+
+ + + + + +### Function `revoke_permission_storage_address` + + +
public entry fun revoke_permission_storage_address(s: &signer, permissions_storage_addr: address)
+
+ + + + + + +### Function `create_storable_permissioned_handle` + + +
public(friend) fun create_storable_permissioned_handle(master: &signer, expiration_time: u64): permissioned_signer::StorablePermissionedHandle
+
+ + + + +
pragma opaque;
+aborts_if [abstract] spec_is_permissioned_signer(master);
+let permissions_storage_addr = transaction_context::spec_generate_unique_address();
+modifies global<PermissionStorage>(permissions_storage_addr);
+let master_account_addr = signer::address_of(master);
+modifies global<GrantedPermissionHandles>(master_account_addr);
+ensures result.master_account_addr == master_account_addr;
+ensures result.permissions_storage_addr == permissions_storage_addr;
+ensures result.expiration_time == expiration_time;
+ensures vector::spec_contains(
+    global<GrantedPermissionHandles>(master_account_addr).active_handles,
+    permissions_storage_addr
+);
+ensures exists<GrantedPermissionHandles>(master_account_addr);
+
+ + + + + +### Function `destroy_storable_permissioned_handle` + + +
public(friend) fun destroy_storable_permissioned_handle(p: permissioned_signer::StorablePermissionedHandle)
+
+ + + + +
ensures !exists<PermissionStorage>(p.permissions_storage_addr);
+let post granted_permissions = global<GrantedPermissionHandles>(
+    p.master_account_addr
+);
+
+ + + + + +### Function `authorize_increase` + + +
public(friend) fun authorize_increase<PermKey: copy, drop, store>(master: &signer, permissioned: &signer, capacity: u256, perm: PermKey)
+
+ + + + +
pragma aborts_if_is_partial;
+aborts_if !spec_is_permissioned_signer(permissioned);
+aborts_if spec_is_permissioned_signer(master);
+aborts_if signer::address_of(permissioned) != signer::address_of(master);
+ensures exists<PermissionStorage>(
+    spec_permission_address(permissioned)
+);
+
+ + + + + +### Function `check_permission_exists` + + +
public(friend) fun check_permission_exists<PermKey: copy, drop, store>(s: &signer, perm: PermKey): bool
+
+ + + + +
pragma verify = false;
+
+ + + + + + + +
fun spec_check_permission_exists<PermKey: copy + drop + store>(s: signer, perm: PermKey): bool {
+   use aptos_std::type_info;
+   use std::bcs;
+   let addr = spec_permission_address(s);
+   let key = Any {
+       type_name: type_info::type_name<PermKey>(),
+       data: bcs::serialize(perm)
+   };
+   if (!spec_is_permissioned_signer(s)) { true }
+   else if (!exists<PermissionStorage>(addr)) { false }
+   else {
+       // ordered_map::spec_contains_key(global<PermissionStorage>(addr).perms, key)
+       // FIXME: ordered map spec doesn't exist yet.
+       true
+   }
+}
+
+ + + + + +### Function `check_permission_capacity_above` + + +
public(friend) fun check_permission_capacity_above<PermKey: copy, drop, store>(s: &signer, threshold: u256, perm: PermKey): bool
+
+ + + + +
let permissioned_signer_addr = spec_permission_address(s);
+ensures !spec_is_permissioned_signer(s) ==> result == true;
+ensures (
+    spec_is_permissioned_signer(s)
+        && !exists<PermissionStorage>(permissioned_signer_addr)
+) ==> result == false;
+
+ + + + + +### Function `check_permission_consume` + + +
public(friend) fun check_permission_consume<PermKey: copy, drop, store>(s: &signer, threshold: u256, perm: PermKey): bool
+
+ + + + +
let permissioned_signer_addr = spec_permission_address(s);
+ensures !spec_is_permissioned_signer(s) ==> result == true;
+ensures (
+    spec_is_permissioned_signer(s)
+        && !exists<PermissionStorage>(permissioned_signer_addr)
+) ==> result == false;
+
+ + + + + +### Function `capacity` + + +
public(friend) fun capacity<PermKey: copy, drop, store>(s: &signer, perm: PermKey): option::Option<u256>
+
+ + + + + + +### Function `permission_address` + + +
fun permission_address(permissioned: &signer): address
+
+ + + + +
pragma opaque;
+aborts_if [abstract]!spec_is_permissioned_signer(permissioned);
+ensures [abstract] result == spec_permission_address(permissioned);
+
+ + + + + + + +
fun spec_signer_from_permissioned_handle_impl(
+   master_account_addr: address, permissions_storage_addr: address
+): signer;
+
+ + + + + +### Function `signer_from_permissioned_handle_impl` + + +
fun signer_from_permissioned_handle_impl(master_account_addr: address, permissions_storage_addr: address): signer
+
+ + + + +
pragma opaque;
+ensures [abstract] result
+    == spec_signer_from_permissioned_handle_impl(
+        master_account_addr, permissions_storage_addr
+    );
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/primary_fungible_store.md b/aptos-move/framework/aptos-framework/doc/primary_fungible_store.md index 524024ea69f17..fdc63ca6edf5a 100644 --- a/aptos-move/framework/aptos-framework/doc/primary_fungible_store.md +++ b/aptos-move/framework/aptos-framework/doc/primary_fungible_store.md @@ -28,11 +28,14 @@ fungible asset to it. This emits an deposit event. - [Function `primary_store_address_inlined`](#0x1_primary_fungible_store_primary_store_address_inlined) - [Function `primary_store_inlined`](#0x1_primary_fungible_store_primary_store_inlined) - [Function `primary_store_exists_inlined`](#0x1_primary_fungible_store_primary_store_exists_inlined) +- [Function `grant_permission`](#0x1_primary_fungible_store_grant_permission) +- [Function `grant_apt_permission`](#0x1_primary_fungible_store_grant_apt_permission) - [Function `balance`](#0x1_primary_fungible_store_balance) - [Function `is_balance_at_least`](#0x1_primary_fungible_store_is_balance_at_least) - [Function `is_frozen`](#0x1_primary_fungible_store_is_frozen) - [Function `withdraw`](#0x1_primary_fungible_store_withdraw) - [Function `deposit`](#0x1_primary_fungible_store_deposit) +- [Function `deposit_with_signer`](#0x1_primary_fungible_store_deposit_with_signer) - [Function `force_deposit`](#0x1_primary_fungible_store_force_deposit) - [Function `transfer`](#0x1_primary_fungible_store_transfer) - [Function `transfer_assert_minimum_deposit`](#0x1_primary_fungible_store_transfer_assert_minimum_deposit) @@ -363,6 +366,73 @@ Use instead of the corresponding view functions for dispatchable hooks to avoid + + + + +## Function `grant_permission` + + + +
public fun grant_permission<T: key>(master: &signer, permissioned: &signer, metadata: object::Object<T>, amount: u64)
+
+ + + +
+Implementation + + +
public fun grant_permission<T: key>(
+    master: &signer,
+    permissioned: &signer,
+    metadata: Object<T>,
+    amount: u64
+) {
+    fungible_asset::grant_permission_by_address(
+        master,
+        permissioned,
+        primary_store_address_inlined(signer::address_of(permissioned), metadata),
+        amount
+    );
+}
+
+ + + +
+ + + +## Function `grant_apt_permission` + + + +
public fun grant_apt_permission(master: &signer, permissioned: &signer, amount: u64)
+
+ + + +
+Implementation + + +
public fun grant_apt_permission(
+    master: &signer,
+    permissioned: &signer,
+    amount: u64
+) {
+    fungible_asset::grant_permission_by_address(
+        master,
+        permissioned,
+        object::create_user_derived_object_address(signer::address_of(permissioned), @aptos_fungible_asset),
+        amount
+    );
+}
+
+ + +
@@ -507,6 +577,44 @@ Deposit fungible asset fa to the given account's primary store. + + + + +## Function `deposit_with_signer` + +Deposit fungible asset fa to the given account's primary store using signer. + +If owner is a permissioned signer, the signer will be granted with permission to withdraw +the same amount of fund in the future. + + +
public fun deposit_with_signer(owner: &signer, fa: fungible_asset::FungibleAsset)
+
+ + + +
+Implementation + + +
public fun deposit_with_signer(owner: &signer, fa: FungibleAsset) acquires DeriveRefPod {
+    fungible_asset::refill_permission(
+        owner,
+        fungible_asset::amount(&fa),
+        primary_store_address_inlined(
+            signer::address_of(owner),
+            fungible_asset::metadata_from_asset(&fa),
+        )
+    );
+    let metadata = fungible_asset::asset_metadata(&fa);
+    let store = ensure_primary_store_exists(signer::address_of(owner), metadata);
+    dispatchable_fungible_asset::deposit(store, fa);
+}
+
+ + +
diff --git a/aptos-move/framework/aptos-framework/doc/resource_account.md b/aptos-move/framework/aptos-framework/doc/resource_account.md index 318d15a785de7..95e3d0ec197ab 100644 --- a/aptos-move/framework/aptos-framework/doc/resource_account.md +++ b/aptos-move/framework/aptos-framework/doc/resource_account.md @@ -468,7 +468,7 @@ the SignerCapability.
pragma verify = true;
-pragma aborts_if_is_strict;
+pragma aborts_if_is_partial;
 
@@ -486,6 +486,7 @@ the SignerCapability.
let source_addr = signer::address_of(origin);
 let resource_addr = account::spec_create_resource_address(source_addr, seed);
+let resource = create_signer::spec_create_signer(resource_addr);
 include RotateAccountAuthenticationKeyAndStoreCapabilityAbortsIfWithoutAccountLimit;
 
@@ -547,7 +548,8 @@ the SignerCapability. -
let resource_addr = signer::address_of(resource);
+
pragma aborts_if_is_partial;
+let resource_addr = signer::address_of(resource);
 // This enforces high-level requirement 1:
 include RotateAccountAuthenticationKeyAndStoreCapabilityAbortsIf;
 // This enforces high-level requirement 2:
@@ -618,7 +620,8 @@ the SignerCapability.
 
 
 
-
// This enforces high-level requirement 6:
+
pragma aborts_if_is_partial;
+// This enforces high-level requirement 6:
 aborts_if !exists<Container>(source_addr);
 let resource_addr = signer::address_of(resource);
 let container = global<Container>(source_addr);
diff --git a/aptos-move/framework/aptos-framework/doc/signing_data.md b/aptos-move/framework/aptos-framework/doc/signing_data.md
new file mode 100644
index 0000000000000..2288c9d4ac9cf
--- /dev/null
+++ b/aptos-move/framework/aptos-framework/doc/signing_data.md
@@ -0,0 +1,111 @@
+
+
+
+# Module `0x1::signing_data`
+
+
+
+-  [Enum `SigningData`](#0x1_signing_data_SigningData)
+-  [Function `digest`](#0x1_signing_data_digest)
+-  [Function `authenticator`](#0x1_signing_data_authenticator)
+
+
+
+ + + + + +## Enum `SigningData` + + + +
enum SigningData has copy, drop
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+digest: vector<u8> +
+
+ +
+
+authenticator: vector<u8> +
+
+ +
+
+ + +
+ +
+ +
+ + + +## Function `digest` + + + +
public fun digest(signing_data: &signing_data::SigningData): &vector<u8>
+
+ + + +
+Implementation + + +
public fun digest(signing_data: &SigningData): &vector<u8> {
+    &signing_data.digest
+}
+
+ + + +
+ + + +## Function `authenticator` + + + +
public fun authenticator(signing_data: &signing_data::SigningData): &vector<u8>
+
+ + + +
+Implementation + + +
public fun authenticator(signing_data: &SigningData): &vector<u8> {
+    &signing_data.authenticator
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/stake.md b/aptos-move/framework/aptos-framework/doc/stake.md index dedfe15027641..564db5d3f1434 100644 --- a/aptos-move/framework/aptos-framework/doc/stake.md +++ b/aptos-move/framework/aptos-framework/doc/stake.md @@ -33,6 +33,7 @@ or if their stake drops below the min required, they would get removed at the en - [Struct `IndividualValidatorPerformance`](#0x1_stake_IndividualValidatorPerformance) - [Resource `ValidatorPerformance`](#0x1_stake_ValidatorPerformance) - [Struct `RegisterValidatorCandidateEvent`](#0x1_stake_RegisterValidatorCandidateEvent) +- [Struct `StakeManagementPermission`](#0x1_stake_StakeManagementPermission) - [Struct `RegisterValidatorCandidate`](#0x1_stake_RegisterValidatorCandidate) - [Struct `SetOperatorEvent`](#0x1_stake_SetOperatorEvent) - [Struct `SetOperator`](#0x1_stake_SetOperator) @@ -63,6 +64,8 @@ or if their stake drops below the min required, they would get removed at the en - [Resource `Ghost$ghost_active_num`](#0x1_stake_Ghost$ghost_active_num) - [Resource `Ghost$ghost_pending_inactive_num`](#0x1_stake_Ghost$ghost_pending_inactive_num) - [Constants](#@Constants_0) +- [Function `check_stake_permission`](#0x1_stake_check_stake_permission) +- [Function `grant_permission`](#0x1_stake_grant_permission) - [Function `get_lockup_secs`](#0x1_stake_get_lockup_secs) - [Function `get_remaining_lockup_secs`](#0x1_stake_get_remaining_lockup_secs) - [Function `get_stake`](#0x1_stake_get_stake) @@ -175,6 +178,7 @@ or if their stake drops below the min required, they would get removed at the en use 0x1::fixed_point64; use 0x1::math64; use 0x1::option; +use 0x1::permissioned_signer; use 0x1::reconfiguration_state; use 0x1::signer; use 0x1::staking_config; @@ -624,6 +628,33 @@ This allows the Stake module to mint rewards to stakers.
+ + + + +## Struct `StakeManagementPermission` + + + +
struct StakeManagementPermission has copy, drop, store
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ +
@@ -1730,6 +1761,16 @@ Validators cannot join or leave post genesis on this test network. + + +Signer does not have permission to perform stake logic. + + +
const ENO_STAKE_PERMISSION: u64 = 28;
+
+ + + An account cannot own more than one owner capability. @@ -1878,6 +1919,59 @@ Validator status enum. We can switch to proper enum later once Move supports it. + + +## Function `check_stake_permission` + +Permissions + + +
fun check_stake_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_stake_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, StakeManagementPermission {}),
+        error::permission_denied(ENO_STAKE_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_permission` + +Grant permission to mutate staking on behalf of the master signer. + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, StakeManagementPermission {})
+}
+
+ + + +
+ ## Function `get_lockup_secs` @@ -2385,6 +2479,7 @@ to set later. operator: address, voter: address, ) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet { + check_stake_permission(owner); initialize_owner(owner); move_to(owner, ValidatorConfig { consensus_pubkey: vector::empty(), @@ -2434,6 +2529,7 @@ Initialize the validator account and give ownership to the signing account. network_addresses: vector<u8>, fullnode_addresses: vector<u8>, ) acquires AllowedValidators { + check_stake_permission(account); // Checks the public key has a valid proof-of-possession to prevent rogue-key attacks. let pubkey_from_pop = &bls12381::public_key_from_bytes_with_pop( consensus_pubkey, @@ -2471,6 +2567,7 @@ Initialize the validator account and give ownership to the signing account.
fun initialize_owner(owner: &signer) acquires AllowedValidators {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert!(is_allowed(owner_address), error::not_found(EINELIGIBLE_VALIDATOR));
     assert!(!stake_pool_exists(owner_address), error::already_exists(EALREADY_REGISTERED));
@@ -2525,6 +2622,7 @@ Extract and return owner capability from the signing account.
 
 
 
public fun extract_owner_cap(owner: &signer): OwnerCapability acquires OwnerCapability {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     move_from<OwnerCapability>(owner_address)
@@ -2553,6 +2651,7 @@ staking pool.
 
 
 
public fun deposit_owner_cap(owner: &signer, owner_cap: OwnerCapability) {
+    check_stake_permission(owner);
     assert!(!exists<OwnerCapability>(signer::address_of(owner)), error::not_found(EOWNER_CAP_ALREADY_EXISTS));
     move_to(owner, owner_cap);
 }
@@ -2604,6 +2703,7 @@ Allows an owner to change the operator of the stake pool.
 
 
 
public entry fun set_operator(owner: &signer, new_operator: address) acquires OwnerCapability, StakePool {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -2680,6 +2780,7 @@ Allows an owner to change the delegated voter of the stake pool.
 
 
 
public entry fun set_delegated_voter(owner: &signer, new_voter: address) acquires OwnerCapability, StakePool {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -2736,6 +2837,7 @@ Add amount of coins from the public entry fun add_stake(owner: &signer, amount: u64) acquires OwnerCapability, StakePool, ValidatorSet {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -2837,6 +2939,7 @@ Move amount of coins from pending_inactive to active.
 
 
 
public entry fun reactivate_stake(owner: &signer, amount: u64) acquires OwnerCapability, StakePool {
+    check_stake_permission(owner);
     assert_reconfig_not_in_progress();
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
@@ -2925,6 +3028,7 @@ Rotate the consensus key of the validator, it'll take effect in next epoch.
     new_consensus_pubkey: vector<u8>,
     proof_of_possession: vector<u8>,
 ) acquires StakePool, ValidatorConfig {
+    check_stake_permission(operator);
     assert_reconfig_not_in_progress();
     assert_stake_pool_exists(pool_address);
 
@@ -2989,6 +3093,7 @@ Update the network and full node addresses of the validator. This only takes eff
     new_network_addresses: vector<u8>,
     new_fullnode_addresses: vector<u8>,
 ) acquires StakePool, ValidatorConfig {
+    check_stake_permission(operator);
     assert_reconfig_not_in_progress();
     assert_stake_pool_exists(pool_address);
     let stake_pool = borrow_global_mut<StakePool>(pool_address);
@@ -3046,6 +3151,7 @@ Similar to increase_lockup_with_cap but will use ownership capability from the s
 
 
 
public entry fun increase_lockup(owner: &signer) acquires OwnerCapability, StakePool {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -3130,6 +3236,7 @@ This can only called by the operator of the validator/staking pool.
     operator: &signer,
     pool_address: address
 ) acquires StakePool, ValidatorConfig, ValidatorSet {
+    check_stake_permission(operator);
     assert!(
         staking_config::get_allow_validator_set_change(&staking_config::get()),
         error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED),
@@ -3233,6 +3340,7 @@ Similar to unlock_with_cap but will use ownership capability from the signing ac
 
 
 
public entry fun unlock(owner: &signer, amount: u64) acquires OwnerCapability, StakePool {
+    check_stake_permission(owner);
     assert_reconfig_not_in_progress();
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
@@ -3321,6 +3429,7 @@ Withdraw from account's inacti
     owner: &signer,
     withdraw_amount: u64
 ) acquires OwnerCapability, StakePool, ValidatorSet {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -3420,6 +3529,7 @@ Can only be called by the operator of the validator/staking pool.
     operator: &signer,
     pool_address: address
 ) acquires StakePool, ValidatorSet {
+    check_stake_permission(operator);
     assert_reconfig_not_in_progress();
     let config = staking_config::get();
     assert!(
@@ -4546,6 +4656,7 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
pragma verify = true;
+pragma aborts_if_is_partial;
 invariant [suspendable] exists<ValidatorSet>(@aptos_framework) ==> validator_set_is_valid();
 invariant [suspendable] chain_status::is_operating() ==> exists<AptosCoinCapabilities>(@aptos_framework);
 invariant [suspendable] chain_status::is_operating() ==> exists<ValidatorPerformance>(@aptos_framework);
@@ -4565,6 +4676,115 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
+
+
+
+
+
fun spec_rewards_amount(
+   stake_amount: u64,
+   num_successful_proposals: u64,
+   num_total_proposals: u64,
+   rewards_rate: u64,
+   rewards_rate_denominator: u64,
+): u64;
+
+ + + + + + + +
fun spec_contains(validators: vector<ValidatorInfo>, addr: address): bool {
+   exists i in 0..len(validators): validators[i].addr == addr
+}
+
+ + + + + + + +
fun spec_is_current_epoch_validator(pool_address: address): bool {
+   let validator_set = global<ValidatorSet>(@aptos_framework);
+   !spec_contains(validator_set.pending_active, pool_address)
+       && (spec_contains(validator_set.active_validators, pool_address)
+       || spec_contains(validator_set.pending_inactive, pool_address))
+}
+
+ + + + + + + +
schema ResourceRequirement {
+    requires exists<AptosCoinCapabilities>(@aptos_framework);
+    requires exists<ValidatorPerformance>(@aptos_framework);
+    requires exists<ValidatorSet>(@aptos_framework);
+    requires exists<StakingConfig>(@aptos_framework);
+    requires exists<StakingRewardsConfig>(@aptos_framework) || !features::spec_periodical_reward_rate_decrease_enabled();
+    requires exists<timestamp::CurrentTimeMicroseconds>(@aptos_framework);
+}
+
+ + + + + + + +
fun spec_get_reward_rate_1(config: StakingConfig): num {
+   if (features::spec_periodical_reward_rate_decrease_enabled()) {
+       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@aptos_framework).rewards_rate;
+       if (epoch_rewards_rate.value == 0) {
+           0
+       } else {
+           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
+           let denominator = if (denominator_0 > MAX_U64) {
+               MAX_U64
+           } else {
+               denominator_0
+           };
+           let nominator = aptos_std::fixed_point64::spec_multiply_u128(denominator, epoch_rewards_rate);
+           nominator
+       }
+   } else {
+           config.rewards_rate
+   }
+}
+
+ + + + + + + +
fun spec_get_reward_rate_2(config: StakingConfig): num {
+   if (features::spec_periodical_reward_rate_decrease_enabled()) {
+       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@aptos_framework).rewards_rate;
+       if (epoch_rewards_rate.value == 0) {
+           1
+       } else {
+           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
+           let denominator = if (denominator_0 > MAX_U64) {
+               MAX_U64
+           } else {
+               denominator_0
+           };
+           denominator
+       }
+   } else {
+           config.rewards_rate_denominator
+   }
+}
+
+ + + ### Resource `ValidatorSet` @@ -4792,6 +5012,11 @@ Returns validator's next epoch voting power, including pending_active, active, a
pragma verify_duration_estimate = 120;
+pragma verify = false;
+pragma aborts_if_is_partial;
+include AbortsIfSignerPermissionStake {
+    s: owner
+};
 include ResourceRequirement;
 let addr = signer::address_of(owner);
 ensures global<ValidatorConfig>(addr) == ValidatorConfig {
@@ -4823,7 +5048,11 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
let pubkey_from_pop = bls12381::spec_public_key_from_bytes_with_pop(
+
pragma verify = false;
+include AbortsIfSignerPermissionStake {
+    s: account
+};
+let pubkey_from_pop = bls12381::spec_public_key_from_bytes_with_pop(
     consensus_pubkey,
     proof_of_possession_from_bytes(proof_of_possession)
 );
@@ -4862,6 +5091,9 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
pragma verify_duration_estimate = 300;
+include AbortsIfSignerPermissionStake {
+    s: owner
+};
 let owner_address = signer::address_of(owner);
 aborts_if !exists<OwnerCapability>(owner_address);
 ensures !exists<OwnerCapability>(owner_address);
@@ -4880,7 +5112,10 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
let owner_address = signer::address_of(owner);
+
include AbortsIfSignerPermissionStake {
+    s: owner
+};
+let owner_address = signer::address_of(owner);
 aborts_if exists<OwnerCapability>(owner_address);
 ensures exists<OwnerCapability>(owner_address);
 ensures global<OwnerCapability>(owner_address) == owner_cap;
@@ -4940,8 +5175,11 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
pragma verify_duration_estimate = 120;
+
pragma verify = false;
 pragma aborts_if_is_partial;
+include AbortsIfSignerPermissionStake {
+    s: owner
+};
 aborts_if reconfiguration_state::spec_is_in_progress();
 include ResourceRequirement;
 include AddStakeAbortsIfAndEnsures;
@@ -4961,7 +5199,7 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
pragma disable_invariants_in_body;
-pragma verify_duration_estimate = 300;
+pragma verify = false;
 include ResourceRequirement;
 let amount = coins.value;
 aborts_if reconfiguration_state::spec_is_in_progress();
@@ -5006,7 +5244,10 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
let pre_stake_pool = global<StakePool>(pool_address);
+
include AbortsIfSignerPermissionStake {
+    s: operator
+};
+let pre_stake_pool = global<StakePool>(pool_address);
 let post validator_info = global<ValidatorConfig>(pool_address);
 aborts_if reconfiguration_state::spec_is_in_progress();
 aborts_if !exists<StakePool>(pool_address);
@@ -5035,7 +5276,10 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
let pre_stake_pool = global<StakePool>(pool_address);
+
include AbortsIfSignerPermissionStake {
+    s: operator
+};
+let pre_stake_pool = global<StakePool>(pool_address);
 let post validator_info = global<ValidatorConfig>(pool_address);
 modifies global<ValidatorConfig>(pool_address);
 include StakedValueNochange;
@@ -5091,6 +5335,9 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
pragma verify_duration_estimate = 60;
 pragma disable_invariants_in_body;
+include AbortsIfSignerPermissionStake {
+    s: operator
+};
 aborts_if !staking_config::get_allow_validator_set_change(staking_config::get());
 aborts_if !exists<StakePool>(pool_address);
 aborts_if !exists<ValidatorConfig>(pool_address);
@@ -5168,6 +5415,9 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
pragma verify = false;
+include AbortsIfSignerPermissionStake {
+    s: owner
+};
 aborts_if reconfiguration_state::spec_is_in_progress();
 let addr = signer::address_of(owner);
 let ownership_cap = global<OwnerCapability>(addr);
@@ -5214,6 +5464,9 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
pragma disable_invariants_in_body;
 requires chain_status::is_operating();
+include AbortsIfSignerPermissionStake {
+    s: operator
+};
 aborts_if reconfiguration_state::spec_is_in_progress();
 let config = staking_config::get();
 aborts_if !staking_config::get_allow_validator_set_change(config);
@@ -5400,6 +5653,19 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
+
+
+
+
schema AbortsIfSignerPermissionStake {
+    s: signer;
+    let perm = StakeManagementPermission {};
+    aborts_if !permissioned_signer::spec_check_permission_exists(s, perm);
+}
+
+ + + + @@ -5485,6 +5751,7 @@ Returns validator's next epoch voting power, including pending_active, active, a
pragma opaque;
 pragma verify_duration_estimate = 300;
+pragma verify = false;
 requires rewards_rate <= MAX_REWARDS_RATE;
 requires rewards_rate_denominator > 0;
 requires rewards_rate <= rewards_rate_denominator;
@@ -5517,7 +5784,8 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
include ResourceRequirement;
+
pragma aborts_if_is_partial;
+include ResourceRequirement;
 requires rewards_rate <= MAX_REWARDS_RATE;
 requires rewards_rate_denominator > 0;
 requires rewards_rate <= rewards_rate_denominator;
diff --git a/aptos-move/framework/aptos-framework/doc/staking_contract.md b/aptos-move/framework/aptos-framework/doc/staking_contract.md
index 09ecf20686f86..43d969b13b988 100644
--- a/aptos-move/framework/aptos-framework/doc/staking_contract.md
+++ b/aptos-move/framework/aptos-framework/doc/staking_contract.md
@@ -99,6 +99,7 @@ pool.
     -  [Function `pending_distribution_counts`](#@Specification_1_pending_distribution_counts)
     -  [Function `staking_contract_exists`](#@Specification_1_staking_contract_exists)
     -  [Function `beneficiary_for_operator`](#@Specification_1_beneficiary_for_operator)
+    -  [Function `get_expected_stake_pool_address`](#@Specification_1_get_expected_stake_pool_address)
     -  [Function `create_staking_contract`](#@Specification_1_create_staking_contract)
     -  [Function `create_staking_contract_with_coins`](#@Specification_1_create_staking_contract_with_coins)
     -  [Function `add_stake`](#@Specification_1_add_stake)
@@ -2958,35 +2959,52 @@ Staking_contract exists the stacker/operator pair.
 
 
 
+
 
-
+### Function `beneficiary_for_operator`
 
 
-
fun spec_staking_contract_exists(staker: address, operator: address): bool {
-   if (!exists<Store>(staker)) {
-       false
-   } else {
-       let store = global<Store>(staker);
-       simple_map::spec_contains_key(store.staking_contracts, operator)
-   }
-}
+
#[view]
+public fun beneficiary_for_operator(operator: address): address
 
- -### Function `beneficiary_for_operator` +
pragma verify = false;
+
+ + + + + +### Function `get_expected_stake_pool_address`
#[view]
-public fun beneficiary_for_operator(operator: address): address
+public fun get_expected_stake_pool_address(staker: address, operator: address, contract_creation_seed: vector<u8>): address
 
-
pragma verify = false;
+
pragma aborts_if_is_partial;
+
+ + + + + + + +
fun spec_staking_contract_exists(staker: address, operator: address): bool {
+   if (!exists<Store>(staker)) {
+       false
+   } else {
+       let store = global<Store>(staker);
+       simple_map::spec_contains_key(store.staking_contracts, operator)
+   }
+}
 
diff --git a/aptos-move/framework/aptos-framework/doc/staking_proxy.md b/aptos-move/framework/aptos-framework/doc/staking_proxy.md index c05adb7f26803..2a2f4577aa04d 100644 --- a/aptos-move/framework/aptos-framework/doc/staking_proxy.md +++ b/aptos-move/framework/aptos-framework/doc/staking_proxy.md @@ -5,6 +5,10 @@ +- [Struct `StakeProxyPermission`](#0x1_staking_proxy_StakeProxyPermission) +- [Constants](#@Constants_0) +- [Function `check_stake_proxy_permission`](#0x1_staking_proxy_check_stake_proxy_permission) +- [Function `grant_permission`](#0x1_staking_proxy_grant_permission) - [Function `set_operator`](#0x1_staking_proxy_set_operator) - [Function `set_voter`](#0x1_staking_proxy_set_voter) - [Function `set_vesting_contract_operator`](#0x1_staking_proxy_set_vesting_contract_operator) @@ -13,20 +17,23 @@ - [Function `set_vesting_contract_voter`](#0x1_staking_proxy_set_vesting_contract_voter) - [Function `set_staking_contract_voter`](#0x1_staking_proxy_set_staking_contract_voter) - [Function `set_stake_pool_voter`](#0x1_staking_proxy_set_stake_pool_voter) -- [Specification](#@Specification_0) +- [Specification](#@Specification_1) - [High-level Requirements](#high-level-req) - [Module-level Specification](#module-level-spec) - - [Function `set_operator`](#@Specification_0_set_operator) - - [Function `set_voter`](#@Specification_0_set_voter) - - [Function `set_vesting_contract_operator`](#@Specification_0_set_vesting_contract_operator) - - [Function `set_staking_contract_operator`](#@Specification_0_set_staking_contract_operator) - - [Function `set_stake_pool_operator`](#@Specification_0_set_stake_pool_operator) - - [Function `set_vesting_contract_voter`](#@Specification_0_set_vesting_contract_voter) - - [Function `set_staking_contract_voter`](#@Specification_0_set_staking_contract_voter) - - [Function `set_stake_pool_voter`](#@Specification_0_set_stake_pool_voter) - - -
use 0x1::signer;
+    -  [Function `grant_permission`](#@Specification_1_grant_permission)
+    -  [Function `set_operator`](#@Specification_1_set_operator)
+    -  [Function `set_voter`](#@Specification_1_set_voter)
+    -  [Function `set_vesting_contract_operator`](#@Specification_1_set_vesting_contract_operator)
+    -  [Function `set_staking_contract_operator`](#@Specification_1_set_staking_contract_operator)
+    -  [Function `set_stake_pool_operator`](#@Specification_1_set_stake_pool_operator)
+    -  [Function `set_vesting_contract_voter`](#@Specification_1_set_vesting_contract_voter)
+    -  [Function `set_staking_contract_voter`](#@Specification_1_set_staking_contract_voter)
+    -  [Function `set_stake_pool_voter`](#@Specification_1_set_stake_pool_voter)
+
+
+
use 0x1::error;
+use 0x1::permissioned_signer;
+use 0x1::signer;
 use 0x1::stake;
 use 0x1::staking_contract;
 use 0x1::vesting;
@@ -34,6 +41,101 @@
 
 
 
+
+
+## Struct `StakeProxyPermission`
+
+
+
+
struct StakeProxyPermission has copy, drop, store
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Constants + + + + +Signer does not have permission to perform stake proxy logic. + + +
const ENO_STAKE_PERMISSION: u64 = 28;
+
+ + + + + +## Function `check_stake_proxy_permission` + +Permissions + + +
fun check_stake_proxy_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_stake_proxy_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, StakeProxyPermission {}),
+        error::permission_denied(ENO_STAKE_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_permission` + +Grant permission to mutate staking on behalf of the master signer. + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, StakeProxyPermission {})
+}
+
+ + + +
+ ## Function `set_operator` @@ -102,6 +204,7 @@
public entry fun set_vesting_contract_operator(owner: &signer, old_operator: address, new_operator: address) {
+    check_stake_proxy_permission(owner);
     let owner_address = signer::address_of(owner);
     let vesting_contracts = &vesting::vesting_contracts(owner_address);
     vector::for_each_ref(vesting_contracts, |vesting_contract| {
@@ -134,6 +237,7 @@
 
 
 
public entry fun set_staking_contract_operator(owner: &signer, old_operator: address, new_operator: address) {
+    check_stake_proxy_permission(owner);
     let owner_address = signer::address_of(owner);
     if (staking_contract::staking_contract_exists(owner_address, old_operator)) {
         let current_commission_percentage = staking_contract::commission_percentage(owner_address, old_operator);
@@ -162,6 +266,7 @@
 
 
 
public entry fun set_stake_pool_operator(owner: &signer, new_operator: address) {
+    check_stake_proxy_permission(owner);
     let owner_address = signer::address_of(owner);
     if (stake::stake_pool_exists(owner_address)) {
         stake::set_operator(owner, new_operator);
@@ -189,6 +294,7 @@
 
 
 
public entry fun set_vesting_contract_voter(owner: &signer, operator: address, new_voter: address) {
+    check_stake_proxy_permission(owner);
     let owner_address = signer::address_of(owner);
     let vesting_contracts = &vesting::vesting_contracts(owner_address);
     vector::for_each_ref(vesting_contracts, |vesting_contract| {
@@ -220,6 +326,7 @@
 
 
 
public entry fun set_staking_contract_voter(owner: &signer, operator: address, new_voter: address) {
+    check_stake_proxy_permission(owner);
     let owner_address = signer::address_of(owner);
     if (staking_contract::staking_contract_exists(owner_address, operator)) {
         staking_contract::update_voter(owner, operator, new_voter);
@@ -247,6 +354,7 @@
 
 
 
public entry fun set_stake_pool_voter(owner: &signer, new_voter: address) {
+    check_stake_proxy_permission(owner);
     if (stake::stake_pool_exists(signer::address_of(owner))) {
         stake::set_delegated_voter(owner, new_voter);
     };
@@ -257,7 +365,7 @@
 
 
 
-
+
 
 ## Specification
 
@@ -324,12 +432,31 @@
 
 
 
pragma verify = true;
-pragma aborts_if_is_strict;
+pragma aborts_if_is_partial;
 
- + + +### Function `grant_permission` + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer)
+
+ + + + +
pragma aborts_if_is_partial;
+aborts_if !permissioned_signer::spec_is_permissioned_signer(permissioned_signer);
+aborts_if permissioned_signer::spec_is_permissioned_signer(master);
+aborts_if signer::address_of(master) != signer::address_of(permissioned_signer);
+
+ + + + ### Function `set_operator` @@ -349,7 +476,7 @@ Aborts if conditions of SetStakePoolOperator are not met - + ### Function `set_voter` @@ -362,13 +489,14 @@ Aborts if conditions of SetStackingContractVoter and SetStackPoolVoterAbortsIf a
pragma aborts_if_is_partial;
+pragma verify_duration_estimate = 120;
 include SetStakingContractVoter;
 include SetStakePoolVoterAbortsIf;
 
- + ### Function `set_vesting_contract_operator` @@ -384,7 +512,7 @@ Aborts if conditions of SetStackingContractVoter and SetStackPoolVoterAbortsIf a - + ### Function `set_staking_contract_operator` @@ -438,7 +566,7 @@ Aborts if conditions of SetStackingContractVoter and SetStackPoolVoterAbortsIf a - + ### Function `set_stake_pool_operator` @@ -452,6 +580,12 @@ One of them are not exists
include SetStakePoolOperator;
+include AbortsIfSignerPermissionStakeProxy {
+    s: owner
+};
+include exists<stake::StakePool>(signer::address_of(owner)) ==> stake::AbortsIfSignerPermissionStake {
+    s:owner
+};
 
@@ -463,6 +597,9 @@ One of them are not exists
schema SetStakePoolOperator {
     owner: &signer;
     new_operator: address;
+    include AbortsIfSignerPermissionStakeProxy {
+        s: owner
+    };
     let owner_address = signer::address_of(owner);
     let ownership_cap = borrow_global<stake::OwnerCapability>(owner_address);
     let pool_address = ownership_cap.pool_address;
@@ -473,7 +610,7 @@ One of them are not exists
 
 
 
-
+
 
 ### Function `set_vesting_contract_voter`
 
@@ -489,7 +626,7 @@ One of them are not exists
 
 
 
-
+
 
 ### Function `set_staking_contract_voter`
 
@@ -501,6 +638,9 @@ One of them are not exists
 
 
 
include SetStakingContractVoter;
+include AbortsIfSignerPermissionStakeProxy {
+    s: owner
+};
 
@@ -531,7 +671,7 @@ Then abort if the resource is not exist - + ### Function `set_stake_pool_voter` @@ -543,6 +683,12 @@ Then abort if the resource is not exist
include SetStakePoolVoterAbortsIf;
+include AbortsIfSignerPermissionStakeProxy {
+    s: owner
+};
+include exists<stake::StakePool>(signer::address_of(owner)) ==> stake::AbortsIfSignerPermissionStake {
+    s:owner
+};
 
@@ -554,6 +700,9 @@ Then abort if the resource is not exist
schema SetStakePoolVoterAbortsIf {
     owner: &signer;
     new_voter: address;
+    include AbortsIfSignerPermissionStakeProxy {
+        s: owner
+    };
     let owner_address = signer::address_of(owner);
     let ownership_cap = global<stake::OwnerCapability>(owner_address);
     let pool_address = ownership_cap.pool_address;
@@ -563,4 +712,17 @@ Then abort if the resource is not exist
 
+ + + + + +
schema AbortsIfSignerPermissionStakeProxy {
+    s: signer;
+    let perm = StakeProxyPermission {};
+    aborts_if !permissioned_signer::spec_check_permission_exists(s, perm);
+}
+
+ + [move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/transaction_context.md b/aptos-move/framework/aptos-framework/doc/transaction_context.md index cc7d9010ffc74..d4dbf2d635811 100644 --- a/aptos-move/framework/aptos-framework/doc/transaction_context.md +++ b/aptos-move/framework/aptos-framework/doc/transaction_context.md @@ -1029,6 +1029,7 @@ Returns the inner entry function payload of the multisig payload.
pragma opaque;
+aborts_if [abstract] false;
 ensures [abstract] result == spec_generate_unique_address();
 
@@ -1055,6 +1056,7 @@ Returns the inner entry function payload of the multisig payload.
pragma opaque;
+aborts_if [abstract] false;
 // This enforces high-level requirement 3:
 ensures [abstract] result == spec_generate_unique_address();
 
diff --git a/aptos-move/framework/aptos-framework/doc/transaction_validation.md b/aptos-move/framework/aptos-framework/doc/transaction_validation.md index c126406ef89b5..90b0e01a7a56f 100644 --- a/aptos-move/framework/aptos-framework/doc/transaction_validation.md +++ b/aptos-move/framework/aptos-framework/doc/transaction_validation.md @@ -22,6 +22,9 @@ - [Function `epilogue_gas_payer_extended`](#0x1_transaction_validation_epilogue_gas_payer_extended) - [Function `skip_auth_key_check`](#0x1_transaction_validation_skip_auth_key_check) - [Function `skip_gas_payment`](#0x1_transaction_validation_skip_gas_payment) +- [Function `unified_prologue`](#0x1_transaction_validation_unified_prologue) +- [Function `unified_prologue_fee_payer`](#0x1_transaction_validation_unified_prologue_fee_payer) +- [Function `unified_epilogue`](#0x1_transaction_validation_unified_epilogue) - [Specification](#@Specification_1) - [High-level Requirements](#high-level-req) - [Module-level Specification](#module-level-spec) @@ -38,16 +41,22 @@ - [Function `epilogue_extended`](#@Specification_1_epilogue_extended) - [Function `epilogue_gas_payer`](#@Specification_1_epilogue_gas_payer) - [Function `epilogue_gas_payer_extended`](#@Specification_1_epilogue_gas_payer_extended) + - [Function `unified_prologue`](#@Specification_1_unified_prologue) + - [Function `unified_prologue_fee_payer`](#@Specification_1_unified_prologue_fee_payer) + - [Function `unified_epilogue`](#@Specification_1_unified_epilogue)
use 0x1::account;
+use 0x1::account_abstraction;
 use 0x1::aptos_account;
 use 0x1::aptos_coin;
 use 0x1::bcs;
 use 0x1::chain_id;
 use 0x1::coin;
+use 0x1::create_signer;
 use 0x1::error;
 use 0x1::features;
+use 0x1::option;
 use 0x1::signer;
 use 0x1::system_addresses;
 use 0x1::timestamp;
@@ -282,7 +291,7 @@ Only called during genesis to initialize system resources for this module.
 
 
 
-
fun prologue_common(sender: signer, gas_payer: address, txn_sequence_number: u64, txn_authentication_key: vector<u8>, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, chain_id: u8, is_simulation: bool)
+
fun prologue_common(sender: &signer, gas_payer: &signer, txn_sequence_number: u64, txn_authentication_key: option::Option<vector<u8>>, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, chain_id: u8, is_simulation: bool)
 
@@ -292,10 +301,10 @@ Only called during genesis to initialize system resources for this module.
fun prologue_common(
-    sender: signer,
-    gas_payer: address,
+    sender: &signer,
+    gas_payer: &signer,
     txn_sequence_number: u64,
-    txn_authentication_key: vector<u8>,
+    txn_authentication_key: Option<vector<u8>>,
     txn_gas_price: u64,
     txn_max_gas_units: u64,
     txn_expiration_time: u64,
@@ -308,23 +317,33 @@ Only called during genesis to initialize system resources for this module.
     );
     assert!(chain_id::get() == chain_id, error::invalid_argument(PROLOGUE_EBAD_CHAIN_ID));
 
-    let transaction_sender = signer::address_of(&sender);
+    let transaction_sender = signer::address_of(sender);
+    let gas_payer_address = signer::address_of(gas_payer);
 
     if (
-        transaction_sender == gas_payer
+        transaction_sender == gas_payer_address
             || account::exists_at(transaction_sender)
             || !features::sponsored_automatic_account_creation_enabled()
             || txn_sequence_number > 0
     ) {
         assert!(account::exists_at(transaction_sender), error::invalid_argument(PROLOGUE_EACCOUNT_DOES_NOT_EXIST));
         if (!features::transaction_simulation_enhancement_enabled() ||
-                !skip_auth_key_check(is_simulation, &txn_authentication_key)) {
-            assert!(
-                txn_authentication_key == account::get_authentication_key(transaction_sender),
-                error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY),
-            )
+            !skip_auth_key_check(is_simulation, &txn_authentication_key)) {
+            if (option::is_some(&txn_authentication_key)) {
+                assert!(
+                    txn_authentication_key == option::some(account::get_authentication_key(transaction_sender)),
+                    error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY)
+                );
+            } else {
+                assert!(
+                    features::is_account_abstraction_enabled(
+                    ) && account_abstraction::using_dispatchable_authenticator(
+                        transaction_sender
+                    ),
+                    error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY)
+                )
+            };
         };
-
         let account_sequence_number = account::get_sequence_number(transaction_sender);
         assert!(
             txn_sequence_number < (1u64 << 63),
@@ -351,7 +370,7 @@ Only called during genesis to initialize system resources for this module.
         if (!features::transaction_simulation_enhancement_enabled() ||
                 !skip_auth_key_check(is_simulation, &txn_authentication_key)) {
             assert!(
-                txn_authentication_key == bcs::to_bytes(&transaction_sender),
+                txn_authentication_key == option::some(bcs::to_bytes(&transaction_sender)),
                 error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY),
             );
         }
@@ -359,15 +378,18 @@ Only called during genesis to initialize system resources for this module.
 
     let max_transaction_fee = txn_gas_price * txn_max_gas_units;
 
-    if (!features::transaction_simulation_enhancement_enabled() || !skip_gas_payment(is_simulation, gas_payer)) {
+    if (!features::transaction_simulation_enhancement_enabled() || !skip_gas_payment(
+        is_simulation,
+        gas_payer_address
+    )) {
         if (features::operations_default_to_fa_apt_store_enabled()) {
             assert!(
-                aptos_account::is_fungible_balance_at_least(gas_payer, max_transaction_fee),
+                aptos_account::is_fungible_balance_at_least(gas_payer_address, max_transaction_fee),
                 error::invalid_argument(PROLOGUE_ECANT_PAY_GAS_DEPOSIT)
             );
         } else {
             assert!(
-                coin::is_balance_at_least<AptosCoin>(gas_payer, max_transaction_fee),
+                coin::is_balance_at_least<AptosCoin>(gas_payer_address, max_transaction_fee),
                 error::invalid_argument(PROLOGUE_ECANT_PAY_GAS_DEPOSIT)
             );
         }
@@ -404,13 +426,12 @@ Only called during genesis to initialize system resources for this module.
     chain_id: u8,
     _script_hash: vector<u8>,
 ) {
-    let gas_payer = signer::address_of(&sender);
     // prologue_common with is_simulation set to false behaves identically to the original script_prologue function.
     prologue_common(
-        sender,
-        gas_payer,
+        &sender,
+        &sender,
         txn_sequence_number,
-        txn_public_key,
+        option::some(txn_public_key),
         txn_gas_price,
         txn_max_gas_units,
         txn_expiration_time,
@@ -450,12 +471,11 @@ Only called during genesis to initialize system resources for this module.
     _script_hash: vector<u8>,
     is_simulation: bool,
 ) {
-    let gas_payer = signer::address_of(&sender);
     prologue_common(
-        sender,
-        gas_payer,
+        &sender,
+        &sender,
         txn_sequence_number,
-        txn_public_key,
+        option::some(txn_public_key),
         txn_gas_price,
         txn_max_gas_units,
         txn_expiration_time,
@@ -495,21 +515,24 @@ Only called during genesis to initialize system resources for this module.
     txn_expiration_time: u64,
     chain_id: u8,
 ) {
-    let sender_addr = signer::address_of(&sender);
     // prologue_common and multi_agent_common_prologue with is_simulation set to false behaves identically to the
     // original multi_agent_script_prologue function.
     prologue_common(
-        sender,
-        sender_addr,
+        &sender,
+        &sender,
         txn_sequence_number,
-        txn_sender_public_key,
+        option::some(txn_sender_public_key),
         txn_gas_price,
         txn_max_gas_units,
         txn_expiration_time,
         chain_id,
         false,
     );
-    multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, false);
+    multi_agent_common_prologue(
+        secondary_signer_addresses,
+        vector::map(secondary_signer_public_key_hashes, |x| option::some(x)),
+        false
+    );
 }
 
@@ -544,19 +567,22 @@ Only called during genesis to initialize system resources for this module. chain_id: u8, is_simulation: bool, ) { - let sender_addr = signer::address_of(&sender); prologue_common( - sender, - sender_addr, + &sender, + &sender, txn_sequence_number, - txn_sender_public_key, + option::some(txn_sender_public_key), txn_gas_price, txn_max_gas_units, txn_expiration_time, chain_id, is_simulation, ); - multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, is_simulation); + multi_agent_common_prologue( + secondary_signer_addresses, + vector::map(secondary_signer_public_key_hashes, |x| option::some(x)), + is_simulation + ); }
@@ -570,7 +596,7 @@ Only called during genesis to initialize system resources for this module. -
fun multi_agent_common_prologue(secondary_signer_addresses: vector<address>, secondary_signer_public_key_hashes: vector<vector<u8>>, is_simulation: bool)
+
fun multi_agent_common_prologue(secondary_signer_addresses: vector<address>, secondary_signer_public_key_hashes: vector<option::Option<vector<u8>>>, is_simulation: bool)
 
@@ -581,7 +607,7 @@ Only called during genesis to initialize system resources for this module.
fun multi_agent_common_prologue(
     secondary_signer_addresses: vector<address>,
-    secondary_signer_public_key_hashes: vector<vector<u8>>,
+    secondary_signer_public_key_hashes: vector<Option<vector<u8>>>,
     is_simulation: bool,
 ) {
     let num_secondary_signers = vector::length(&secondary_signer_addresses);
@@ -592,27 +618,53 @@ Only called during genesis to initialize system resources for this module.
 
     let i = 0;
     while ({
-        spec {
-            invariant i <= num_secondary_signers;
-            invariant forall j in 0..i:
-                account::exists_at(secondary_signer_addresses[j]);
-            invariant forall j in 0..i:
-                secondary_signer_public_key_hashes[j] == account::get_authentication_key(secondary_signer_addresses[j]) ||
-                    (features::spec_simulation_enhancement_enabled() && is_simulation && vector::is_empty(secondary_signer_public_key_hashes[j]));
-        };
+        // spec {
+        //     invariant i <= num_secondary_signers;
+        //     invariant forall j in 0..i:
+        //         account::exists_at(secondary_signer_addresses[j]);
+        //     invariant forall j in 0..i:
+        //         secondary_signer_public_key_hashes[j] == account::get_authentication_key(secondary_signer_addresses[j]) ||
+        //             (features::spec_simulation_enhancement_enabled() && is_simulation && vector::is_empty(secondary_signer_public_key_hashes[j]));
+        //         account::account_resource_exists_at(secondary_signer_addresses[j])
+        //         && secondary_signer_public_key_hashes[j]
+        //             == account::get_authentication_key(secondary_signer_addresses[j])
+        //             || features::account_abstraction_enabled() && account_abstraction::using_native_authenticator(
+        //             secondary_signer_addresses[j]
+        //         ) && option::spec_some(secondary_signer_public_key_hashes[j]) == account_abstraction::native_authenticator(
+        //         account::exists_at(secondary_signer_addresses[j])
+        //         && secondary_signer_public_key_hashes[j]
+        //             == account::spec_get_authentication_key(secondary_signer_addresses[j])
+        //             || features::spec_account_abstraction_enabled() && account_abstraction::using_native_authenticator(
+        //             secondary_signer_addresses[j]
+        //         ) && option::spec_some(
+        //             secondary_signer_public_key_hashes[j]
+        //         ) == account_abstraction::spec_native_authenticator(
+        //             secondary_signer_addresses[j]
+        //         );
+        // };
         (i < num_secondary_signers)
     }) {
         let secondary_address = *vector::borrow(&secondary_signer_addresses, i);
         assert!(account::exists_at(secondary_address), error::invalid_argument(PROLOGUE_EACCOUNT_DOES_NOT_EXIST));
-
         let signer_public_key_hash = *vector::borrow(&secondary_signer_public_key_hashes, i);
         if (!features::transaction_simulation_enhancement_enabled() ||
-                !skip_auth_key_check(is_simulation, &signer_public_key_hash)) {
-            assert!(
-                signer_public_key_hash == account::get_authentication_key(secondary_address),
-                error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY),
-            )
+            !skip_auth_key_check(is_simulation, &signer_public_key_hash)) {
+            if (option::is_some(&signer_public_key_hash)) {
+                assert!(
+                    signer_public_key_hash == option::some(account::get_authentication_key(secondary_address)),
+                    error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY)
+                );
+            } else {
+                assert!(
+                    features::is_account_abstraction_enabled(
+                    ) && account_abstraction::using_dispatchable_authenticator(
+                        secondary_address
+                    ),
+                    error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY)
+                )
+            };
         };
+
         i = i + 1;
     }
 }
@@ -654,17 +706,21 @@ Only called during genesis to initialize system resources for this module.
     // prologue_common and multi_agent_common_prologue with is_simulation set to false behaves identically to the
     // original fee_payer_script_prologue function.
     prologue_common(
-        sender,
-        fee_payer_address,
+        &sender,
+        &create_signer::create_signer(fee_payer_address),
         txn_sequence_number,
-        txn_sender_public_key,
+        option::some(txn_sender_public_key),
         txn_gas_price,
         txn_max_gas_units,
         txn_expiration_time,
         chain_id,
         false,
     );
-    multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, false);
+    multi_agent_common_prologue(
+        secondary_signer_addresses,
+        vector::map(secondary_signer_public_key_hashes, |x| option::some(x)),
+        false
+    );
     assert!(
         fee_payer_public_key_hash == account::get_authentication_key(fee_payer_address),
         error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY),
@@ -707,24 +763,25 @@ Only called during genesis to initialize system resources for this module.
 ) {
     assert!(features::fee_payer_enabled(), error::invalid_state(PROLOGUE_EFEE_PAYER_NOT_ENABLED));
     prologue_common(
-        sender,
-        fee_payer_address,
+        &sender,
+        &create_signer::create_signer(fee_payer_address),
         txn_sequence_number,
-        txn_sender_public_key,
+        option::some(txn_sender_public_key),
         txn_gas_price,
         txn_max_gas_units,
         txn_expiration_time,
         chain_id,
         is_simulation,
     );
-    multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, is_simulation);
-    if (!features::transaction_simulation_enhancement_enabled() ||
-        !skip_auth_key_check(is_simulation, &fee_payer_public_key_hash)) {
-        assert!(
-            fee_payer_public_key_hash == account::get_authentication_key(fee_payer_address),
-            error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY),
-        )
-    }
+    multi_agent_common_prologue(
+        secondary_signer_addresses,
+        vector::map(secondary_signer_public_key_hashes, |x| option::some(x)),
+        is_simulation
+    );
+    assert!(
+        fee_payer_public_key_hash == account::get_authentication_key(fee_payer_address),
+        error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY),
+    )
 }
 
@@ -757,7 +814,14 @@ Called by the Adapter gas_units_remaining: u64, ) { let addr = signer::address_of(&account); - epilogue_gas_payer(account, addr, storage_fee_refunded, txn_gas_price, txn_max_gas_units, gas_units_remaining); + epilogue_gas_payer( + account, + addr, + storage_fee_refunded, + txn_gas_price, + txn_max_gas_units, + gas_units_remaining + ); }
@@ -789,7 +853,15 @@ Called by the Adapter is_simulation: bool, ) { let addr = signer::address_of(&account); - epilogue_gas_payer_extended(account, addr, storage_fee_refunded, txn_gas_price, txn_max_gas_units, gas_units_remaining, is_simulation); + epilogue_gas_payer_extended( + account, + addr, + storage_fee_refunded, + txn_gas_price, + txn_max_gas_units, + gas_units_remaining, + is_simulation + ); }
@@ -820,7 +892,7 @@ Called by the Adapter storage_fee_refunded: u64, txn_gas_price: u64, txn_max_gas_units: u64, - gas_units_remaining: u64, + gas_units_remaining: u64 ) { // epilogue_gas_payer_extended with is_simulation set to false behaves identically to the original // epilogue_gas_payer function. @@ -913,7 +985,7 @@ Called by the Adapter -
fun skip_auth_key_check(is_simulation: bool, auth_key: &vector<u8>): bool
+
fun skip_auth_key_check(is_simulation: bool, auth_key: &option::Option<vector<u8>>): bool
 
@@ -922,8 +994,8 @@ Called by the Adapter Implementation -
inline fun skip_auth_key_check(is_simulation: bool, auth_key: &vector<u8>): bool {
-    is_simulation && vector::is_empty(auth_key)
+
inline fun skip_auth_key_check(is_simulation: bool, auth_key: &Option<vector<u8>>): bool {
+    is_simulation && (option::is_none(auth_key) || vector::is_empty(option::borrow(auth_key)))
 }
 
@@ -953,6 +1025,190 @@ Called by the Adapter + + + + +## Function `unified_prologue` + +new set of functions + + +
fun unified_prologue(sender: signer, txn_sender_public_key: option::Option<vector<u8>>, txn_sequence_number: u64, secondary_signer_addresses: vector<address>, secondary_signer_public_key_hashes: vector<option::Option<vector<u8>>>, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, chain_id: u8, is_simulation: bool)
+
+ + + +
+Implementation + + +
fun unified_prologue(
+    sender: signer,
+    txn_sender_public_key: Option<vector<u8>>,
+    txn_sequence_number: u64,
+    secondary_signer_addresses: vector<address>,
+    secondary_signer_public_key_hashes: vector<Option<vector<u8>>>,
+    txn_gas_price: u64,
+    txn_max_gas_units: u64,
+    txn_expiration_time: u64,
+    chain_id: u8,
+    is_simulation: bool,
+) {
+    prologue_common(
+        &sender,
+        &sender,
+        txn_sequence_number,
+        txn_sender_public_key,
+        txn_gas_price,
+        txn_max_gas_units,
+        txn_expiration_time,
+        chain_id,
+        is_simulation,
+    );
+    multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, is_simulation);
+}
+
+ + + +
+ + + +## Function `unified_prologue_fee_payer` + +If there is no fee_payer, fee_payer = sender + + +
fun unified_prologue_fee_payer(sender: signer, fee_payer: signer, txn_sender_public_key: option::Option<vector<u8>>, fee_payer_public_key_hash: option::Option<vector<u8>>, txn_sequence_number: u64, secondary_signer_addresses: vector<address>, secondary_signer_public_key_hashes: vector<option::Option<vector<u8>>>, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, chain_id: u8, is_simulation: bool)
+
+ + + +
+Implementation + + +
fun unified_prologue_fee_payer(
+    sender: signer,
+    fee_payer: signer,
+    txn_sender_public_key: Option<vector<u8>>,
+    fee_payer_public_key_hash: Option<vector<u8>>,
+    txn_sequence_number: u64,
+    secondary_signer_addresses: vector<address>,
+    secondary_signer_public_key_hashes: vector<Option<vector<u8>>>,
+    txn_gas_price: u64,
+    txn_max_gas_units: u64,
+    txn_expiration_time: u64,
+    chain_id: u8,
+    is_simulation: bool,
+) {
+    prologue_common(
+        &sender,
+        &fee_payer,
+        txn_sequence_number,
+        txn_sender_public_key,
+        txn_gas_price,
+        txn_max_gas_units,
+        txn_expiration_time,
+        chain_id,
+        is_simulation,
+    );
+    multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, is_simulation);
+    if (!features::transaction_simulation_enhancement_enabled() ||
+        !skip_auth_key_check(is_simulation, &fee_payer_public_key_hash)) {
+        let fee_payer_address = signer::address_of(&fee_payer);
+        if (option::is_some(&fee_payer_public_key_hash)) {
+            assert!(
+                fee_payer_public_key_hash == option::some(account::get_authentication_key(fee_payer_address)),
+                error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY)
+            );
+        } else {
+            assert!(
+                features::is_account_abstraction_enabled() && account_abstraction::using_dispatchable_authenticator(
+                    fee_payer_address
+                ),
+                error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY)
+            )
+        };
+    }
+}
+
+ + + +
+ + + +## Function `unified_epilogue` + + + +
fun unified_epilogue(account: signer, gas_payer: signer, storage_fee_refunded: u64, txn_gas_price: u64, txn_max_gas_units: u64, gas_units_remaining: u64, is_simulation: bool)
+
+ + + +
+Implementation + + +
fun unified_epilogue(
+    account: signer,
+    gas_payer: signer,
+    storage_fee_refunded: u64,
+    txn_gas_price: u64,
+    txn_max_gas_units: u64,
+    gas_units_remaining: u64,
+    is_simulation: bool,
+) {
+    assert!(txn_max_gas_units >= gas_units_remaining, error::invalid_argument(EOUT_OF_GAS));
+    let gas_used = txn_max_gas_units - gas_units_remaining;
+
+    assert!(
+        (txn_gas_price as u128) * (gas_used as u128) <= MAX_U64,
+        error::out_of_range(EOUT_OF_GAS)
+    );
+    let transaction_fee_amount = txn_gas_price * gas_used;
+
+    let gas_payer_address = signer::address_of(&gas_payer);
+    // it's important to maintain the error code consistent with vm
+    // to do failed transaction cleanup.
+    if (!features::transaction_simulation_enhancement_enabled() || !skip_gas_payment(
+        is_simulation,
+        gas_payer_address
+    )) {
+        if (features::operations_default_to_fa_apt_store_enabled()) {
+            assert!(
+                aptos_account::is_fungible_balance_at_least(gas_payer_address, transaction_fee_amount),
+                error::out_of_range(PROLOGUE_ECANT_PAY_GAS_DEPOSIT),
+            );
+        } else {
+            assert!(
+                coin::is_balance_at_least<AptosCoin>(gas_payer_address, transaction_fee_amount),
+                error::out_of_range(PROLOGUE_ECANT_PAY_GAS_DEPOSIT),
+            );
+        };
+
+        if (transaction_fee_amount > storage_fee_refunded) {
+            let burn_amount = transaction_fee_amount - storage_fee_refunded;
+            transaction_fee::burn_fee(gas_payer_address, burn_amount);
+        } else if (transaction_fee_amount < storage_fee_refunded) {
+            let mint_amount = storage_fee_refunded - transaction_fee_amount;
+            transaction_fee::mint_and_refund(gas_payer_address, mint_amount)
+        };
+    };
+
+    // Increment sequence number
+    let addr = signer::address_of(&account);
+    account::increment_sequence_number(addr);
+}
+
+ + +
@@ -1039,10 +1295,10 @@ Give some constraints that may abort according to the conditions.
schema PrologueCommonAbortsIf {
-    sender: signer;
-    gas_payer: address;
+    sender: &signer;
+    gas_payer: &signer;
     txn_sequence_number: u64;
-    txn_authentication_key: vector<u8>;
+    txn_authentication_key: Option<vector<u8>>;
     txn_gas_price: u64;
     txn_max_gas_units: u64;
     txn_expiration_time: u64;
@@ -1052,28 +1308,33 @@ Give some constraints that may abort according to the conditions.
     aborts_if !exists<ChainId>(@aptos_framework);
     aborts_if !(chain_id::get() == chain_id);
     let transaction_sender = signer::address_of(sender);
+    let gas_payer_addr = signer::address_of(gas_payer);
     aborts_if (
         !features::spec_is_enabled(features::SPONSORED_AUTOMATIC_ACCOUNT_CREATION)
             || account::exists_at(transaction_sender)
-            || transaction_sender == gas_payer
+            || transaction_sender == gas_payer_addr
             || txn_sequence_number > 0
     ) && (
         !(txn_sequence_number >= global<Account>(transaction_sender).sequence_number)
-            || !(txn_authentication_key == global<Account>(transaction_sender).authentication_key)
+            || !(option::spec_is_none(txn_authentication_key) || option::spec_borrow(
+            txn_authentication_key
+        ) == global<Account>(transaction_sender).authentication_key)
             || !account::exists_at(transaction_sender)
             || !(txn_sequence_number == global<Account>(transaction_sender).sequence_number)
     );
     aborts_if features::spec_is_enabled(features::SPONSORED_AUTOMATIC_ACCOUNT_CREATION)
-        && transaction_sender != gas_payer
+        && transaction_sender != gas_payer_addr
         && txn_sequence_number == 0
         && !account::exists_at(transaction_sender)
-        && txn_authentication_key != bcs::to_bytes(transaction_sender);
+        && (option::spec_is_none(txn_authentication_key) || option::spec_borrow(
+        txn_authentication_key
+    ) != bcs::to_bytes(transaction_sender));
     aborts_if !(txn_sequence_number < (1u64 << 63));
     let max_transaction_fee = txn_gas_price * txn_max_gas_units;
     aborts_if max_transaction_fee > MAX_U64;
-    aborts_if !exists<CoinStore<AptosCoin>>(gas_payer);
+    aborts_if !exists<CoinStore<AptosCoin>>(gas_payer_addr);
     // This enforces high-level requirement 1:
-    aborts_if !(global<CoinStore<AptosCoin>>(gas_payer).coin.value >= max_transaction_fee);
+    aborts_if !(global<CoinStore<AptosCoin>>(gas_payer_addr).coin.value >= max_transaction_fee);
 }
 
@@ -1084,7 +1345,7 @@ Give some constraints that may abort according to the conditions. ### Function `prologue_common` -
fun prologue_common(sender: signer, gas_payer: address, txn_sequence_number: u64, txn_authentication_key: vector<u8>, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, chain_id: u8, is_simulation: bool)
+
fun prologue_common(sender: &signer, gas_payer: &signer, txn_sequence_number: u64, txn_authentication_key: option::Option<vector<u8>>, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, chain_id: u8, is_simulation: bool)
 
@@ -1118,7 +1379,7 @@ Give some constraints that may abort according to the conditions.
schema MultiAgentPrologueCommonAbortsIf {
     secondary_signer_addresses: vector<address>;
-    secondary_signer_public_key_hashes: vector<vector<u8>>;
+    secondary_signer_public_key_hashes: vector<Option<vector<u8>>>;
     is_simulation: bool;
     let num_secondary_signers = len(secondary_signer_addresses);
     aborts_if len(secondary_signer_public_key_hashes) != num_secondary_signers;
@@ -1127,12 +1388,17 @@ Give some constraints that may abort according to the conditions.
         !account::exists_at(secondary_signer_addresses[i]);
     aborts_if exists i in 0..num_secondary_signers:
         !can_skip(features::spec_simulation_enhancement_enabled(), is_simulation, secondary_signer_public_key_hashes[i]) &&
-            secondary_signer_public_key_hashes[i] !=
+            option::spec_is_some(secondary_signer_public_key_hashes[i]) && option::spec_borrow(
+            secondary_signer_public_key_hashes[i]
+        ) !=
                 account::get_authentication_key(secondary_signer_addresses[i]);
     ensures forall i in 0..num_secondary_signers:
         account::exists_at(secondary_signer_addresses[i]);
     ensures forall i in 0..num_secondary_signers:
-        secondary_signer_public_key_hashes[i] == account::get_authentication_key(secondary_signer_addresses[i])
+        option::spec_is_none(secondary_signer_public_key_hashes[i]) || option::spec_borrow(
+            secondary_signer_public_key_hashes[i]
+        ) ==
+            account::get_authentication_key(secondary_signer_addresses[i])
             || can_skip(features::spec_simulation_enhancement_enabled(), is_simulation, secondary_signer_public_key_hashes[i]);
 }
 
@@ -1143,8 +1409,8 @@ Give some constraints that may abort according to the conditions. -
fun can_skip(feature_flag: bool, is_simulation: bool, auth_key: vector<u8>): bool {
-   features::spec_simulation_enhancement_enabled() && is_simulation && vector::is_empty(auth_key)
+
fun can_skip(feature_flag: bool, is_simulation: bool, auth_key: Option<vector<u8>>): bool {
+   features::spec_simulation_enhancement_enabled() && is_simulation && option::spec_is_none(auth_key)
 }
 
@@ -1163,8 +1429,8 @@ Give some constraints that may abort according to the conditions.
pragma verify = false;
 include PrologueCommonAbortsIf {
-    gas_payer: signer::address_of(sender),
-    txn_authentication_key: txn_public_key
+    gas_payer: sender,
+    txn_authentication_key: option::spec_some(txn_public_key)
 };
 
@@ -1200,18 +1466,8 @@ not equal the number of singers.
pragma verify_duration_estimate = 120;
-let gas_payer = signer::address_of(sender);
+let gas_payer = sender;
 pragma verify = false;
-include PrologueCommonAbortsIf {
-    gas_payer,
-    txn_sequence_number,
-    txn_authentication_key: txn_sender_public_key,
-};
-include MultiAgentPrologueCommonAbortsIf {
-    secondary_signer_addresses,
-    secondary_signer_public_key_hashes,
-    is_simulation,
-};
 
@@ -1221,17 +1477,13 @@ not equal the number of singers. ### Function `multi_agent_common_prologue` -
fun multi_agent_common_prologue(secondary_signer_addresses: vector<address>, secondary_signer_public_key_hashes: vector<vector<u8>>, is_simulation: bool)
+
fun multi_agent_common_prologue(secondary_signer_addresses: vector<address>, secondary_signer_public_key_hashes: vector<option::Option<vector<u8>>>, is_simulation: bool)
 
-
include MultiAgentPrologueCommonAbortsIf {
-    secondary_signer_addresses,
-    secondary_signer_public_key_hashes,
-    is_simulation,
-};
+
pragma aborts_if_is_partial;
 
@@ -1263,21 +1515,17 @@ not equal the number of singers. -
pragma verify_duration_estimate = 120;
+
pragma aborts_if_is_partial;
+pragma verify_duration_estimate = 120;
 aborts_if !features::spec_is_enabled(features::FEE_PAYER_ENABLED);
-let gas_payer = fee_payer_address;
+let gas_payer = create_signer::create_signer(fee_payer_address);
 include PrologueCommonAbortsIf {
     gas_payer,
     txn_sequence_number,
-    txn_authentication_key: txn_sender_public_key,
+    txn_authentication_key: option::spec_some(txn_sender_public_key),
 };
-include MultiAgentPrologueCommonAbortsIf {
-    secondary_signer_addresses,
-    secondary_signer_public_key_hashes,
-    is_simulation,
-};
-aborts_if !account::exists_at(gas_payer);
-aborts_if !(fee_payer_public_key_hash == account::get_authentication_key(gas_payer));
+aborts_if !account::exists_at(fee_payer_address);
+aborts_if !(fee_payer_public_key_hash == account::get_authentication_key(fee_payer_address));
 aborts_if !features::spec_fee_payer_enabled();
 
@@ -1330,6 +1578,74 @@ Skip transaction_fee::burn_fee verification. +
pragma verify = false;
+
+ + + + + +### Function `epilogue_gas_payer_extended` + + +
fun epilogue_gas_payer_extended(account: signer, gas_payer: address, storage_fee_refunded: u64, txn_gas_price: u64, txn_max_gas_units: u64, gas_units_remaining: u64, is_simulation: bool)
+
+ + +Abort according to the conditions. +AptosCoinCapabilities and CoinInfo should exist. +Skip transaction_fee::burn_fee verification. + + +
pragma verify = false;
+include EpilogueGasPayerAbortsIf;
+
+ + + + + +### Function `unified_prologue` + + +
fun unified_prologue(sender: signer, txn_sender_public_key: option::Option<vector<u8>>, txn_sequence_number: u64, secondary_signer_addresses: vector<address>, secondary_signer_public_key_hashes: vector<option::Option<vector<u8>>>, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, chain_id: u8, is_simulation: bool)
+
+ + + + +
pragma verify = false;
+
+ + + + + +### Function `unified_prologue_fee_payer` + + +
fun unified_prologue_fee_payer(sender: signer, fee_payer: signer, txn_sender_public_key: option::Option<vector<u8>>, fee_payer_public_key_hash: option::Option<vector<u8>>, txn_sequence_number: u64, secondary_signer_addresses: vector<address>, secondary_signer_public_key_hashes: vector<option::Option<vector<u8>>>, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, chain_id: u8, is_simulation: bool)
+
+ + + + +
pragma verify = false;
+
+ + + + + +### Function `unified_epilogue` + + +
fun unified_epilogue(account: signer, gas_payer: signer, storage_fee_refunded: u64, txn_gas_price: u64, txn_max_gas_units: u64, gas_units_remaining: u64, is_simulation: bool)
+
+ + + +
pragma verify = false;
 
@@ -1384,24 +1700,4 @@ Skip transaction_fee::burn_fee verification.
- - - -### Function `epilogue_gas_payer_extended` - - -
fun epilogue_gas_payer_extended(account: signer, gas_payer: address, storage_fee_refunded: u64, txn_gas_price: u64, txn_max_gas_units: u64, gas_units_remaining: u64, is_simulation: bool)
-
- - -Abort according to the conditions. -AptosCoinCapabilities and CoinInfo should exist. -Skip transaction_fee::burn_fee verification. - - -
pragma verify = false;
-include EpilogueGasPayerAbortsIf;
-
- - [move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/util.md b/aptos-move/framework/aptos-framework/doc/util.md index 58f3e29748c93..ca6b1f1264c0e 100644 --- a/aptos-move/framework/aptos-framework/doc/util.md +++ b/aptos-move/framework/aptos-framework/doc/util.md @@ -29,6 +29,8 @@ Note that this function does not put any constraint on T. If code u deserialized a linear value, its their responsibility that the data they deserialize is owned. +Function would abort if T has signer in it. +
public(friend) fun from_bytes<T>(bytes: vector<u8>): T
 
diff --git a/aptos-move/framework/aptos-framework/doc/vesting.md b/aptos-move/framework/aptos-framework/doc/vesting.md index 95b80f3be991a..9d7cf203786c9 100644 --- a/aptos-move/framework/aptos-framework/doc/vesting.md +++ b/aptos-move/framework/aptos-framework/doc/vesting.md @@ -65,7 +65,10 @@ withdrawable, admin can call admin_withdraw to withdraw all funds to the vesting - [Struct `DistributeEvent`](#0x1_vesting_DistributeEvent) - [Struct `TerminateEvent`](#0x1_vesting_TerminateEvent) - [Struct `AdminWithdrawEvent`](#0x1_vesting_AdminWithdrawEvent) +- [Struct `VestPermission`](#0x1_vesting_VestPermission) - [Constants](#@Constants_0) +- [Function `check_vest_permission`](#0x1_vesting_check_vest_permission) +- [Function `grant_permission`](#0x1_vesting_grant_permission) - [Function `stake_pool_address`](#0x1_vesting_stake_pool_address) - [Function `vesting_start_secs`](#0x1_vesting_vesting_start_secs) - [Function `period_duration_secs`](#0x1_vesting_period_duration_secs) @@ -169,6 +172,7 @@ withdrawable, admin can call admin_withdraw to withdraw all funds to the vesting use 0x1::features; use 0x1::fixed_point32; use 0x1::math64; +use 0x1::permissioned_signer; use 0x1::pool_u64; use 0x1::signer; use 0x1::simple_map; @@ -1423,6 +1427,34 @@ withdrawable, admin can call admin_withdraw to withdraw all funds to the vesting + + + + +## Struct `VestPermission` + +Permissions to mutate the vesting config for a given account. + + +
struct VestPermission has copy, drop, store
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ +
@@ -1470,6 +1502,16 @@ Shareholders list cannot be empty. + + +Current permissioned signer cannot perform vesting operations. + + +
const ENO_VESTING_PERMISSION: u64 = 17;
+
+ + + Cannot terminate the vesting contract with pending active stake. Need to wait until next epoch. @@ -1640,6 +1682,59 @@ Vesting contract has been terminated and all funds have been released back to th + + +## Function `check_vest_permission` + +Permissions + + +
fun check_vest_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_vest_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, VestPermission {}),
+        error::permission_denied(ENO_VESTING_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_permission` + +Grant permission to perform vesting operations on behalf of the master signer. + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, VestPermission {})
+}
+
+ + + +
+ ## Function `stake_pool_address` @@ -2162,6 +2257,7 @@ Create a vesting contract with a given configurations. // Optional seed used when creating the staking contract account. contract_creation_seed: vector<u8>, ): address acquires AdminStore { + check_vest_permission(admin); assert!( !system_addresses::is_reserved_address(withdrawal_address), error::invalid_argument(EINVALID_WITHDRAWAL_ADDRESS), @@ -2980,6 +3076,7 @@ account. contract_address: address, shareholder: address, ) acquires VestingAccountManagement, VestingContract { + check_vest_permission(account); let vesting_contract = borrow_global_mut<VestingContract>(contract_address); let addr = signer::address_of(account); assert!( @@ -3199,6 +3296,7 @@ This address should be deterministic for the same admin and vesting contract cre admin: &signer, contract_creation_seed: vector<u8>, ): (signer, SignerCapability) acquires AdminStore { + check_vest_permission(admin); let admin_store = borrow_global_mut<AdminStore>(signer::address_of(admin)); let seed = bcs::to_bytes(&signer::address_of(admin)); vector::append(&mut seed, bcs::to_bytes(&admin_store.nonce)); @@ -3238,6 +3336,7 @@ This address should be deterministic for the same admin and vesting contract cre
fun verify_admin(admin: &signer, vesting_contract: &VestingContract) {
+    check_vest_permission(admin);
     assert!(signer::address_of(admin) == vesting_contract.admin, error::unauthenticated(ENOT_ADMIN));
 }
 
@@ -3492,7 +3591,7 @@ This address should be deterministic for the same admin and vesting contract cre
pragma verify = true;
-pragma aborts_if_is_strict;
+pragma aborts_if_is_partial;
 // This enforces high-level requirement 2:
 invariant forall a: address where exists<VestingContract>(a):
     global<VestingContract>(a).grant_pool.shareholders_limit <= MAXIMUM_SHAREHOLDERS;
@@ -3500,6 +3599,19 @@ This address should be deterministic for the same admin and vesting contract cre
 
 
 
+
+
+
+
+
schema AbortsIfPermissionedSigner {
+    s: signer;
+    let perm = VestPermission {};
+    aborts_if !permissioned_signer::spec_check_permission_exists(s, perm);
+}
+
+ + + ### Function `stake_pool_address` @@ -4247,7 +4359,8 @@ This address should be deterministic for the same admin and vesting contract cre -
include VerifyAdminAbortsIf;
+
pragma verify_duration_estimate = 120;
+include VerifyAdminAbortsIf;
 
@@ -4327,7 +4440,9 @@ This address should be deterministic for the same admin and vesting contract cre -
// This enforces high-level requirement 9:
+
pragma verify_duration_estimate = 120;
+aborts_if permissioned_signer::spec_is_permissioned_signer(admin);
+// This enforces high-level requirement 9:
 aborts_if signer::address_of(admin) != vesting_contract.admin;
 
@@ -4508,6 +4623,7 @@ This address should be deterministic for the same admin and vesting contract cre
schema VerifyAdminAbortsIf {
     contract_address: address;
     admin: signer;
+    aborts_if permissioned_signer::spec_is_permissioned_signer(admin);
     aborts_if !exists<VestingContract>(contract_address);
     let vesting_contract = global<VestingContract>(contract_address);
     aborts_if signer::address_of(admin) != vesting_contract.admin;
diff --git a/aptos-move/framework/aptos-framework/doc/voting.md b/aptos-move/framework/aptos-framework/doc/voting.md
index 2a4cb6cb28387..6d9187b10d064 100644
--- a/aptos-move/framework/aptos-framework/doc/voting.md
+++ b/aptos-move/framework/aptos-framework/doc/voting.md
@@ -36,7 +36,10 @@ the resolution process.
 -  [Struct `CreateProposalEvent`](#0x1_voting_CreateProposalEvent)
 -  [Struct `RegisterForumEvent`](#0x1_voting_RegisterForumEvent)
 -  [Struct `VoteEvent`](#0x1_voting_VoteEvent)
+-  [Struct `VotePermission`](#0x1_voting_VotePermission)
 -  [Constants](#@Constants_0)
+-  [Function `check_vote_permission`](#0x1_voting_check_vote_permission)
+-  [Function `grant_permission`](#0x1_voting_grant_permission)
 -  [Function `register`](#0x1_voting_register)
 -  [Function `create_proposal`](#0x1_voting_create_proposal)
 -  [Function `create_proposal_v2`](#0x1_voting_create_proposal_v2)
@@ -98,6 +101,7 @@ the resolution process.
 use 0x1::features;
 use 0x1::from_bcs;
 use 0x1::option;
+use 0x1::permissioned_signer;
 use 0x1::signer;
 use 0x1::simple_map;
 use 0x1::string;
@@ -593,6 +597,33 @@ Extra metadata (e.g. description, code url) can be part of the ProposalType stru
 
 
 
+
+
+
+
+## Struct `VotePermission`
+
+
+
+
struct VotePermission has copy, drop, store
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ +
@@ -631,6 +662,16 @@ Cannot vote if the specified multi-step proposal is in execution. + + +Cannot call is_multi_step_proposal_in_execution() on single-step proposals. + + +
const ENO_VOTE_PERMISSION: u64 = 13;
+
+ + + Proposal cannot be resolved more than once @@ -780,6 +821,59 @@ Key used to track the resolvable time in the proposal's metadata. + + +## Function `check_vote_permission` + +Permissions + + +
fun check_vote_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_vote_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, VotePermission {}),
+        error::permission_denied(ENO_VOTE_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_permission` + +Grant permission to vote on behalf of the master signer. + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, VotePermission {})
+}
+
+ + + +
+ ## Function `register` @@ -796,6 +890,7 @@ Key used to track the resolvable time in the proposal's metadata.
public fun register<ProposalType: store>(account: &signer) {
+    check_vote_permission(account);
     let addr = signer::address_of(account);
     assert!(!exists<VotingForum<ProposalType>>(addr), error::already_exists(EVOTING_FORUM_ALREADY_REGISTERED));
 
@@ -1910,7 +2005,20 @@ Return true if the voting period of the given proposal has already ended.
 
 
 
pragma verify = true;
-pragma aborts_if_is_strict;
+pragma aborts_if_is_partial;
+
+ + + + + + + +
schema AbortsIfPermissionedSigner {
+    s: signer;
+    let perm = VotePermission {};
+    aborts_if !permissioned_signer::spec_check_permission_exists(s, perm);
+}
 
diff --git a/aptos-move/framework/aptos-framework/sources/account.move b/aptos-move/framework/aptos-framework/sources/account/account.move similarity index 91% rename from aptos-move/framework/aptos-framework/sources/account.move rename to aptos-move/framework/aptos-framework/sources/account/account.move index 744ffa18861e9..9af50f3817e53 100644 --- a/aptos-move/framework/aptos-framework/sources/account.move +++ b/aptos-move/framework/aptos-framework/sources/account/account.move @@ -9,6 +9,7 @@ module aptos_framework::account { use aptos_framework::create_signer::create_signer; use aptos_framework::event::{Self, EventHandle}; use aptos_framework::guid; + use aptos_framework::permissioned_signer; use aptos_framework::system_addresses; use aptos_std::ed25519; use aptos_std::from_bcs; @@ -179,6 +180,8 @@ module aptos_framework::account { const ENEW_AUTH_KEY_ALREADY_MAPPED: u64 = 21; /// The current authentication key and the new authentication key are the same const ENEW_AUTH_KEY_SAME_AS_CURRENT: u64 = 22; + /// Current permissioned signer cannot perform the privilaged operations. + const ENO_ACCOUNT_PERMISSION: u64 = 23; /// Explicitly separate the GUID space between Object and Account to prevent accidental overlap. const MAX_GUID_CREATION_NUM: u64 = 0x4000000000000; @@ -187,6 +190,43 @@ module aptos_framework::account { /// Create signer for testing, independently of an Aptos-style `Account`. public fun create_signer_for_test(addr: address): signer { create_signer(addr) } + enum AccountPermission has copy, drop, store { + /// Permission to rotate a key. + KeyRotation, + /// Permission to offer another address to act like your address + Offering, + } + + /// Permissions + /// + inline fun check_rotation_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, AccountPermission::KeyRotation {}), + error::permission_denied(ENO_ACCOUNT_PERMISSION), + ); + } + + inline fun check_offering_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, AccountPermission::Offering {}), + error::permission_denied(ENO_ACCOUNT_PERMISSION), + ); + } + + /// Grant permission to perform key rotations on behalf of the master signer. + /// + /// This is **extremely dangerous** and should be granted only when it's absolutely needed. + public fun grant_key_rotation_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, AccountPermission::KeyRotation {}) + } + + /// Grant permission to use offered address's signer on behalf of the master signer. + /// + /// This is **extremely dangerous** and should be granted only when it's absolutely needed. + public fun grant_key_offering_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, AccountPermission::Offering {}) + } + /// Only called during genesis to initialize system resources for this module. public(friend) fun initialize(aptos_framework: &signer) { system_addresses::assert_aptos_framework(aptos_framework); @@ -302,6 +342,7 @@ module aptos_framework::account { vector::length(&new_auth_key) == 32, error::invalid_argument(EMALFORMED_AUTHENTICATION_KEY) ); + check_rotation_permission(account); let account_resource = borrow_global_mut(addr); account_resource.authentication_key = new_auth_key; } @@ -357,6 +398,7 @@ module aptos_framework::account { ) acquires Account, OriginatingAddress { let addr = signer::address_of(account); assert!(exists_at(addr), error::not_found(EACCOUNT_DOES_NOT_EXIST)); + check_rotation_permission(account); let account_resource = borrow_global_mut(addr); // Verify the given `from_public_key_bytes` matches this account's current authentication key. @@ -412,6 +454,7 @@ module aptos_framework::account { new_public_key_bytes: vector, cap_update_table: vector ) acquires Account, OriginatingAddress { + check_rotation_permission(delegate_signer); assert!(exists_at(rotation_cap_offerer_address), error::not_found(EOFFERER_ADDRESS_DOES_NOT_EXIST)); // Check that there exists a rotation capability offer at the offerer's account resource for the delegate. @@ -471,6 +514,7 @@ module aptos_framework::account { account_public_key_bytes: vector, recipient_address: address, ) acquires Account { + check_rotation_permission(account); let addr = signer::address_of(account); assert!(exists_at(recipient_address), error::not_found(EACCOUNT_DOES_NOT_EXIST)); @@ -569,6 +613,7 @@ module aptos_framework::account { /// Revoke the rotation capability offer given to `to_be_revoked_recipient_address` from `account` public entry fun revoke_rotation_capability(account: &signer, to_be_revoked_address: address) acquires Account { assert!(exists_at(to_be_revoked_address), error::not_found(EACCOUNT_DOES_NOT_EXIST)); + check_rotation_permission(account); let addr = signer::address_of(account); let account_resource = borrow_global(addr); assert!( @@ -580,6 +625,7 @@ module aptos_framework::account { /// Revoke any rotation capability offer in the specified account. public entry fun revoke_any_rotation_capability(account: &signer) acquires Account { + check_rotation_permission(account); let account_resource = borrow_global_mut(signer::address_of(account)); option::extract(&mut account_resource.rotation_capability_offer.for); } @@ -600,6 +646,7 @@ module aptos_framework::account { account_public_key_bytes: vector, recipient_address: address ) acquires Account { + check_offering_permission(account); let source_address = signer::address_of(account); assert!(exists_at(recipient_address), error::not_found(EACCOUNT_DOES_NOT_EXIST)); @@ -639,6 +686,7 @@ module aptos_framework::account { /// has a signer capability offer from `account` but will be revoked in this function). public entry fun revoke_signer_capability(account: &signer, to_be_revoked_address: address) acquires Account { assert!(exists_at(to_be_revoked_address), error::not_found(EACCOUNT_DOES_NOT_EXIST)); + check_offering_permission(account); let addr = signer::address_of(account); let account_resource = borrow_global(addr); assert!( @@ -650,6 +698,7 @@ module aptos_framework::account { /// Revoke any signer capability offer in the specified account. public entry fun revoke_any_signer_capability(account: &signer) acquires Account { + check_offering_permission(account); let account_resource = borrow_global_mut(signer::address_of(account)); option::extract(&mut account_resource.signer_capability_offer.for); } @@ -657,6 +706,7 @@ module aptos_framework::account { /// Return an authorized signer of the offerer, if there's an existing signer capability offer for `account` /// at the offerer's address. public fun create_authorized_signer(account: &signer, offerer_address: address): signer acquires Account { + check_offering_permission(account); assert!(exists_at(offerer_address), error::not_found(EOFFERER_ADDRESS_DOES_NOT_EXIST)); // Check if there's an existing signer capability offer from the offerer. @@ -1202,6 +1252,123 @@ module aptos_framework::account { assert!(signer::address_of(&signer) == signer::address_of(&alice), 0); } + #[test(bob = @0x345)] + public entry fun test_valid_check_signer_capability_and_create_authorized_signer_with_permission(bob: signer) acquires Account { + let (alice_sk, alice_pk) = ed25519::generate_keys(); + let alice_pk_bytes = ed25519::validated_public_key_to_bytes(&alice_pk); + let alice = create_account_from_ed25519_public_key(alice_pk_bytes); + let alice_addr = signer::address_of(&alice); + + let bob_addr = signer::address_of(&bob); + create_account(bob_addr); + + let challenge = SignerCapabilityOfferProofChallengeV2 { + sequence_number: borrow_global(alice_addr).sequence_number, + source_address: alice_addr, + recipient_address: bob_addr, + }; + + let alice_signer_capability_offer_sig = ed25519::sign_struct(&alice_sk, challenge); + + let alice_permission_handle = permissioned_signer::create_permissioned_handle(&alice); + let alice_permission_signer = permissioned_signer::signer_from_permissioned_handle(&alice_permission_handle); + + grant_key_offering_permission(&alice, &alice_permission_signer); + + offer_signer_capability( + &alice_permission_signer, + ed25519::signature_to_bytes(&alice_signer_capability_offer_sig), + 0, + alice_pk_bytes, + bob_addr + ); + + assert!(option::contains(&borrow_global(alice_addr).signer_capability_offer.for, &bob_addr), 0); + + let signer = create_authorized_signer(&bob, alice_addr); + assert!(signer::address_of(&signer) == signer::address_of(&alice), 0); + + permissioned_signer::destroy_permissioned_handle(alice_permission_handle); + } + + #[test(bob = @0x345)] + #[expected_failure(abort_code = 0x50017, location = Self)] + public entry fun test_valid_check_signer_capability_and_create_authorized_signer_with_no_permission(bob: signer) acquires Account { + let (alice_sk, alice_pk) = ed25519::generate_keys(); + let alice_pk_bytes = ed25519::validated_public_key_to_bytes(&alice_pk); + let alice = create_account_from_ed25519_public_key(alice_pk_bytes); + let alice_addr = signer::address_of(&alice); + + let bob_addr = signer::address_of(&bob); + create_account(bob_addr); + + let challenge = SignerCapabilityOfferProofChallengeV2 { + sequence_number: borrow_global(alice_addr).sequence_number, + source_address: alice_addr, + recipient_address: bob_addr, + }; + + let alice_signer_capability_offer_sig = ed25519::sign_struct(&alice_sk, challenge); + + let alice_permission_handle = permissioned_signer::create_permissioned_handle(&alice); + let alice_permission_signer = permissioned_signer::signer_from_permissioned_handle(&alice_permission_handle); + + offer_signer_capability( + &alice_permission_signer, + ed25519::signature_to_bytes(&alice_signer_capability_offer_sig), + 0, + alice_pk_bytes, + bob_addr + ); + + assert!(option::contains(&borrow_global(alice_addr).signer_capability_offer.for, &bob_addr), 0); + + let signer = create_authorized_signer(&bob, alice_addr); + assert!(signer::address_of(&signer) == signer::address_of(&alice), 0); + + permissioned_signer::destroy_permissioned_handle(alice_permission_handle); + } + + #[test(bob = @0x345)] + #[expected_failure(abort_code = 0x50017, location = Self)] + public entry fun test_valid_check_signer_capability_and_create_authorized_signer_with_wrong_permission(bob: signer) acquires Account { + let (alice_sk, alice_pk) = ed25519::generate_keys(); + let alice_pk_bytes = ed25519::validated_public_key_to_bytes(&alice_pk); + let alice = create_account_from_ed25519_public_key(alice_pk_bytes); + let alice_addr = signer::address_of(&alice); + + let bob_addr = signer::address_of(&bob); + create_account(bob_addr); + + let challenge = SignerCapabilityOfferProofChallengeV2 { + sequence_number: borrow_global(alice_addr).sequence_number, + source_address: alice_addr, + recipient_address: bob_addr, + }; + + let alice_signer_capability_offer_sig = ed25519::sign_struct(&alice_sk, challenge); + + let alice_permission_handle = permissioned_signer::create_permissioned_handle(&alice); + let alice_permission_signer = permissioned_signer::signer_from_permissioned_handle(&alice_permission_handle); + + grant_key_rotation_permission(&alice, &alice_permission_signer); + + offer_signer_capability( + &alice_permission_signer, + ed25519::signature_to_bytes(&alice_signer_capability_offer_sig), + 0, + alice_pk_bytes, + bob_addr + ); + + assert!(option::contains(&borrow_global(alice_addr).signer_capability_offer.for, &bob_addr), 0); + + let signer = create_authorized_signer(&bob, alice_addr); + assert!(signer::address_of(&signer) == signer::address_of(&alice), 0); + + permissioned_signer::destroy_permissioned_handle(alice_permission_handle); + } + #[test(bob = @0x345)] public entry fun test_get_signer_cap_and_is_signer_cap(bob: signer) acquires Account { let (alice_sk, alice_pk) = ed25519::generate_keys(); diff --git a/aptos-move/framework/aptos-framework/sources/account.spec.move b/aptos-move/framework/aptos-framework/sources/account/account.spec.move similarity index 99% rename from aptos-move/framework/aptos-framework/sources/account.spec.move rename to aptos-move/framework/aptos-framework/sources/account/account.spec.move index 36e7a5740027e..336d42363f69b 100644 --- a/aptos-move/framework/aptos-framework/sources/account.spec.move +++ b/aptos-move/framework/aptos-framework/sources/account/account.spec.move @@ -105,8 +105,9 @@ spec aptos_framework::account { /// spec module { - pragma verify = true; - pragma aborts_if_is_strict; + pragma verify = false; + + } /// Only the address `@aptos_framework` can call. @@ -390,7 +391,6 @@ spec aptos_framework::account { source_address, recipient_address, }; - aborts_if !exists(@aptos_framework); aborts_if !exists(recipient_address); aborts_if !exists(source_address); diff --git a/aptos-move/framework/aptos-framework/sources/account/account_abstraction.move b/aptos-move/framework/aptos-framework/sources/account/account_abstraction.move new file mode 100644 index 0000000000000..176ca42ca19c2 --- /dev/null +++ b/aptos-move/framework/aptos-framework/sources/account/account_abstraction.move @@ -0,0 +1,203 @@ +module aptos_framework::account_abstraction { + use std::error; + use std::option::{Self, Option}; + use std::signer; + use std::string::{Self, String}; + use aptos_std::ordered_map::{Self, OrderedMap}; + use aptos_framework::create_signer; + use aptos_framework::event; + use aptos_framework::function_info::{Self, FunctionInfo}; + use aptos_framework::object; + use aptos_framework::auth_data::AbstractionAuthData; + use aptos_framework::permissioned_signer::is_permissioned_signer; + #[test_only] + use aptos_framework::account::create_account_for_test; + + friend aptos_framework::transaction_validation; + #[test_only] + friend aptos_framework::account_abstraction_tests; + + const EDISPATCHABLE_AUTHENTICATOR_IS_NOT_USED: u64 = 1; + const EFUNCTION_INFO_EXISTENCE: u64 = 2; + const EAUTH_FUNCTION_SIGNATURE_MISMATCH: u64 = 3; + const ENOT_MASTER_SIGNER: u64 = 4; + + const MAX_U64: u128 = 18446744073709551615; + + #[event] + struct UpdateDispatchableAuthenticator has store, drop { + account: address, + update: vector, + auth_function: FunctionInfo, + } + + #[event] + struct RemoveDispatchableAuthenticator has store, drop { + account: address, + } + + #[resource_group_member(group = aptos_framework::object::ObjectGroup)] + /// The dispatchable authenticator that defines how to authenticates this account in the specified module. + /// An integral part of Account Abstraction. + enum DispatchableAuthenticator has key, copy, drop { + V1 { auth_functions: OrderedMap } + } + + /// Update dispatchable authenticator that enables account abstraction. + /// Note: it is a private entry function that can only be called directly from transaction. + public entry fun add_dispatchable_authentication_function( + account: &signer, + module_address: address, + module_name: String, + function_name: String, + ) acquires DispatchableAuthenticator { + assert!(!is_permissioned_signer(account), error::permission_denied(ENOT_MASTER_SIGNER)); + update_dispatchable_authenticator_impl( + account, + function_info::new_function_info_from_address(module_address, module_name, function_name), + true + ); + } + + public entry fun remove_dispatchable_authentication_function( + account: &signer, + module_address: address, + module_name: String, + function_name: String, + ) acquires DispatchableAuthenticator { + assert!(!is_permissioned_signer(account), error::permission_denied(ENOT_MASTER_SIGNER)); + update_dispatchable_authenticator_impl( + account, + function_info::new_function_info_from_address(module_address, module_name, function_name), + false + ); + } + + /// Update dispatchable authenticator that disables account abstraction. + /// Note: it is a private entry function that can only be called directly from transaction. + public entry fun remove_dispatchable_authenticator( + account: &signer, + ) acquires DispatchableAuthenticator { + assert!(!is_permissioned_signer(account), error::permission_denied(ENOT_MASTER_SIGNER)); + let addr = signer::address_of(account); + let resource_addr = resource_addr(addr); + if (exists(resource_addr)) { + move_from(resource_addr); + event::emit(RemoveDispatchableAuthenticator { + account: addr, + }); + }; + } + + inline fun resource_addr(source: address): address { + object::create_user_derived_object_address(source, @aptos_fungible_asset) + } + + fun update_dispatchable_authenticator_impl( + account: &signer, + auth_function: FunctionInfo, + is_add: bool, + ) acquires DispatchableAuthenticator { + let addr = signer::address_of(account); + let resource_addr = resource_addr(addr); + let dispatcher_auth_function_info = function_info::new_function_info_from_address( + @aptos_framework, + string::utf8(b"account_abstraction"), + string::utf8(b"dispatchable_authenticate"), + ); + assert!( + function_info::check_dispatch_type_compatibility(&dispatcher_auth_function_info, &auth_function), + error::invalid_argument(EAUTH_FUNCTION_SIGNATURE_MISMATCH) + ); + if (is_add && !exists(resource_addr)) { + move_to( + &create_signer::create_signer(resource_addr), + DispatchableAuthenticator::V1 { auth_functions: ordered_map::new() } + ); + }; + if (exists(resource_addr)) { + let current_map = &mut borrow_global_mut(resource_addr).auth_functions; + if (is_add) { + assert!( + !ordered_map::contains(current_map, &auth_function), + error::already_exists(EFUNCTION_INFO_EXISTENCE) + ); + ordered_map::add(current_map, auth_function, true); + } else { + assert!( + ordered_map::contains(current_map, &auth_function), + error::not_found(EFUNCTION_INFO_EXISTENCE) + ); + ordered_map::remove(current_map, &auth_function); + }; + event::emit( + UpdateDispatchableAuthenticator { + account: addr, + update: if (is_add) { b"add" } else { b"remove" }, + auth_function, + } + ); + if (ordered_map::length(current_map) == 0) { + remove_dispatchable_authenticator(account); + } + }; + } + + #[view] + /// Return `true` if the account is an abstracted account that can be authenticated with dispatchable move authenticator. + public fun using_dispatchable_authenticator(addr: address): bool { + exists(resource_addr(addr)) + } + + #[view] + /// Return the current dispatchable authenticator move function info. `None` means this authentication scheme is disabled. + public fun dispatchable_authenticator(addr: address): Option> acquires DispatchableAuthenticator { + let resource_addr = resource_addr(addr); + if (exists(resource_addr)) { + option::some( + ordered_map::keys(&borrow_global(resource_addr).auth_functions) + ) + } else { option::none() } + } + + inline fun dispatchable_authenticator_internal(addr: address): &OrderedMap { + assert!(using_dispatchable_authenticator(addr), error::not_found(EDISPATCHABLE_AUTHENTICATOR_IS_NOT_USED)); + &borrow_global(resource_addr(addr)).auth_functions + } + + fun authenticate( + account: signer, + func_info: FunctionInfo, + signing_data: AbstractionAuthData, + ): signer acquires DispatchableAuthenticator { + let func_infos = dispatchable_authenticator_internal(signer::address_of(&account)); + assert!(ordered_map::contains(func_infos, &func_info), error::not_found(EFUNCTION_INFO_EXISTENCE)); + function_info::load_module_from_function(&func_info); + dispatchable_authenticate(account, signing_data, &func_info) + } + + /// The native function to dispatch customized move authentication function. + native fun dispatchable_authenticate( + account: signer, + signing_data: AbstractionAuthData, + function: &FunctionInfo + ): signer; + + #[test(bob = @0xb0b)] + entry fun test_dispatchable_authenticator( + bob: &signer, + ) acquires DispatchableAuthenticator { + let bob_addr = signer::address_of(bob); + create_account_for_test(bob_addr); + assert!(!using_dispatchable_authenticator(bob_addr), 0); + add_dispatchable_authentication_function( + bob, + @aptos_framework, + string::utf8(b"account_abstraction_tests"), + string::utf8(b"test_auth") + ); + assert!(using_dispatchable_authenticator(bob_addr), 0); + remove_dispatchable_authenticator(bob); + assert!(!using_dispatchable_authenticator(bob_addr), 0); + } +} diff --git a/aptos-move/framework/aptos-framework/sources/account/account_abstraction.spec.move b/aptos-move/framework/aptos-framework/sources/account/account_abstraction.spec.move new file mode 100644 index 0000000000000..00163529aa71e --- /dev/null +++ b/aptos-move/framework/aptos-framework/sources/account/account_abstraction.spec.move @@ -0,0 +1,17 @@ +spec aptos_framework::account_abstraction { + spec module { + pragma verify = false; + } + + + spec fun spec_dispatchable_authenticate( + account: signer, + signing_data: AbstractionAuthData, + function: &FunctionInfo + ): signer; + + spec dispatchable_authenticate(account: signer, signing_data: AbstractionAuthData, function: &FunctionInfo): signer { + pragma opaque; + ensures [abstract] result == spec_dispatchable_authenticate(account, signing_data, function); + } +} diff --git a/aptos-move/framework/aptos-framework/sources/account/auth_data.move b/aptos-move/framework/aptos-framework/sources/account/auth_data.move new file mode 100644 index 0000000000000..7d1eed70a2602 --- /dev/null +++ b/aptos-move/framework/aptos-framework/sources/account/auth_data.move @@ -0,0 +1,18 @@ +module aptos_framework::auth_data { + enum AbstractionAuthData has copy, drop { + V1 { digest: vector, authenticator: vector }, + } + + #[test_only] + public fun create_auth_data(digest: vector, authenticator: vector): AbstractionAuthData { + AbstractionAuthData::V1 { digest, authenticator } + } + + public fun digest(signing_data: &AbstractionAuthData): &vector { + &signing_data.digest + } + + public fun authenticator(signing_data: &AbstractionAuthData): &vector { + &signing_data.authenticator + } +} diff --git a/aptos-move/framework/aptos-framework/sources/aptos_account.move b/aptos-move/framework/aptos-framework/sources/aptos_account.move index ddd0846b1596e..e9d7efdbf6307 100644 --- a/aptos-move/framework/aptos-framework/sources/aptos_account.move +++ b/aptos-move/framework/aptos-framework/sources/aptos_account.move @@ -247,6 +247,7 @@ module aptos_framework::aptos_account { // as APT cannot be frozen or have dispatch, and PFS cannot be transfered // (PFS could potentially be burned. regular transfer would permanently unburn the store. // Ignoring the check here has the equivalent of unburning, transfers, and then burning again) + fungible_asset::withdraw_permission_check_by_address(source, sender_store, amount); fungible_asset::unchecked_deposit(recipient_store, fungible_asset::unchecked_withdraw(sender_store, amount)); } @@ -315,6 +316,27 @@ module aptos_framework::aptos_account { coin::destroy_mint_cap(mint_cap); } + #[test(alice = @0xa11ce, core = @0x1)] + public fun test_transfer_permission(alice: &signer, core: &signer) { + use aptos_framework::permissioned_signer; + + let bob = from_bcs::to_address(x"0000000000000000000000000000000000000000000000000000000000000b0b"); + + let (burn_cap, mint_cap) = aptos_framework::aptos_coin::initialize_for_test(core); + create_account(signer::address_of(alice)); + coin::deposit(signer::address_of(alice), coin::mint(10000, &mint_cap)); + + let perm_handle = permissioned_signer::create_permissioned_handle(alice); + let alice_perm_signer = permissioned_signer::signer_from_permissioned_handle(&perm_handle); + primary_fungible_store::grant_apt_permission(alice, &alice_perm_signer, 500); + + transfer(&alice_perm_signer, bob, 500); + + coin::destroy_burn_cap(burn_cap); + coin::destroy_mint_cap(mint_cap); + permissioned_signer::destroy_permissioned_handle(perm_handle); + } + #[test(alice = @0xa11ce, core = @0x1)] public fun test_transfer_to_resource_account(alice: &signer, core: &signer) { let (resource_account, _) = account::create_resource_account(alice, vector[]); @@ -353,6 +375,7 @@ module aptos_framework::aptos_account { #[test(from = @0x1, to = @0x12)] public fun test_direct_coin_transfers(from: &signer, to: &signer) acquires DirectTransferConfig { + coin::create_coin_conversion_map(from); let (burn_cap, freeze_cap, mint_cap) = coin::initialize( from, utf8(b"FC"), @@ -376,6 +399,7 @@ module aptos_framework::aptos_account { #[test(from = @0x1, recipient_1 = @0x124, recipient_2 = @0x125)] public fun test_batch_transfer_coins( from: &signer, recipient_1: &signer, recipient_2: &signer) acquires DirectTransferConfig { + coin::create_coin_conversion_map(from); let (burn_cap, freeze_cap, mint_cap) = coin::initialize( from, utf8(b"FC"), @@ -417,6 +441,7 @@ module aptos_framework::aptos_account { #[test(from = @0x1, to = @0x12)] public fun test_direct_coin_transfers_with_explicit_direct_coin_transfer_config( from: &signer, to: &signer) acquires DirectTransferConfig { + coin::create_coin_conversion_map(from); let (burn_cap, freeze_cap, mint_cap) = coin::initialize( from, utf8(b"FC"), @@ -442,6 +467,7 @@ module aptos_framework::aptos_account { #[expected_failure(abort_code = 0x50003, location = Self)] public fun test_direct_coin_transfers_fail_if_recipient_opted_out( from: &signer, to: &signer) acquires DirectTransferConfig { + coin::create_coin_conversion_map(from); let (burn_cap, freeze_cap, mint_cap) = coin::initialize( from, utf8(b"FC"), diff --git a/aptos-move/framework/aptos-framework/sources/aptos_coin.spec.move b/aptos-move/framework/aptos-framework/sources/aptos_coin.spec.move index 9983eee23265f..080af15b7f7e6 100644 --- a/aptos-move/framework/aptos-framework/sources/aptos_coin.spec.move +++ b/aptos-move/framework/aptos-framework/sources/aptos_coin.spec.move @@ -31,12 +31,16 @@ spec aptos_framework::aptos_coin { /// spec module { pragma verify = true; - pragma aborts_if_is_strict; + pragma aborts_if_is_partial; } spec initialize(aptos_framework: &signer): (BurnCapability, MintCapability) { use aptos_framework::aggregator_factory; + use aptos_framework::permissioned_signer; + pragma verify = false; + + aborts_if permissioned_signer::spec_is_permissioned_signer(aptos_framework); let addr = signer::address_of(aptos_framework); aborts_if addr != @aptos_framework; aborts_if !string::spec_internal_check_utf8(b"Aptos Coin"); diff --git a/aptos-move/framework/aptos-framework/sources/aptos_governance.move b/aptos-move/framework/aptos-framework/sources/aptos_governance.move index f5de768d05864..ecd8144689ffd 100644 --- a/aptos-move/framework/aptos-framework/sources/aptos_governance.move +++ b/aptos-move/framework/aptos-framework/sources/aptos_governance.move @@ -31,6 +31,7 @@ module aptos_framework::aptos_governance { use aptos_framework::system_addresses; use aptos_framework::aptos_coin::{Self, AptosCoin}; use aptos_framework::consensus_config; + use aptos_framework::permissioned_signer; use aptos_framework::randomness_config; use aptos_framework::reconfiguration_with_dkg; use aptos_framework::timestamp; @@ -64,6 +65,8 @@ module aptos_framework::aptos_governance { const ENOT_PARTIAL_VOTING_PROPOSAL: u64 = 14; /// The proposal has expired. const EPROPOSAL_EXPIRED: u64 = 15; + /// Current permissioned signer cannot perform governance operations. + const ENO_GOVERNANCE_PERMISSION: u64 = 16; /// This matches the same enum const in voting. We have to duplicate it as Move doesn't have support for enums yet. const PROPOSAL_STATE_SUCCEEDED: u64 = 1; @@ -168,6 +171,21 @@ module aptos_framework::aptos_governance { voting_duration_secs: u64, } + struct GovernancePermission has copy, drop, store {} + + /// Permissions + inline fun check_governance_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, GovernancePermission {}), + error::permission_denied(ENO_GOVERNANCE_PERMISSION), + ); + } + + /// Grant permission to perform governance operations on behalf of the master signer. + public fun grant_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, GovernancePermission {}) + } + /// Can be called during genesis or by the governance itself. /// Stores the signer capability for a given address. public fun store_signer_cap( @@ -396,6 +414,7 @@ module aptos_framework::aptos_governance { metadata_hash: vector, is_multi_step_proposal: bool, ): u64 acquires GovernanceConfig, GovernanceEvents { + check_governance_permission(proposer); let proposer_address = signer::address_of(proposer); assert!( stake::get_delegated_voter(stake_pool) == proposer_address, @@ -528,6 +547,7 @@ module aptos_framework::aptos_governance { voting_power: u64, should_pass: bool, ) acquires ApprovedExecutionHashes, VotingRecords, VotingRecordsV2, GovernanceEvents { + permissioned_signer::assert_master_signer(voter); let voter_address = signer::address_of(voter); assert!(stake::get_delegated_voter(stake_pool) == voter_address, error::invalid_argument(ENOT_DELEGATED_VOTER)); diff --git a/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move b/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move index 3ea2572dd8fea..7126b01c0d76f 100644 --- a/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move +++ b/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move @@ -29,7 +29,14 @@ spec aptos_framework::aptos_governance { /// spec module { pragma verify = true; - pragma aborts_if_is_strict; + pragma aborts_if_is_partial; + } + + spec schema AbortsIfPermissionedSigner { + use aptos_framework::permissioned_signer; + s: signer; + let perm = GovernancePermission {}; + aborts_if !permissioned_signer::spec_check_permission_exists(s, perm); } spec store_signer_cap( @@ -215,6 +222,7 @@ spec aptos_framework::aptos_governance { pragma verify_duration_estimate = 60; requires chain_status::is_operating(); include CreateProposalAbortsIf; + // include AbortsIfPermissionedSigner { s: proposer }; } /// `stake_pool` must exist StakePool. diff --git a/aptos-move/framework/aptos-framework/sources/code.move b/aptos-move/framework/aptos-framework/sources/code.move index ef884c9695d1c..56a0b13d0056c 100644 --- a/aptos-move/framework/aptos-framework/sources/code.move +++ b/aptos-move/framework/aptos-framework/sources/code.move @@ -13,6 +13,9 @@ module aptos_framework::code { use std::string; use aptos_framework::event; use aptos_framework::object::{Self, Object}; + use aptos_framework::permissioned_signer; + + friend aptos_framework::object_code_deployment; // ---------------------------------------------------------------------- // Code Publishing @@ -105,6 +108,24 @@ module aptos_framework::code { /// `code_object` does not exist. const ECODE_OBJECT_DOES_NOT_EXIST: u64 = 0xA; + /// Current permissioned signer cannot publish codes. + const ENO_CODE_PERMISSION: u64 = 0xB; + + struct CodePublishingPermission has copy, drop, store {} + + /// Permissions + public(friend) fun check_code_publishing_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, CodePublishingPermission {}), + error::permission_denied(ENO_CODE_PERMISSION), + ); + } + + /// Grant permission to publish code on behalf of the master signer. + public fun grant_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, CodePublishingPermission {}) + } + /// Whether unconditional code upgrade with no compatibility check is allowed. This /// publication mode should only be used for modules which aren't shared with user others. /// The developer is responsible for not breaking memory layout of any resources he already @@ -145,6 +166,7 @@ module aptos_framework::code { /// Publishes a package at the given signer's address. The caller must provide package metadata describing the /// package. public fun publish_package(owner: &signer, pack: PackageMetadata, code: vector>) acquires PackageRegistry { + check_code_publishing_permission(owner); // Disallow incompatible upgrade mode. Governance can decide later if this should be reconsidered. assert!( pack.upgrade_policy.policy > upgrade_policy_arbitrary().policy, @@ -206,6 +228,7 @@ module aptos_framework::code { } public fun freeze_code_object(publisher: &signer, code_object: Object) acquires PackageRegistry { + check_code_publishing_permission(publisher); let code_object_addr = object::object_address(&code_object); assert!(exists(code_object_addr), error::not_found(ECODE_OBJECT_DOES_NOT_EXIST)); assert!( diff --git a/aptos-move/framework/aptos-framework/sources/code.spec.move b/aptos-move/framework/aptos-framework/sources/code.spec.move index f968e0dbbddc3..88c63ccb927d0 100644 --- a/aptos-move/framework/aptos-framework/sources/code.spec.move +++ b/aptos-move/framework/aptos-framework/sources/code.spec.move @@ -59,7 +59,7 @@ spec aptos_framework::code { /// spec module { pragma verify = true; - pragma aborts_if_is_strict; + pragma aborts_if_is_partial; } spec request_publish { @@ -72,6 +72,13 @@ spec aptos_framework::code { pragma opaque; } + spec schema AbortsIfPermissionedSigner { + use aptos_framework::permissioned_signer; + s: signer; + let perm = CodePublishingPermission {}; + aborts_if !permissioned_signer::spec_check_permission_exists(s, perm); + } + spec initialize(aptos_framework: &signer, package_owner: &signer, metadata: PackageMetadata) { let aptos_addr = signer::address_of(aptos_framework); let owner_addr = signer::address_of(package_owner); @@ -86,6 +93,7 @@ spec aptos_framework::code { let addr = signer::address_of(owner); modifies global(addr); aborts_if pack.upgrade_policy.policy <= upgrade_policy_arbitrary().policy; + // include AbortsIfPermissionedSigner { s: owner }; } spec publish_package_txn { @@ -125,6 +133,7 @@ spec aptos_framework::code { aborts_if !exists(code_object_addr); aborts_if !exists(code_object_addr); aborts_if !object::is_owner(code_object, signer::address_of(publisher)); + // include AbortsIfPermissionedSigner { s: publisher }; modifies global(code_object_addr); } diff --git a/aptos-move/framework/aptos-framework/sources/coin.move b/aptos-move/framework/aptos-framework/sources/coin.move index ce9d5b8230ca9..159ae64b7207d 100644 --- a/aptos-move/framework/aptos-framework/sources/coin.move +++ b/aptos-move/framework/aptos-framework/sources/coin.move @@ -13,6 +13,7 @@ module aptos_framework::coin { use aptos_framework::event::{Self, EventHandle}; use aptos_framework::guid; use aptos_framework::optional_aggregator::{Self, OptionalAggregator}; + use aptos_framework::permissioned_signer; use aptos_framework::system_addresses; use aptos_framework::fungible_asset::{Self, FungibleAsset, Metadata, MintRef, TransferRef, BurnRef}; @@ -206,14 +207,26 @@ module aptos_framework::coin { } + #[deprecated] #[event] /// Module event emitted when the event handles related to coin store is deleted. + /// + /// Deprecated: replaced with CoinStoreDeletion struct CoinEventHandleDeletion has drop, store { event_handle_creation_address: address, deleted_deposit_event_handle_creation_number: u64, deleted_withdraw_event_handle_creation_number: u64, } + #[event] + /// Module event emitted when the event handles related to coin store is deleted. + struct CoinStoreDeletion has drop, store { + coin_type: String, + event_handle_creation_address: address, + deleted_deposit_event_handle_creation_number: u64, + deleted_withdraw_event_handle_creation_number: u64, + } + #[event] /// Module event emitted when a new pair of coin and fungible asset is created. struct PairCreation has drop, store { @@ -568,12 +581,14 @@ module aptos_framework::coin { let metadata = ensure_paired_metadata(); let store = primary_fungible_store::ensure_primary_store_exists(account, metadata); + let store_address = object::object_address(&store); if (exists>(account)) { let CoinStore { coin, frozen, deposit_events, withdraw_events } = move_from>( account ); event::emit( - CoinEventHandleDeletion { + CoinStoreDeletion { + coin_type: type_info::type_name(), event_handle_creation_address: guid::creator_address( event::guid(&deposit_events) ), @@ -597,13 +612,31 @@ module aptos_framework::coin { fungible_asset::set_frozen_flag_internal(store, frozen); } }; + if (!exists(store_address)) { + move_to(&create_signer::create_signer(store_address), MigrationFlag {}); + } + } + + inline fun assert_signer_has_permission(account: &signer) { + if(permissioned_signer::is_permissioned_signer(account)) { + fungible_asset::withdraw_permission_check_by_address( + account, + primary_fungible_store::primary_store_address( + signer::address_of(account), + ensure_paired_metadata() + ), + 0 + ); + } } /// Voluntarily migrate to fungible store for `CoinType` if not yet. public entry fun migrate_to_fungible_store( account: &signer ) acquires CoinStore, CoinConversionMap, CoinInfo { - maybe_convert_to_fungible_store(signer::address_of(account)); + let account_addr = signer::address_of(account); + assert_signer_has_permission(account); + maybe_convert_to_fungible_store(account_addr); } /// Migrate to fungible store for `CoinType` if not yet. @@ -825,17 +858,32 @@ module aptos_framework::coin { } } + public fun deposit_with_signer( + account: &signer, + coin: Coin + ) acquires CoinStore, CoinConversionMap, CoinInfo { + let metadata = ensure_paired_metadata(); + let account_address = signer::address_of(account); + fungible_asset::refill_permission( + account, + coin.value, + primary_fungible_store::primary_store_address_inlined( + account_address, + metadata, + ) + ); + deposit(account_address, coin); + } + inline fun can_receive_paired_fungible_asset( account_address: address, metadata: Object ): bool { - (features::new_accounts_default_to_fa_apt_store_enabled() && object::object_address(&metadata) == @0xa) || { - let primary_store_address = primary_fungible_store::primary_store_address( - account_address, - metadata - ); - fungible_asset::store_exists(primary_store_address) - } + let primary_store_address = primary_fungible_store::primary_store_address(account_address, metadata); + fungible_asset::store_exists(primary_store_address) && ( + // migration flag is needed, until we start defaulting new accounts to APT PFS + features::new_accounts_default_to_fa_apt_store_enabled() || exists(primary_store_address) + ) } /// Deposit the coin balance into the recipient's account without checking if the account is frozen. @@ -855,7 +903,7 @@ module aptos_framework::coin { )) { let fa = coin_to_fungible_asset(coin); let metadata = fungible_asset::asset_metadata(&fa); - let store = primary_fungible_store::ensure_primary_store_exists(account_addr, metadata); + let store = primary_fungible_store::primary_store(account_addr, metadata); fungible_asset::unchecked_deposit_with_no_events(object::object_address(&store), fa); } else { abort error::not_found(ECOIN_STORE_NOT_PUBLISHED) @@ -935,7 +983,7 @@ module aptos_framework::coin { symbol: string::String, decimals: u8, monitor_supply: bool, - ): (BurnCapability, FreezeCapability, MintCapability) { + ): (BurnCapability, FreezeCapability, MintCapability) acquires CoinInfo, CoinConversionMap { initialize_internal(account, name, symbol, decimals, monitor_supply, false) } @@ -946,7 +994,7 @@ module aptos_framework::coin { symbol: string::String, decimals: u8, monitor_supply: bool, - ): (BurnCapability, FreezeCapability, MintCapability) { + ): (BurnCapability, FreezeCapability, MintCapability) acquires CoinInfo, CoinConversionMap { system_addresses::assert_aptos_framework(account); initialize_internal(account, name, symbol, decimals, monitor_supply, true) } @@ -958,8 +1006,9 @@ module aptos_framework::coin { decimals: u8, monitor_supply: bool, parallelizable: bool, - ): (BurnCapability, FreezeCapability, MintCapability) { + ): (BurnCapability, FreezeCapability, MintCapability) acquires CoinInfo, CoinConversionMap { let account_addr = signer::address_of(account); + assert_signer_has_permission(account); assert!( coin_address() == account_addr, @@ -1015,8 +1064,9 @@ module aptos_framework::coin { mint_internal(amount) } - public fun register(account: &signer) acquires CoinConversionMap { + public fun register(account: &signer) acquires CoinInfo, CoinConversionMap { let account_addr = signer::address_of(account); + assert_signer_has_permission(account); // Short-circuit and do nothing if account is already registered for CoinType. if (is_account_registered(account_addr)) { return @@ -1059,6 +1109,17 @@ module aptos_framework::coin { amount ); let withdrawn_coin = if (coin_amount_to_withdraw > 0) { + let metadata = ensure_paired_metadata(); + if(permissioned_signer::is_permissioned_signer(account)) { + // Perform the check only if the account is a permissioned signer to save the cost of + // computing the primary store location. + fungible_asset::withdraw_permission_check_by_address( + account, + primary_fungible_store::primary_store_address(account_addr, metadata), + coin_amount_to_withdraw + ); + }; + let coin_store = borrow_global_mut>(account_addr); assert!( !coin_store.frozen, @@ -1203,7 +1264,7 @@ module aptos_framework::coin { account: &signer, decimals: u8, monitor_supply: bool, - ): (BurnCapability, FreezeCapability, MintCapability) { + ): (BurnCapability, FreezeCapability, MintCapability) acquires CoinInfo, CoinConversionMap { aggregator_factory::initialize_aggregator_factory_for_test(account); initialize( account, @@ -1219,7 +1280,7 @@ module aptos_framework::coin { account: &signer, decimals: u8, monitor_supply: bool, - ): (BurnCapability, FreezeCapability, MintCapability) { + ): (BurnCapability, FreezeCapability, MintCapability) acquires CoinInfo, CoinConversionMap { let (burn_cap, freeze_cap, mint_cap) = initialize_fake_money( account, decimals, @@ -1336,7 +1397,7 @@ module aptos_framework::coin { #[test(source = @0x2, framework = @aptos_framework)] #[expected_failure(abort_code = 0x10001, location = Self)] - public fun fail_initialize(source: signer, framework: signer) { + public fun fail_initialize(source: signer, framework: signer) acquires CoinInfo, CoinConversionMap { aggregator_factory::initialize_aggregator_factory_for_test(&framework); let (burn_cap, freeze_cap, mint_cap) = initialize( &source, @@ -1433,7 +1494,7 @@ module aptos_framework::coin { #[expected_failure(abort_code = 0x10007, location = Self)] public fun test_destroy_non_zero( source: signer, - ) acquires CoinInfo { + ) acquires CoinInfo, CoinConversionMap { account::create_account_for_test(signer::address_of(&source)); let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(&source, 1, true); let coins_minted = mint(100, &mint_cap); @@ -1473,7 +1534,7 @@ module aptos_framework::coin { } #[test(source = @0x1)] - public fun test_is_coin_initialized(source: signer) { + public fun test_is_coin_initialized(source: signer) acquires CoinInfo, CoinConversionMap { assert!(!is_coin_initialized(), 0); let (burn_cap, freeze_cap, mint_cap) = initialize_fake_money(&source, 1, true); @@ -1599,7 +1660,7 @@ module aptos_framework::coin { } #[test_only] - fun initialize_with_aggregator(account: &signer) { + fun initialize_with_aggregator(account: &signer) acquires CoinInfo, CoinConversionMap { let (burn_cap, freeze_cap, mint_cap) = initialize_with_parallelizable_supply( account, string::utf8(b"Fake money"), @@ -1615,7 +1676,7 @@ module aptos_framework::coin { } #[test_only] - fun initialize_with_integer(account: &signer) { + fun initialize_with_integer(account: &signer) acquires CoinInfo, CoinConversionMap { let (burn_cap, freeze_cap, mint_cap) = initialize( account, string::utf8(b"Fake money"), @@ -1633,14 +1694,14 @@ module aptos_framework::coin { #[test(framework = @aptos_framework, other = @0x123)] #[expected_failure(abort_code = 0x50003, location = aptos_framework::system_addresses)] - fun test_supply_initialize_fails(framework: signer, other: signer) { + fun test_supply_initialize_fails(framework: signer, other: signer) acquires CoinInfo, CoinConversionMap { aggregator_factory::initialize_aggregator_factory_for_test(&framework); initialize_with_aggregator(&other); } #[test(other = @0x123)] #[expected_failure(abort_code = 0x10003, location = Self)] - fun test_create_coin_store_with_non_coin_type(other: signer) acquires CoinConversionMap { + fun test_create_coin_store_with_non_coin_type(other: signer) acquires CoinInfo, CoinConversionMap { register(&other); } @@ -1651,7 +1712,7 @@ module aptos_framework::coin { } #[test(framework = @aptos_framework)] - fun test_supply_initialize(framework: signer) acquires CoinInfo { + fun test_supply_initialize(framework: signer) acquires CoinInfo, CoinConversionMap { aggregator_factory::initialize_aggregator_factory_for_test(&framework); initialize_with_aggregator(&framework); @@ -1673,7 +1734,7 @@ module aptos_framework::coin { #[test(framework = @aptos_framework)] #[expected_failure(abort_code = 0x20001, location = aptos_framework::aggregator)] - fun test_supply_overflow(framework: signer) acquires CoinInfo { + fun test_supply_overflow(framework: signer) acquires CoinInfo, CoinConversionMap { aggregator_factory::initialize_aggregator_factory_for_test(&framework); initialize_with_aggregator(&framework); @@ -1911,6 +1972,7 @@ module aptos_framework::coin { } #[test(account = @aptos_framework, aaron = @0xaa10, bob = @0xb0b)] + #[expected_failure(abort_code = 0x60005, location = Self)] fun test_force_deposit( account: &signer, aaron: &signer, @@ -1924,7 +1986,6 @@ module aptos_framework::coin { account::create_account_for_test(bob_addr); let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(account, 1, true); maybe_convert_to_fungible_store(aaron_addr); - maybe_convert_to_fungible_store(bob_addr); deposit(aaron_addr, mint(1, &mint_cap)); force_deposit(account_addr, mint(100, &mint_cap)); @@ -1954,8 +2015,6 @@ module aptos_framework::coin { account::create_account_for_test(account_addr); account::create_account_for_test(aaron_addr); account::create_account_for_test(bob_addr); - let feature = features::get_new_accounts_default_to_fa_apt_store_feature(); - features::change_feature_flags_for_testing(account, vector[], vector[feature]); let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(account, 1, true); assert!(coin_store_exists(account_addr), 0); @@ -1964,13 +2023,6 @@ module aptos_framework::coin { assert!(!coin_store_exists(aaron_addr), 0); assert!(!is_account_registered(aaron_addr), 0); - register(bob); - assert!(coin_store_exists(bob_addr), 0); - maybe_convert_to_fungible_store(bob_addr); - assert!(!coin_store_exists(bob_addr), 0); - register(bob); - assert!(!coin_store_exists(bob_addr), 0); - maybe_convert_to_fungible_store(aaron_addr); let coin = mint(100, &mint_cap); deposit(aaron_addr, coin); @@ -1982,8 +2034,15 @@ module aptos_framework::coin { assert!(!coin_store_exists(account_addr), 0); assert!(is_account_registered(account_addr), 0); + // Deposit FA to bob to created primary fungible store without `MigrationFlag`. primary_fungible_store::deposit(bob_addr, coin_to_fungible_asset(mint(100, &mint_cap))); assert!(!coin_store_exists(bob_addr), 0); + register(bob); + assert!(coin_store_exists(bob_addr), 0); + maybe_convert_to_fungible_store(bob_addr); + assert!(!coin_store_exists(bob_addr), 0); + register(bob); + assert!(!coin_store_exists(bob_addr), 0); move_to(account, FakeMoneyCapabilities { burn_cap, @@ -2005,8 +2064,9 @@ module aptos_framework::coin { assert!(coin_balance(account_addr) == 0, 0); assert!(balance(account_addr) == 100, 0); let coin = withdraw(account, 50); - assert!(can_receive_paired_fungible_asset(account_addr, ensure_paired_metadata()), 0); + assert!(!can_receive_paired_fungible_asset(account_addr, ensure_paired_metadata()), 0); maybe_convert_to_fungible_store(account_addr); + assert!(can_receive_paired_fungible_asset(account_addr, ensure_paired_metadata()), 0); deposit(account_addr, coin); assert!(coin_balance(account_addr) == 0, 0); assert!(balance(account_addr) == 100, 0); @@ -2018,8 +2078,227 @@ module aptos_framework::coin { }); } - #[deprecated] #[resource_group_member(group = aptos_framework::object::ObjectGroup)] /// The flag the existence of which indicates the primary fungible store is created by the migration from CoinStore. struct MigrationFlag has key {} + + #[test(account = @aptos_framework)] + #[expected_failure(abort_code = 0x50024, location = aptos_framework::fungible_asset)] + fun test_withdraw_with_permissioned_signer_no_migration( + account: &signer, + ) acquires CoinConversionMap, CoinInfo, CoinStore, PairedCoinType { + account::create_account_for_test(signer::address_of(account)); + let account_addr = signer::address_of(account); + let (burn_cap, freeze_cap, mint_cap) = initialize_fake_money(account, 1, true); + create_coin_store(account); + create_coin_conversion_map(account); + + let coin = mint(100, &mint_cap); + deposit(account_addr, coin); + + let permissioned_handle = permissioned_signer::create_permissioned_handle(account); + let permissioned_signer = permissioned_signer::signer_from_permissioned_handle(&permissioned_handle); + + // Withdraw from permissioned signer with no migration rules set + // + // Aborted with error. + let coin_2 = withdraw(&permissioned_signer, 10); + permissioned_signer::destroy_permissioned_handle(permissioned_handle); + + burn(coin_2, &burn_cap); + move_to(account, FakeMoneyCapabilities { + burn_cap, + freeze_cap, + mint_cap, + }); + } + + #[test(account = @aptos_framework)] + #[expected_failure(abort_code = 0x50024, location = aptos_framework::fungible_asset)] + fun test_withdraw_with_permissioned_signer( + account: &signer, + ) acquires CoinConversionMap, CoinInfo, CoinStore, PairedCoinType { + account::create_account_for_test(signer::address_of(account)); + let account_addr = signer::address_of(account); + let (burn_cap, freeze_cap, mint_cap) = initialize_fake_money(account, 1, true); + create_coin_store(account); + create_coin_conversion_map(account); + + let coin = mint(100, &mint_cap); + deposit(account_addr, coin); + + let permissioned_handle = permissioned_signer::create_permissioned_handle(account); + let permissioned_signer = permissioned_signer::signer_from_permissioned_handle(&permissioned_handle); + + // Withdraw from permissioned signer with no migration rules set + // + // Aborted with error. + let coin_2 = withdraw(&permissioned_signer, 10); + permissioned_signer::destroy_permissioned_handle(permissioned_handle); + + burn(coin_2, &burn_cap); + move_to(account, FakeMoneyCapabilities { + burn_cap, + freeze_cap, + mint_cap, + }); + } + + #[test(account = @aptos_framework)] + #[expected_failure(abort_code = 0x50024, location = aptos_framework::fungible_asset)] + fun test_withdraw_with_permissioned_signer_no_capacity( + account: &signer, + ) acquires CoinConversionMap, CoinInfo, CoinStore, PairedCoinType { + account::create_account_for_test(signer::address_of(account)); + let account_addr = signer::address_of(account); + let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(account, 1, true); + ensure_paired_metadata(); + + let coin = mint(100, &mint_cap); + deposit(account_addr, coin); + + let permissioned_handle = permissioned_signer::create_permissioned_handle(account); + let permissioned_signer = permissioned_signer::signer_from_permissioned_handle(&permissioned_handle); + + // Withdraw from permissioned signer with no permissions granted. + let coin_2 = withdraw(&permissioned_signer, 10); + permissioned_signer::destroy_permissioned_handle(permissioned_handle); + + burn(coin_2, &burn_cap); + move_to(account, FakeMoneyCapabilities { + burn_cap, + freeze_cap, + mint_cap, + }); + } + + #[test(account = @aptos_framework)] + fun test_e2e_withdraw_with_permissioned_signer_and_migration( + account: &signer, + ) acquires CoinConversionMap, CoinInfo, CoinStore, PairedCoinType { + account::create_account_for_test(signer::address_of(account)); + let account_addr = signer::address_of(account); + let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(account, 1, true); + let metadata = ensure_paired_metadata(); + + let coin = mint(100, &mint_cap); + deposit(account_addr, coin); + + let permissioned_handle = permissioned_signer::create_permissioned_handle(account); + let permissioned_signer = permissioned_signer::signer_from_permissioned_handle(&permissioned_handle); + primary_fungible_store::grant_permission(account, &permissioned_signer, metadata, 10); + + // Withdraw from permissioned signer with proper permissions. + let coin_2 = withdraw(&permissioned_signer, 10); + burn(coin_2, &burn_cap); + + // Withdraw with some funds from CoinStore and some from PFS. + primary_fungible_store::deposit(account_addr, coin_to_fungible_asset(mint(100, &mint_cap))); + primary_fungible_store::grant_permission(account, &permissioned_signer, metadata, 100); + let coin_2 = withdraw(&permissioned_signer, 100); + burn(coin_2, &burn_cap); + + // Withdraw funds from PFS only. + assert!(coin_balance(account_addr) == 0, 1); + primary_fungible_store::grant_permission(account, &permissioned_signer, metadata, 10); + let coin_2 = withdraw(&permissioned_signer, 10); + burn(coin_2, &burn_cap); + + permissioned_signer::destroy_permissioned_handle(permissioned_handle); + move_to(account, FakeMoneyCapabilities { + burn_cap, + freeze_cap, + mint_cap, + }); + } + + #[test(account = @aptos_framework)] + #[expected_failure(abort_code = 0x50024, location = aptos_framework::fungible_asset)] + fun test_e2e_withdraw_with_permissioned_signer_no_permission_1( + account: &signer, + ) acquires CoinConversionMap, CoinInfo, CoinStore, PairedCoinType { + account::create_account_for_test(signer::address_of(account)); + let account_addr = signer::address_of(account); + let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(account, 1, true); + let metadata = ensure_paired_metadata(); + + let coin = mint(100, &mint_cap); + deposit(account_addr, coin); + + let permissioned_handle = permissioned_signer::create_permissioned_handle(account); + let permissioned_signer = permissioned_signer::signer_from_permissioned_handle(&permissioned_handle); + primary_fungible_store::grant_permission(account, &permissioned_signer, metadata, 10); + + let coin_2 = withdraw(&permissioned_signer, 20); + burn(coin_2, &burn_cap); + + permissioned_signer::destroy_permissioned_handle(permissioned_handle); + move_to(account, FakeMoneyCapabilities { + burn_cap, + freeze_cap, + mint_cap, + }); + } + + #[test(account = @aptos_framework)] + #[expected_failure(abort_code = 0x50024, location = aptos_framework::fungible_asset)] + fun test_e2e_withdraw_with_permissioned_signer_no_permission_2( + account: &signer, + ) acquires CoinConversionMap, CoinInfo, CoinStore, PairedCoinType { + account::create_account_for_test(signer::address_of(account)); + let account_addr = signer::address_of(account); + let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(account, 1, true); + let metadata = ensure_paired_metadata(); + + let coin = mint(100, &mint_cap); + deposit(account_addr, coin); + + let permissioned_handle = permissioned_signer::create_permissioned_handle(account); + let permissioned_signer = permissioned_signer::signer_from_permissioned_handle(&permissioned_handle); + primary_fungible_store::grant_permission(account, &permissioned_signer, metadata, 10); + + // Withdraw from permissioned signer with proper permissions. + let coin_2 = withdraw(&permissioned_signer, 10); + burn(coin_2, &burn_cap); + + // Withdraw with some funds from CoinStore and some from PFS. + primary_fungible_store::deposit(account_addr, coin_to_fungible_asset(mint(100, &mint_cap))); + primary_fungible_store::grant_permission(account, &permissioned_signer, metadata, 90); + let coin_2 = withdraw(&permissioned_signer, 100); + burn(coin_2, &burn_cap); + + permissioned_signer::destroy_permissioned_handle(permissioned_handle); + move_to(account, FakeMoneyCapabilities { + burn_cap, + freeze_cap, + mint_cap, + }); + } + + #[test(account = @aptos_framework)] + #[expected_failure(abort_code = 0x50024, location = aptos_framework::fungible_asset)] + fun test_e2e_withdraw_with_permissioned_signer_no_permission_3( + account: &signer, + ) acquires CoinConversionMap, CoinInfo, CoinStore, PairedCoinType { + account::create_account_for_test(signer::address_of(account)); + let account_addr = signer::address_of(account); + let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(account, 1, true); + let metadata = ensure_paired_metadata(); + + let permissioned_handle = permissioned_signer::create_permissioned_handle(account); + let permissioned_signer = permissioned_signer::signer_from_permissioned_handle(&permissioned_handle); + + // Withdraw with some funds from PFS only. + primary_fungible_store::deposit(account_addr, coin_to_fungible_asset(mint(100, &mint_cap))); + primary_fungible_store::grant_permission(account, &permissioned_signer, metadata, 90); + let coin_2 = withdraw(&permissioned_signer, 100); + burn(coin_2, &burn_cap); + + permissioned_signer::destroy_permissioned_handle(permissioned_handle); + move_to(account, FakeMoneyCapabilities { + burn_cap, + freeze_cap, + mint_cap, + }); + } } diff --git a/aptos-move/framework/aptos-framework/sources/coin.spec.move b/aptos-move/framework/aptos-framework/sources/coin.spec.move index b43c5850ec882..0ccf01d2dd194 100644 --- a/aptos-move/framework/aptos-framework/sources/coin.spec.move +++ b/aptos-move/framework/aptos-framework/sources/coin.spec.move @@ -60,6 +60,7 @@ spec aptos_framework::coin { /// spec module { pragma verify = true; + pragma aborts_if_is_partial; global supply: num; global aggregate_supply: num; apply TotalSupplyTracked to * except diff --git a/aptos-move/framework/aptos-framework/sources/create_signer.move b/aptos-move/framework/aptos-framework/sources/create_signer.move index 3da0c50c904f0..8bea49055b469 100644 --- a/aptos-move/framework/aptos-framework/sources/create_signer.move +++ b/aptos-move/framework/aptos-framework/sources/create_signer.move @@ -14,8 +14,11 @@ module aptos_framework::create_signer { friend aptos_framework::coin; friend aptos_framework::fungible_asset; friend aptos_framework::genesis; + friend aptos_framework::account_abstraction; friend aptos_framework::multisig_account; friend aptos_framework::object; + friend aptos_framework::permissioned_signer; + friend aptos_framework::transaction_validation; public(friend) native fun create_signer(addr: address): signer; } diff --git a/aptos-move/framework/aptos-framework/sources/create_signer.spec.move b/aptos-move/framework/aptos-framework/sources/create_signer.spec.move index 1bb4c0ffa9fd6..dab59d30da2db 100644 --- a/aptos-move/framework/aptos-framework/sources/create_signer.spec.move +++ b/aptos-move/framework/aptos-framework/sources/create_signer.spec.move @@ -41,5 +41,8 @@ spec aptos_framework::create_signer { pragma opaque; aborts_if [abstract] false; ensures [abstract] signer::address_of(result) == addr; + ensures [abstract] result == spec_create_signer(addr); } + + spec fun spec_create_signer(addr: address): signer; } diff --git a/aptos-move/framework/aptos-stdlib/sources/data_structures/big_ordered_map.move b/aptos-move/framework/aptos-framework/sources/datastructures/big_ordered_map.move similarity index 94% rename from aptos-move/framework/aptos-stdlib/sources/data_structures/big_ordered_map.move rename to aptos-move/framework/aptos-framework/sources/datastructures/big_ordered_map.move index 13db9c30033fd..f92bbe100493c 100644 --- a/aptos-move/framework/aptos-stdlib/sources/data_structures/big_ordered_map.move +++ b/aptos-move/framework/aptos-framework/sources/datastructures/big_ordered_map.move @@ -29,6 +29,8 @@ module aptos_std::big_ordered_map { use aptos_std::storage_slots_allocator::{Self, StorageSlotsAllocator, StoredSlot}; use aptos_std::math64::{max, min}; + friend aptos_framework::permissioned_signer; + // Error constants shared with ordered_map (so try using same values) /// Map key already exists @@ -201,7 +203,7 @@ module aptos_std::big_ordered_map { root.destroy_empty_node(); // If root node is empty, then we know that no storage slots are used, // and so we can safely destroy all nodes. - nodes.destroy_known_empty_unsafe(); + nodes.destroy_empty(); } // ======================= Section with Modifiers ========================= @@ -310,7 +312,13 @@ module aptos_std::big_ordered_map { public fun borrow(self: &BigOrderedMap, key: &K): &V { let iter = self.find(key); assert!(!iter.iter_is_end(self), error::invalid_argument(EKEY_NOT_FOUND)); - iter.iter_borrow(self) + + // TODO cannot call iter_borrow, because reference checks assume return has reference to iter that is being destroyed + // iter.iter_borrow(self) + + assert!(!iter.iter_is_end(self), error::invalid_argument(EITER_OUT_OF_BOUNDS)); + let children = &self.borrow_node(iter.node_index).children; + &iter.child_iter.iter_borrow(children).value } /// Returns a mutable reference to the element with its key at the given index, aborts if the key is not found. @@ -365,7 +373,7 @@ module aptos_std::big_ordered_map { /// Borrows the value given iterator points to. /// Aborts with EITER_OUT_OF_BOUNDS if iterator is pointing to the end. /// Note: Requires that the map is not changed after the input iterator is generated. - public(friend) fun iter_borrow(self: IteratorPtr, map: &BigOrderedMap): &V { + public(friend) fun iter_borrow(self: &IteratorPtr, map: &BigOrderedMap): &V { assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS)); let children = &map.borrow_node(self.node_index).children; &self.child_iter.iter_borrow(children).value @@ -376,7 +384,7 @@ module aptos_std::big_ordered_map { /// Aborts with EBORROW_MUT_REQUIRES_CONSTANT_KV_SIZE if KV size doesn't have constant size, /// because if it doesn't - we need to call `upsert` to be able to check size invariants after modification. /// Note: Requires that the map is not changed after the input iterator is generated. - public(friend) fun iter_borrow_mut(self: IteratorPtr, map: &mut BigOrderedMap): &mut V { + public(friend) fun iter_borrow_mut(self: &IteratorPtr, map: &mut BigOrderedMap): &mut V { assert!(map.constant_kv_size, error::invalid_argument(EBORROW_MUT_REQUIRES_CONSTANT_KV_SIZE)); assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS)); let children = &mut map.borrow_node_mut(self.node_index).children; @@ -443,6 +451,36 @@ module aptos_std::big_ordered_map { new_iter(prev_index, child_iter, iter_key) } + /// Apply the function to each element in the vector, consuming it. + public(friend) inline fun for_each(self: BigOrderedMap, f: |K, V|) { + // TODO - this can be done more efficiently, by destroying the leaves directly + // but that requires more complicated code and testing. + let it = self.new_begin_iter(); + while (!it.iter_is_end(&self)) { + let k = *it.iter_borrow_key(); + let v = self.remove(&k); + f(k, v); + it = self.new_begin_iter(); + }; + destroy_empty(self) + } + + /// Apply the function to a reference of each element in the vector. + public(friend) inline fun for_each_ref(self: &BigOrderedMap, f: |&K, &V|) { + let it = self.new_begin_iter(); + while (!it.iter_is_end(self)) { + f(it.iter_borrow_key(), it.iter_borrow(self)); + it = it.iter_next(self); + }; + } + + /// Destroy a map, by destroying elements individually. + public(friend) inline fun destroy(self: BigOrderedMap, dv: |V|) { + for_each(self, |_k, v| { + dv(v); + }); + } + // ====================== Internal Implementations ======================== /// Borrow a node, given an index. Works for both root (i.e. inline) node and separately stored nodes @@ -1118,7 +1156,7 @@ module aptos_std::big_ordered_map { } #[test_only] - fun destroy(self: BigOrderedMap) { + fun destroy_and_validate(self: BigOrderedMap) { let it = new_begin_iter(&self); while (!it.iter_is_end(&self)) { remove(&mut self, it.iter_borrow_key()); @@ -1213,9 +1251,19 @@ module aptos_std::big_ordered_map { add(&mut map, 5, 5); map.print_map(); map.validate_map(); add(&mut map, 6, 6); map.print_map(); map.validate_map(); - vector::zip(vector[1, 2, 3, 4, 5, 6], vector[1, 2, 3, 8, 5, 6], |key, value| { - assert!(map.borrow(&key) == &value, key + 100); - assert!(map.borrow_mut(&key) == &value, key + 200); + let expected_keys = vector[1, 2, 3, 4, 5, 6]; + let expected_values = vector[1, 2, 3, 8, 5, 6]; + + let index = 0; + map.for_each_ref(|k, v| { + assert!(k == expected_keys.borrow(index), *k + 100); + assert!(v == expected_values.borrow(index), *k + 200); + index += 1; + }); + + vector::zip(expected_keys, expected_values, |key, value| { + assert!(map.borrow(&key) == &value, key + 300); + assert!(map.borrow_mut(&key) == &value, key + 400); }); remove(&mut map, &5); map.print_map(); map.validate_map(); @@ -1228,6 +1276,20 @@ module aptos_std::big_ordered_map { destroy_empty(map); } + #[test] + fun test_for_each() { + let map = new_with_config(4, 3, false, 0); + map.add_all(vector[1, 3, 6, 2, 9, 5, 7, 4, 8], vector[1, 3, 6, 2, 9, 5, 7, 4, 8]); + + let expected = vector[1, 2, 3, 4, 5, 6, 7, 8, 9]; + let index = 0; + map.for_each(|k, v| { + assert!(k == expected[index], k + 100); + assert!(v == expected[index], k + 200); + index += 1; + }); + } + #[test] fun test_variable_size() { let map = new_with_config, vector>(0, 0, false, 0); @@ -1323,7 +1385,7 @@ module aptos_std::big_ordered_map { it = it.iter_next(&map); }; - destroy(map); + map.destroy(|_v| {}); } #[test] @@ -1345,7 +1407,7 @@ module aptos_std::big_ordered_map { assert!(find(&map, &4).iter_is_end(&map), 0); assert!(find(&map, &9).iter_is_end(&map), 1); - destroy(map); + map.destroy(|_v| {}); } #[test] @@ -1375,7 +1437,7 @@ module aptos_std::big_ordered_map { assert!(lower_bound(&map, &3).key == 6, 5); assert!(lower_bound(&map, &4).key == 6, 6); - map.destroy(); + map.destroy(|_v| {}); } #[test] @@ -1389,28 +1451,28 @@ module aptos_std::big_ordered_map { let missing = vector[0, 2, 4, 6, 8, 10]; missing.for_each_ref(|i| assert!(!map.contains(i), *i)); - map.destroy(); + map.destroy(|_v| {}); } #[test] #[expected_failure(abort_code = 0x1000B, location = Self)] /// EINVALID_CONFIG_PARAMETER fun test_inner_max_degree_too_large() { let map = new_with_config(4097, 0, false, 0); - map.destroy(); + map.destroy_and_validate(); } #[test] #[expected_failure(abort_code = 0x1000B, location = Self)] /// EINVALID_CONFIG_PARAMETER fun test_inner_max_degree_too_small() { let map = new_with_config(3, 0, false, 0); - map.destroy(); + map.destroy_and_validate(); } #[test] #[expected_failure(abort_code = 0x1000B, location = Self)] /// EINVALID_CONFIG_PARAMETER fun test_leaf_max_degree_too_small() { let map = new_with_config(0, 2, false, 0); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1418,7 +1480,7 @@ module aptos_std::big_ordered_map { fun test_abort_add_existing_value() { let map = new_from(vector[1], vector[1]); map.add(1, 2); - map.destroy(); + map.destroy_and_validate(); } #[test_only] @@ -1436,7 +1498,7 @@ module aptos_std::big_ordered_map { let map = new_with_config(4, 4, false, 0); map.add_all(vector_range(1, 10), vector_range(1, 10)); map.add(3, 3); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1444,7 +1506,7 @@ module aptos_std::big_ordered_map { fun test_abort_remove_missing_value() { let map = new_from(vector[1], vector[1]); map.remove(&2); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1454,7 +1516,7 @@ module aptos_std::big_ordered_map { map.add_all(vector_range(1, 10), vector_range(1, 10)); map.remove(&4); map.remove(&4); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1463,7 +1525,7 @@ module aptos_std::big_ordered_map { let map = new_with_config(4, 4, false, 0); map.add_all(vector_range(1, 10), vector_range(1, 10)); map.remove(&11); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1471,7 +1533,7 @@ module aptos_std::big_ordered_map { fun test_abort_borrow_missing() { let map = new_from(vector[1], vector[1]); map.borrow(&2); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1479,7 +1541,7 @@ module aptos_std::big_ordered_map { fun test_abort_borrow_mut_missing() { let map = new_from(vector[1], vector[1]); map.borrow_mut(&2); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1488,7 +1550,7 @@ module aptos_std::big_ordered_map { let map = new_with_config(0, 0, false, 0); map.add(1, vector[1]); map.borrow_mut(&1); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1496,7 +1558,7 @@ module aptos_std::big_ordered_map { fun test_abort_iter_borrow_key_missing() { let map = new_from(vector[1], vector[1]); map.new_end_iter().iter_borrow_key(); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1504,7 +1566,7 @@ module aptos_std::big_ordered_map { fun test_abort_iter_borrow_missing() { let map = new_from(vector[1], vector[1]); map.new_end_iter().iter_borrow(&map); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1512,7 +1574,7 @@ module aptos_std::big_ordered_map { fun test_abort_iter_borrow_mut_missing() { let map = new_from(vector[1], vector[1]); map.new_end_iter().iter_borrow_mut(&mut map); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1521,7 +1583,7 @@ module aptos_std::big_ordered_map { let map = new_with_config(0, 0, false, 0); map.add(1, vector[1]); map.new_begin_iter().iter_borrow_mut(&mut map); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1529,7 +1591,7 @@ module aptos_std::big_ordered_map { fun test_abort_end_iter_next() { let map = new_from(vector[1, 2, 3], vector[1, 2, 3]); map.new_end_iter().iter_next(&map); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1537,7 +1599,7 @@ module aptos_std::big_ordered_map { fun test_abort_begin_iter_prev() { let map = new_from(vector[1, 2, 3], vector[1, 2, 3]); map.new_begin_iter().iter_prev(&map); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1553,7 +1615,7 @@ module aptos_std::big_ordered_map { let map = new_with_config(0, 0, false, 0); map.add(vector[1], 1); map.add(vector_range(0, 57), 1); - map.destroy(); + map.destroy_and_validate(); } #[test] @@ -1562,7 +1624,7 @@ module aptos_std::big_ordered_map { let map = new_with_config(0, 0, false, 0); map.add(1, vector[1]); map.add(2, vector_range(0, 107)); - map.destroy(); + map.destroy_and_validate(); } #[test_only] @@ -1595,7 +1657,7 @@ module aptos_std::big_ordered_map { }; }; }; - big_map.destroy(); + big_map.destroy_and_validate(); } #[test_only] diff --git a/aptos-move/framework/aptos-stdlib/sources/data_structures/ordered_map.move b/aptos-move/framework/aptos-framework/sources/datastructures/ordered_map.move similarity index 100% rename from aptos-move/framework/aptos-stdlib/sources/data_structures/ordered_map.move rename to aptos-move/framework/aptos-framework/sources/datastructures/ordered_map.move diff --git a/aptos-move/framework/aptos-framework/sources/delegation_pool.move b/aptos-move/framework/aptos-framework/sources/delegation_pool.move index 3b5cc7600f881..b02129fd40a3e 100644 --- a/aptos-move/framework/aptos-framework/sources/delegation_pool.move +++ b/aptos-move/framework/aptos-framework/sources/delegation_pool.move @@ -124,6 +124,7 @@ module aptos_framework::delegation_pool { use aptos_framework::aptos_governance; use aptos_framework::coin; use aptos_framework::event::{Self, EventHandle, emit}; + use aptos_framework::permissioned_signer; use aptos_framework::stake; use aptos_framework::stake::get_operator; use aptos_framework::staking_config; @@ -215,6 +216,9 @@ module aptos_framework::delegation_pool { /// Cannot unlock the accumulated active stake of NULL_SHAREHOLDER(0x0). const ECANNOT_UNLOCK_NULL_SHAREHOLDER: u64 = 27; + /// Signer does not have permission to perform delegation logic. + const ENO_DELEGATION_PERMISSION: u64 = 28; + const MAX_U64: u64 = 18446744073709551615; /// Maximum operator percentage fee(of double digit precision): 22.85% is represented as 2285 @@ -346,6 +350,11 @@ module aptos_framework::delegation_pool { allowlist: SmartTable, } + enum DelegationPermission has copy, drop, store { + DelegationPoolManagementPermission, + StakeManagementPermission, + } + #[event] struct AddStake has drop, store { pool_address: address, @@ -832,6 +841,29 @@ module aptos_framework::delegation_pool { allowlist } + /// Permissions + inline fun check_delegation_pool_management_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, DelegationPermission::DelegationPoolManagementPermission {}), + error::permission_denied(ENO_DELEGATION_PERMISSION), + ); + } + + public fun grant_delegation_pool_management_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, DelegationPermission::DelegationPoolManagementPermission {}) + } + + inline fun check_stake_management_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, DelegationPermission::StakeManagementPermission {}), + error::permission_denied(ENO_DELEGATION_PERMISSION), + ); + } + + public fun grant_stake_management_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, DelegationPermission::StakeManagementPermission {}) + } + /// Initialize a delegation pool of custom fixed `operator_commission_percentage`. /// A resource account is created from `owner` signer and its supplied `delegation_pool_creation_seed` /// to host the delegation pool resource and own the underlying stake pool. @@ -841,6 +873,7 @@ module aptos_framework::delegation_pool { operator_commission_percentage: u64, delegation_pool_creation_seed: vector, ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_delegation_pool_management_permission(owner); assert!(features::delegation_pools_enabled(), error::invalid_state(EDELEGATION_POOLS_DISABLED)); let owner_address = signer::address_of(owner); assert!(!owner_cap_exists(owner_address), error::already_exists(EOWNER_CAP_ALREADY_EXISTS)); @@ -941,6 +974,7 @@ module aptos_framework::delegation_pool { voting_power: u64, should_pass: bool ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_stake_management_permission(voter); assert_partial_governance_voting_enabled(pool_address); // synchronize delegation and stake pools before any user operation. synchronize_delegation_pool(pool_address); @@ -1001,6 +1035,7 @@ module aptos_framework::delegation_pool { metadata_hash: vector, is_multi_step_proposal: bool, ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_stake_management_permission(voter); assert_partial_governance_voting_enabled(pool_address); // synchronize delegation and stake pools before any user operation @@ -1293,6 +1328,7 @@ module aptos_framework::delegation_pool { owner: &signer, new_operator: address ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_delegation_pool_management_permission(owner); let pool_address = get_owned_pool_address(signer::address_of(owner)); // synchronize delegation and stake pools before any user operation // ensure the old operator is paid its uncommitted commission rewards @@ -1308,6 +1344,7 @@ module aptos_framework::delegation_pool { operator: &signer, new_beneficiary: address ) acquires BeneficiaryForOperator { + check_stake_management_permission(operator); assert!(features::operator_beneficiary_change_enabled(), std::error::invalid_state( EOPERATOR_BENEFICIARY_CHANGE_NOT_SUPPORTED )); @@ -1333,6 +1370,7 @@ module aptos_framework::delegation_pool { owner: &signer, new_commission_percentage: u64 ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_delegation_pool_management_permission(owner); assert!(features::commission_change_delegation_pool_enabled(), error::invalid_state( ECOMMISSION_RATE_CHANGE_NOT_SUPPORTED )); @@ -1378,6 +1416,7 @@ module aptos_framework::delegation_pool { owner: &signer, new_voter: address ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_delegation_pool_management_permission(owner); // No one can change delegated_voter once the partial governance voting feature is enabled. assert!( !features::delegation_pool_partial_governance_voting_enabled(), @@ -1396,6 +1435,7 @@ module aptos_framework::delegation_pool { pool_address: address, new_voter: address ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_stake_management_permission(delegator); assert_partial_governance_voting_enabled(pool_address); // synchronize delegation and stake pools before any user operation @@ -1453,6 +1493,7 @@ module aptos_framework::delegation_pool { public entry fun enable_delegators_allowlisting( owner: &signer, ) acquires DelegationPoolOwnership, DelegationPool { + check_delegation_pool_management_permission(owner); assert!( features::delegation_pool_allowlisting_enabled(), error::invalid_state(EDELEGATORS_ALLOWLISTING_NOT_SUPPORTED) @@ -1471,6 +1512,7 @@ module aptos_framework::delegation_pool { public entry fun disable_delegators_allowlisting( owner: &signer, ) acquires DelegationPoolOwnership, DelegationPoolAllowlisting { + check_delegation_pool_management_permission(owner); let pool_address = get_owned_pool_address(signer::address_of(owner)); assert_allowlisting_enabled(pool_address); @@ -1486,6 +1528,7 @@ module aptos_framework::delegation_pool { owner: &signer, delegator_address: address, ) acquires DelegationPoolOwnership, DelegationPoolAllowlisting { + check_delegation_pool_management_permission(owner); let pool_address = get_owned_pool_address(signer::address_of(owner)); assert_allowlisting_enabled(pool_address); @@ -1501,6 +1544,7 @@ module aptos_framework::delegation_pool { owner: &signer, delegator_address: address, ) acquires DelegationPoolOwnership, DelegationPoolAllowlisting { + check_delegation_pool_management_permission(owner); let pool_address = get_owned_pool_address(signer::address_of(owner)); assert_allowlisting_enabled(pool_address); @@ -1516,6 +1560,7 @@ module aptos_framework::delegation_pool { owner: &signer, delegator_address: address, ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { + check_delegation_pool_management_permission(owner); let pool_address = get_owned_pool_address(signer::address_of(owner)); assert_allowlisting_enabled(pool_address); assert!( @@ -1540,6 +1585,7 @@ module aptos_framework::delegation_pool { pool_address: address, amount: u64 ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { + check_stake_management_permission(delegator); // short-circuit if amount to add is 0 so no event is emitted if (amount == 0) { return }; @@ -1597,6 +1643,7 @@ module aptos_framework::delegation_pool { pool_address: address, amount: u64 ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_stake_management_permission(delegator); // short-circuit if amount to unlock is 0 so no event is emitted if (amount == 0) { return }; @@ -1658,6 +1705,7 @@ module aptos_framework::delegation_pool { pool_address: address, amount: u64 ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage, DelegationPoolAllowlisting { + check_stake_management_permission(delegator); // short-circuit if amount to reactivate is 0 so no event is emitted if (amount == 0) { return }; @@ -1708,6 +1756,7 @@ module aptos_framework::delegation_pool { pool_address: address, amount: u64 ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + check_stake_management_permission(delegator); assert!(amount > 0, error::invalid_argument(EWITHDRAW_ZERO_STAKE)); // synchronize delegation and stake pools before any user operation synchronize_delegation_pool(pool_address); diff --git a/aptos-move/framework/aptos-framework/sources/dispatchable_fungible_asset.move b/aptos-move/framework/aptos-framework/sources/dispatchable_fungible_asset.move index 496fdf610ab89..40087d979bf76 100644 --- a/aptos-move/framework/aptos-framework/sources/dispatchable_fungible_asset.move +++ b/aptos-move/framework/aptos-framework/sources/dispatchable_fungible_asset.move @@ -77,6 +77,7 @@ module aptos_framework::dispatchable_fungible_asset { amount: u64, ): FungibleAsset acquires TransferRefStore { fungible_asset::withdraw_sanity_check(owner, store, false); + fungible_asset::withdraw_permission_check(owner, store, amount); let func_opt = fungible_asset::withdraw_dispatch_function(store); if (option::is_some(&func_opt)) { assert!( diff --git a/aptos-move/framework/aptos-framework/sources/function_info.move b/aptos-move/framework/aptos-framework/sources/function_info.move index 112a1c33b5903..6466c15d45a58 100644 --- a/aptos-move/framework/aptos-framework/sources/function_info.move +++ b/aptos-move/framework/aptos-framework/sources/function_info.move @@ -7,6 +7,7 @@ module aptos_framework::function_info { friend aptos_framework::fungible_asset; friend aptos_framework::dispatchable_fungible_asset; + friend aptos_framework::account_abstraction; /// String is not a valid Move identifier const EINVALID_IDENTIFIER: u64 = 1; diff --git a/aptos-move/framework/aptos-framework/sources/fungible_asset.move b/aptos-move/framework/aptos-framework/sources/fungible_asset.move index 3573f3cf78980..4b4bd78393b37 100644 --- a/aptos-move/framework/aptos-framework/sources/fungible_asset.move +++ b/aptos-move/framework/aptos-framework/sources/fungible_asset.move @@ -6,6 +6,7 @@ module aptos_framework::fungible_asset { use aptos_framework::event; use aptos_framework::function_info::{Self, FunctionInfo}; use aptos_framework::object::{Self, Object, ConstructorRef, DeleteRef, ExtendRef}; + use aptos_framework::permissioned_signer; use std::string; use std::features; @@ -90,9 +91,10 @@ module aptos_framework::fungible_asset { /// The balance ref and the fungible asset do not match. const ERAW_BALANCE_REF_AND_FUNGIBLE_ASSET_MISMATCH: u64 = 34; /// The supply ref and the fungible asset do not match. - const ERAW_SUPPLY_REF_AND_FUNGIBLE_ASSET_MISMATCH: u64 = 34; - + const ERAW_SUPPLY_REF_AND_FUNGIBLE_ASSET_MISMATCH: u64 = 35; + /// signer don't have the permission to perform withdraw operation + const EWITHDRAW_PERMISSION_DENIED: u64 = 36; // // Constants // @@ -209,6 +211,10 @@ module aptos_framework::fungible_asset { metadata: Object } + enum WithdrawPermission has copy, drop, store { + ByStore { store_address: address } + } + #[event] /// Emitted when fungible assets are deposited into a store. struct Deposit has drop, store { @@ -864,16 +870,51 @@ module aptos_framework::fungible_asset { amount: u64, ): FungibleAsset acquires FungibleStore, DispatchFunctionStore, ConcurrentFungibleBalance { withdraw_sanity_check(owner, store, true); + withdraw_permission_check(owner, store, amount); unchecked_withdraw(object::object_address(&store), amount) } + /// Check the permission for withdraw operation. + public(friend) fun withdraw_permission_check( + owner: &signer, + store: Object, + amount: u64, + ) { + assert!(permissioned_signer::check_permission_consume(owner, amount as u256, WithdrawPermission::ByStore { + store_address: object::object_address(&store), + }), error::permission_denied(EWITHDRAW_PERMISSION_DENIED)); + } + + /// Check the permission for withdraw operation. + public(friend) fun withdraw_permission_check_by_address( + owner: &signer, + store_address: address, + amount: u64, + ) { + assert!(permissioned_signer::check_permission_consume(owner, amount as u256, WithdrawPermission::ByStore { + store_address, + }), error::permission_denied(EWITHDRAW_PERMISSION_DENIED)); + } + /// Check the permission for withdraw operation. public(friend) fun withdraw_sanity_check( owner: &signer, store: Object, abort_on_dispatch: bool, ) acquires FungibleStore, DispatchFunctionStore { - assert!(object::owns(store, signer::address_of(owner)), error::permission_denied(ENOT_STORE_OWNER)); + withdraw_sanity_check_impl( + signer::address_of(owner), + store, + abort_on_dispatch, + ) + } + + inline fun withdraw_sanity_check_impl( + owner_address: address, + store: Object, + abort_on_dispatch: bool, + ) acquires FungibleStore, DispatchFunctionStore { + assert!(object::owns(store, owner_address), error::permission_denied(ENOT_STORE_OWNER)); let fa_store = borrow_store_resource(&store); assert!( !abort_on_dispatch || !has_withdraw_dispatch_function(fa_store.metadata), @@ -1325,6 +1366,58 @@ module aptos_framework::fungible_asset { move_to(&object_signer, ConcurrentFungibleBalance { balance }); } + /// Permission management + /// + /// Master signer grant permissioned signer ability to withdraw a given amount of fungible asset. + public fun grant_permission_by_store( + master: &signer, + permissioned: &signer, + store: Object, + amount: u64 + ) { + permissioned_signer::authorize_increase( + master, + permissioned, + amount as u256, + WithdrawPermission::ByStore { + store_address: object::object_address(&store), + } + ) + } + + public(friend) fun grant_permission_by_address( + master: &signer, + permissioned: &signer, + store_address: address, + amount: u64 + ) { + permissioned_signer::authorize_increase( + master, + permissioned, + amount as u256, + WithdrawPermission::ByStore { store_address } + ) + } + + public(friend) fun refill_permission( + permissioned: &signer, + amount: u64, + store_address: address, + ) { + permissioned_signer::increase_limit( + permissioned, + amount as u256, + WithdrawPermission::ByStore { store_address } + ) + } + + /// Removing permissions from permissioned signer. + public fun revoke_permission(permissioned: &signer, token_type: Object) { + permissioned_signer::revoke_permission(permissioned, WithdrawPermission::ByStore { + store_address: object::object_address(&token_type), + }) + } + #[test_only] use aptos_framework::account; @@ -1380,6 +1473,9 @@ module aptos_framework::fungible_asset { create_store(&object::create_object_from_account(owner), metadata) } + #[test_only] + use aptos_framework::timestamp; + #[test(creator = @0xcafe)] fun test_metadata_basic_flow(creator: &signer) acquires Metadata, Supply, ConcurrentSupply { let (creator_ref, metadata) = create_test_token(creator); @@ -1784,6 +1880,89 @@ module aptos_framework::fungible_asset { assert!(aggregator_v2::read(&borrow_global(object::object_address(&creator_store)).balance) == 30, 12); } + #[test(creator = @0xcafe, aaron = @0xface)] + fun test_e2e_withdraw_limit( + creator: &signer, + aaron: &signer, + ) acquires FungibleStore, Supply, ConcurrentSupply, DispatchFunctionStore, ConcurrentFungibleBalance { + let aptos_framework = account::create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let (mint_ref, _, _, _, test_token) = create_fungible_asset(creator); + let metadata = mint_ref.metadata; + let creator_store = create_test_store(creator, metadata); + let aaron_store = create_test_store(aaron, metadata); + + assert!(supply(test_token) == option::some(0), 1); + // Mint + let fa = mint(&mint_ref, 100); + assert!(supply(test_token) == option::some(100), 2); + // Deposit + deposit(creator_store, fa); + // Withdraw + let fa = withdraw(creator, creator_store, 80); + assert!(supply(test_token) == option::some(100), 3); + deposit(aaron_store, fa); + + // Create a permissioned signer + let aaron_permission_handle = permissioned_signer::create_permissioned_handle(aaron); + let aaron_permission_signer = permissioned_signer::signer_from_permissioned_handle(&aaron_permission_handle); + + // Grant aaron_permission_signer permission to withdraw 10 FA + grant_permission_by_store(aaron, &aaron_permission_signer, aaron_store, 10); + + let fa = withdraw(&aaron_permission_signer, aaron_store, 5); + deposit(aaron_store, fa); + + let fa = withdraw(&aaron_permission_signer, aaron_store, 5); + deposit(aaron_store, fa); + + // aaron signer don't abide to the same limit + let fa = withdraw(aaron, aaron_store, 5); + deposit(aaron_store, fa); + + permissioned_signer::destroy_permissioned_handle(aaron_permission_handle); + } + + #[test(creator = @0xcafe, aaron = @0xface)] + #[expected_failure(abort_code = 0x50024, location = Self)] + fun test_e2e_withdraw_limit_exceeds( + creator: &signer, + aaron: &signer, + ) acquires FungibleStore, Supply, ConcurrentSupply, DispatchFunctionStore, ConcurrentFungibleBalance { + let aptos_framework = account::create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let (mint_ref, _, _, _, test_token) = create_fungible_asset(creator); + let metadata = mint_ref.metadata; + let creator_store = create_test_store(creator, metadata); + let aaron_store = create_test_store(aaron, metadata); + + assert!(supply(test_token) == option::some(0), 1); + // Mint + let fa = mint(&mint_ref, 100); + assert!(supply(test_token) == option::some(100), 2); + // Deposit + deposit(creator_store, fa); + // Withdraw + let fa = withdraw(creator, creator_store, 80); + assert!(supply(test_token) == option::some(100), 3); + deposit(aaron_store, fa); + + // Create a permissioned signer + let aaron_permission_handle = permissioned_signer::create_permissioned_handle(aaron); + let aaron_permission_signer = permissioned_signer::signer_from_permissioned_handle(&aaron_permission_handle); + + // Grant aaron_permission_signer permission to withdraw 10 FA + grant_permission_by_store(aaron, &aaron_permission_signer, aaron_store, 10); + + // Withdrawing more than 10 FA yield an error. + let fa = withdraw(&aaron_permission_signer, aaron_store, 11); + deposit(aaron_store, fa); + + permissioned_signer::destroy_permissioned_handle(aaron_permission_handle); + } + #[deprecated] #[resource_group_member(group = aptos_framework::object::ObjectGroup)] struct FungibleAssetEvents has key { diff --git a/aptos-move/framework/aptos-framework/sources/managed_coin.move b/aptos-move/framework/aptos-framework/sources/managed_coin.move index a5da4b24ad5c9..701f7d97e55d3 100644 --- a/aptos-move/framework/aptos-framework/sources/managed_coin.move +++ b/aptos-move/framework/aptos-framework/sources/managed_coin.move @@ -138,8 +138,9 @@ module aptos_framework::managed_coin { #[test_only] struct FakeMoney {} - #[test(source = @0xa11ce, destination = @0xb0b, mod_account = @0x1)] + #[test(framework = @aptos_framework, source = @0xa11ce, destination = @0xb0b, mod_account = @0x1)] public entry fun test_end_to_end( + framework: signer, source: signer, destination: signer, mod_account: signer @@ -150,6 +151,7 @@ module aptos_framework::managed_coin { aptos_framework::account::create_account_for_test(destination_addr); aptos_framework::account::create_account_for_test(signer::address_of(&mod_account)); aggregator_factory::initialize_aggregator_factory_for_test(&mod_account); + aptos_framework::coin::create_coin_conversion_map(&framework); initialize( &mod_account, diff --git a/aptos-move/framework/aptos-framework/sources/managed_coin.spec.move b/aptos-move/framework/aptos-framework/sources/managed_coin.spec.move index 344c9744f7c97..c85b4e70bbedd 100644 --- a/aptos-move/framework/aptos-framework/sources/managed_coin.spec.move +++ b/aptos-move/framework/aptos-framework/sources/managed_coin.spec.move @@ -47,7 +47,7 @@ spec aptos_framework::managed_coin { /// spec module { pragma verify = true; - pragma aborts_if_is_strict; + pragma aborts_if_is_partial; } spec burn( diff --git a/aptos-move/framework/aptos-framework/sources/multisig_account.spec.move b/aptos-move/framework/aptos-framework/sources/multisig_account.spec.move index 1e2b60c3724ed..f9ebf96b25838 100644 --- a/aptos-move/framework/aptos-framework/sources/multisig_account.spec.move +++ b/aptos-move/framework/aptos-framework/sources/multisig_account.spec.move @@ -207,6 +207,7 @@ spec aptos_framework::multisig_account { } spec get_next_multisig_account_address(creator: address): address { + pragma aborts_if_is_partial; aborts_if !exists(creator); let owner_nonce = global(creator).sequence_number; } diff --git a/aptos-move/framework/aptos-framework/sources/object.move b/aptos-move/framework/aptos-framework/sources/object.move index bb6684ff6f430..09e724318e942 100644 --- a/aptos-move/framework/aptos-framework/sources/object.move +++ b/aptos-move/framework/aptos-framework/sources/object.move @@ -28,6 +28,7 @@ module aptos_framework::object { use aptos_framework::create_signer::create_signer; use aptos_framework::event; use aptos_framework::guid; + use aptos_framework::permissioned_signer; friend aptos_framework::coin; friend aptos_framework::primary_fungible_store; @@ -165,6 +166,11 @@ module aptos_framework::object { self: address, } + /// Permission to transfer object with permissioned signer. + struct TransferPermission has copy, drop, store { + object: address, + } + /// Emitted whenever the object's owner field is changed. struct TransferEvent has drop, store { object: address, @@ -540,6 +546,10 @@ module aptos_framework::object { to: address, ) acquires ObjectCore { let owner_address = signer::address_of(owner); + assert!( + permissioned_signer::check_permission_exists(owner, TransferPermission { object }), + error::permission_denied(EOBJECT_NOT_TRANSFERRABLE) + ); verify_ungated_and_descendant(owner_address, object); transfer_raw_inner(object, to); } @@ -629,6 +639,10 @@ module aptos_framework::object { ) acquires TombStone, ObjectCore { let object_addr = object.inner; assert!(exists(object_addr), error::invalid_argument(EOBJECT_NOT_BURNT)); + assert!( + permissioned_signer::check_permission_exists(original_owner, TransferPermission { object: object_addr }), + error::permission_denied(EOBJECT_NOT_TRANSFERRABLE) + ); let TombStone { original_owner: original_owner_addr } = move_from(object_addr); assert!(original_owner_addr == signer::address_of(original_owner), error::permission_denied(ENOT_OBJECT_OWNER)); @@ -699,6 +713,30 @@ module aptos_framework::object { obj_owner } + /// Master signer offers a transfer permission of an object to a permissioned signer. + public fun grant_permission( + master: &signer, + permissioned_signer: &signer, + object: Object, + ) { + permissioned_signer::authorize_unlimited( + master, + permissioned_signer, + TransferPermission { object: object.inner } + ) + } + + /// Grant a transfer permission to the permissioned signer using TransferRef. + public fun grant_permission_with_transfer_ref( + permissioned_signer: &signer, + ref: &TransferRef, + ) { + permissioned_signer::grant_unlimited_with_permissioned_signer( + permissioned_signer, + TransferPermission { object: ref.self } + ) + } + #[test_only] use std::option::{Self, Option}; @@ -1093,4 +1131,69 @@ module aptos_framework::object { set_untransferable(&weapon_constructor_ref); transfer_with_ref(linear_transfer_ref, @0x456); } + + #[test_only] + use aptos_framework::timestamp; + + #[test(creator = @0x123)] + fun test_transfer_permission_e2e( + creator: &signer, + ) acquires ObjectCore { + let aptos_framework = account::create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let (_, hero) = create_hero(creator); + let (_, weapon) = create_weapon(creator); + + // Create a permissioned signer + let creator_permission_handle = permissioned_signer::create_permissioned_handle(creator); + let creator_permission_signer = permissioned_signer::signer_from_permissioned_handle(&creator_permission_handle); + + // Grant aaron_permission_signer permission to transfer weapon object + grant_permission(creator, &creator_permission_signer, weapon); + transfer_to_object(&creator_permission_signer, weapon, hero); + + permissioned_signer::destroy_permissioned_handle(creator_permission_handle); + } + + #[test(creator = @0x123)] + #[expected_failure(abort_code = 327689, location = Self)] + fun test_transfer_no_permission( + creator: &signer, + ) acquires ObjectCore { + let aptos_framework = account::create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let (_, hero) = create_hero(creator); + let (_, weapon) = create_weapon(creator); + + // Create a permissioned signer + let creator_permission_handle = permissioned_signer::create_permissioned_handle(creator); + let creator_permission_signer = permissioned_signer::signer_from_permissioned_handle(&creator_permission_handle); + + transfer_to_object(&creator_permission_signer, weapon, hero); + + permissioned_signer::destroy_permissioned_handle(creator_permission_handle); + } + + #[test(creator = @0x123)] + fun test_create_and_transfer( + creator: &signer, + ) acquires ObjectCore { + let aptos_framework = account::create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let (_, hero) = create_hero(creator); + let (weapon_ref, weapon) = create_weapon(creator); + let t_ref = generate_transfer_ref(&weapon_ref); + + // Create a permissioned signer + let creator_permission_handle = permissioned_signer::create_permissioned_handle(creator); + let creator_permission_signer = permissioned_signer::signer_from_permissioned_handle(&creator_permission_handle); + + grant_permission_with_transfer_ref(&creator_permission_signer, &t_ref); + transfer_to_object(&creator_permission_signer, weapon, hero); + + permissioned_signer::destroy_permissioned_handle(creator_permission_handle); + } } diff --git a/aptos-move/framework/aptos-framework/sources/object.spec.move b/aptos-move/framework/aptos-framework/sources/object.spec.move index 51ae05b568368..6ddef5f6124bb 100644 --- a/aptos-move/framework/aptos-framework/sources/object.spec.move +++ b/aptos-move/framework/aptos-framework/sources/object.spec.move @@ -46,7 +46,14 @@ spec aptos_framework::object { /// /// spec module { - pragma aborts_if_is_strict; + pragma aborts_if_is_partial; + } + + spec grant_permission { + pragma aborts_if_is_partial; + aborts_if !permissioned_signer::spec_is_permissioned_signer(permissioned_signer); + aborts_if permissioned_signer::spec_is_permissioned_signer(master); + aborts_if signer::address_of(master) != signer::address_of(permissioned_signer); } spec fun spec_exists_at(object: address): bool; diff --git a/aptos-move/framework/aptos-framework/sources/object_code_deployment.move b/aptos-move/framework/aptos-framework/sources/object_code_deployment.move index ef9e7d37fe9df..f611d1003573d 100644 --- a/aptos-move/framework/aptos-framework/sources/object_code_deployment.move +++ b/aptos-move/framework/aptos-framework/sources/object_code_deployment.move @@ -47,6 +47,8 @@ module aptos_framework::object_code_deployment { const ENOT_CODE_OBJECT_OWNER: u64 = 2; /// `code_object` does not exist. const ECODE_OBJECT_DOES_NOT_EXIST: u64 = 3; + /// Current permissioned signer cannot deploy object code. + const ENO_CODE_PERMISSION: u64 = 4; const OBJECT_CODE_DEPLOYMENT_DOMAIN_SEPARATOR: vector = b"aptos_framework::object_code_deployment"; @@ -84,6 +86,7 @@ module aptos_framework::object_code_deployment { metadata_serialized: vector, code: vector>, ) { + code::check_code_publishing_permission(publisher); assert!( features::is_object_code_deployment_enabled(), error::unavailable(EOBJECT_CODE_DEPLOYMENT_NOT_SUPPORTED), @@ -120,6 +123,7 @@ module aptos_framework::object_code_deployment { code: vector>, code_object: Object, ) acquires ManagingRefs { + code::check_code_publishing_permission(publisher); let publisher_address = signer::address_of(publisher); assert!( object::is_owner(code_object, publisher_address), diff --git a/aptos-move/framework/aptos-framework/sources/permissioned_signer.move b/aptos-move/framework/aptos-framework/sources/permissioned_signer.move new file mode 100644 index 0000000000000..8e752e723138d --- /dev/null +++ b/aptos-move/framework/aptos-framework/sources/permissioned_signer.move @@ -0,0 +1,698 @@ +/// A _permissioned signer_ consists of a pair of the original signer and a generated +/// address which is used to store information about associated permissions. +/// +/// A permissioned signer is a restricted version of a signer. Functions `move_to` and +/// `address_of` behave the same, and can be passed wherever signer is needed. However, +/// code can internally query for the permissions to assert additional restrictions on +/// the use of the signer. +/// +/// A client which is interested in restricting access granted via a signer can create a permissioned signer +/// and pass on to other existing code without changes to existing APIs. Core functions in the framework, for +/// example account functions, can then assert availability of permissions, effectively restricting +/// existing code in a compatible way. +/// +/// After introducing the core functionality, examples are provided for withdraw limit on accounts, and +/// for blind signing. +module aptos_framework::permissioned_signer { + use std::features; + use std::signer; + use std::error; + use std::vector; + use std::option::{Option, Self}; + use aptos_std::copyable_any::{Self, Any}; + use aptos_framework::big_ordered_map::{Self, BigOrderedMap}; + use aptos_framework::create_signer::create_signer; + use aptos_framework::transaction_context::generate_auid_address; + use aptos_framework::timestamp; + + /// Trying to grant permission using non-master signer. + const ENOT_MASTER_SIGNER: u64 = 1; + + /// Cannot authorize a permission. + const ECANNOT_AUTHORIZE: u64 = 2; + + /// Access permission information from a master signer. + const ENOT_PERMISSIONED_SIGNER: u64 = 3; + + /// signer doesn't have enough capacity to extract permission. + const ECANNOT_EXTRACT_PERMISSION: u64 = 4; + + /// permission handle has expired. + const E_PERMISSION_EXPIRED: u64 = 5; + + /// storing extracted permission into a different signer. + const E_PERMISSION_MISMATCH: u64 = 6; + + /// permission handle has been revoked by the original signer. + const E_PERMISSION_REVOKED: u64 = 7; + + /// destroying permission handle that has already been revoked or not owned by the + /// given master signer. + const E_NOT_ACTIVE: u64 = 8; + + /// Permissioned signer feature is not activated. + const EPERMISSION_SIGNER_DISABLED: u64 = 9; + + const U256_MAX: u256 = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + /// If a permissioned signer has this permission, it would be able to revoke other granted + /// permission handles in the same signer. + struct RevokePermissionHandlePermission has copy, store, drop {} + + /// Stores the list of granted permission handles for a given account. + struct GrantedPermissionHandles has key { + /// Each address refers to a `permissions_storage_addr` that stores the `PermissionStorage`. + active_handles: vector
+ } + + /// A ephermeral permission handle that can be used to generate a permissioned signer with permission + /// configuration stored within. + enum PermissionedHandle { + V1 { + /// Address of the signer that creates this handle. + master_account_addr: address, + /// Address that stores `PermissionStorage`. + permissions_storage_addr: address + } + } + + /// A permission handle that can be used to generate a permissioned signer. + /// + /// This handle is storable and thus should be treated very carefully as it serves similar functionality + /// as signer delegation. + enum StorablePermissionedHandle has store { + V1 { + /// Address of the signer that creates this handle. + master_account_addr: address, + /// Address that stores `PermissionStorage`. + permissions_storage_addr: address, + /// Permissioned signer can no longer be generated from this handle after `expiration_time`. + expiration_time: u64 + } + } + + /// The actual permission configuration stored on-chain. + /// + /// The address that holds `PermissionStorage` will be generated freshly every time a permission + /// handle gets created. + enum PermissionStorage has key { + V1 { + /// A hetherogenous map from `Permission` structs defined by each different modules to + /// its permission capacity. + perms: BigOrderedMap + } + } + + /// Types of permission capacity stored on chain. + enum StoredPermission has store, copy, drop { + /// Unlimited capacity. + Unlimited, + /// Fixed capacity, will be deducted when permission is used. + Capacity(u256), + } + + /// Create an ephermeral permission handle based on the master signer. + /// + /// This handle can be used to derive a signer that can be used in the context of + /// the current transaction. + public fun create_permissioned_handle(master: &signer): PermissionedHandle { + assert!( + features::is_permissioned_signer_enabled(), + error::permission_denied(EPERMISSION_SIGNER_DISABLED) + ); + + assert_master_signer(master); + let permissions_storage_addr = generate_auid_address(); + let master_account_addr = signer::address_of(master); + + initialize_permission_address(permissions_storage_addr); + + PermissionedHandle::V1 { master_account_addr, permissions_storage_addr } + } + + /// Destroys an ephermeral permission handle. Clean up the permission stored in that handle + public fun destroy_permissioned_handle(p: PermissionedHandle) acquires PermissionStorage { + assert!( + features::is_permissioned_signer_enabled(), + error::permission_denied(EPERMISSION_SIGNER_DISABLED) + ); + let PermissionedHandle::V1 { master_account_addr: _, permissions_storage_addr } = + p; + destroy_permissions_storage_address(permissions_storage_addr); + } + + /// Generate the permissioned signer based on the ephermeral permission handle. + /// + /// This signer can be used as a regular signer for other smart contracts. However when such + /// signer interacts with various framework functions, it would subject to permission checks + /// and would abort if check fails. + public fun signer_from_permissioned_handle(p: &PermissionedHandle): signer { + assert!( + features::is_permissioned_signer_enabled(), + error::permission_denied(EPERMISSION_SIGNER_DISABLED) + ); + signer_from_permissioned_handle_impl( + p.master_account_addr, p.permissions_storage_addr + ) + } + + /// Returns true if `s` is a permissioned signer. + public fun is_permissioned_signer(s: &signer): bool { + // When the permissioned signer is disabled, no one is able to construct a permissioned + // signer. Thus we should return false here, as other on chain permission checks will + // depend on this checks. + if(!features::is_permissioned_signer_enabled()) { + return false; + }; + is_permissioned_signer_impl(s) + } + + /// Grant the permissioned signer the permission to revoke granted permission handles under + /// its address. + public fun grant_revoke_permission( + master: &signer, + permissioned: &signer, + ) acquires PermissionStorage { + assert!( + features::is_permissioned_signer_enabled(), + error::permission_denied(EPERMISSION_SIGNER_DISABLED) + ); + authorize_unlimited(master, permissioned, RevokePermissionHandlePermission {}); + } + + /// Revoke a specific storable permission handle immediately. This will disallow owner of + /// the storable permission handle to derive signer from it anymore. + public entry fun revoke_permission_storage_address( + s: &signer, permissions_storage_addr: address + ) acquires GrantedPermissionHandles, PermissionStorage { + assert!( + features::is_permissioned_signer_enabled(), + error::permission_denied(EPERMISSION_SIGNER_DISABLED) + ); + assert!( + check_permission_exists(s, RevokePermissionHandlePermission {}), + error::permission_denied(ENOT_MASTER_SIGNER) + ); + let master_account_addr = signer::address_of(s); + + assert!( + exists(master_account_addr), + error::permission_denied(E_PERMISSION_REVOKED), + ); + let active_handles = &mut GrantedPermissionHandles[master_account_addr].active_handles; + let (found, idx) = active_handles.index_of(&permissions_storage_addr); + + // The address has to be in the activated list in the master account address. + assert!(found, error::permission_denied(E_NOT_ACTIVE)); + active_handles.swap_remove(idx); + destroy_permissions_storage_address(permissions_storage_addr); + } + + /// Revoke all storable permission handle of the signer immediately. + public entry fun revoke_all_handles(s: &signer) acquires GrantedPermissionHandles, PermissionStorage { + assert!( + features::is_permissioned_signer_enabled(), + error::permission_denied(EPERMISSION_SIGNER_DISABLED) + ); + assert!( + check_permission_exists(s, RevokePermissionHandlePermission {}), + error::permission_denied(ENOT_MASTER_SIGNER) + ); + let master_account_addr = signer::address_of(s); + if (!exists(master_account_addr)) { return }; + + let granted_permissions = + borrow_global_mut(master_account_addr); + let delete_list = vector::trim_reverse( + &mut granted_permissions.active_handles, 0 + ); + vector::destroy( + delete_list, + |address| { + destroy_permissions_storage_address(address); + } + ) + } + + /// initialize permission storage by putting an empty storage under the address. + inline fun initialize_permission_address(permissions_storage_addr: address) { + move_to( + &create_signer(permissions_storage_addr), + // Each key is ~100bytes, the value is 12 bytes. + PermissionStorage::V1 { perms: big_ordered_map::new_with_config(40, 35, false, 0) } + ); + } + + /// Create an storable permission handle based on the master signer. + /// + /// This handle can be used to derive a signer that can be stored by a smart contract. + /// This is as dangerous as key delegation, thus it remains public(package) for now. + /// + /// The caller should check if `expiration_time` is not too far in the future. + public(package) fun create_storable_permissioned_handle( + master: &signer, expiration_time: u64 + ): StorablePermissionedHandle acquires GrantedPermissionHandles { + assert!( + features::is_permissioned_signer_enabled(), + error::permission_denied(EPERMISSION_SIGNER_DISABLED) + ); + + assert_master_signer(master); + let permissions_storage_addr = generate_auid_address(); + let master_account_addr = signer::address_of(master); + + assert!( + timestamp::now_seconds() < expiration_time, + error::permission_denied(E_PERMISSION_EXPIRED) + ); + + if (!exists(master_account_addr)) { + move_to( + master, GrantedPermissionHandles { active_handles: vector::empty() } + ); + }; + + GrantedPermissionHandles[master_account_addr] + .active_handles.push_back(permissions_storage_addr); + + initialize_permission_address(permissions_storage_addr); + + StorablePermissionedHandle::V1 { + master_account_addr, + permissions_storage_addr, + expiration_time + } + } + + /// Destroys a storable permission handle. Clean up the permission stored in that handle + public(package) fun destroy_storable_permissioned_handle( + p: StorablePermissionedHandle + ) acquires PermissionStorage, GrantedPermissionHandles { + let StorablePermissionedHandle::V1 { + master_account_addr, + permissions_storage_addr, + expiration_time: _ + } = p; + + assert!( + exists(master_account_addr), + error::permission_denied(E_PERMISSION_REVOKED), + ); + let active_handles = &mut GrantedPermissionHandles[master_account_addr].active_handles; + + let (found, idx) = active_handles.index_of(&permissions_storage_addr); + + // Removing the address from the active handle list if it's still active. + if(found) { + active_handles.swap_remove(idx); + }; + + destroy_permissions_storage_address(permissions_storage_addr); + } + + inline fun destroy_permissions_storage_address( + permissions_storage_addr: address + ) acquires PermissionStorage { + if (exists(permissions_storage_addr)) { + let PermissionStorage::V1 { perms } = + move_from(permissions_storage_addr); + big_ordered_map::destroy( + perms, + |_dv| {}, + ); + } + } + + /// Generate the permissioned signer based on the storable permission handle. + public(package) fun signer_from_storable_permissioned_handle( + p: &StorablePermissionedHandle + ): signer { + assert!( + features::is_permissioned_signer_enabled(), + error::permission_denied(EPERMISSION_SIGNER_DISABLED) + ); + assert!( + timestamp::now_seconds() < p.expiration_time, + error::permission_denied(E_PERMISSION_EXPIRED) + ); + assert!( + exists(p.permissions_storage_addr), + error::permission_denied(E_PERMISSION_REVOKED) + ); + signer_from_permissioned_handle_impl( + p.master_account_addr, p.permissions_storage_addr + ) + } + + /// Return the permission handle address so that it could be used for revocation purpose. + public(package) fun permissions_storage_address( + p: &StorablePermissionedHandle + ): address { + p.permissions_storage_addr + } + + /// Helper function that would abort if the signer passed in is a permissioned signer. + public(package) fun assert_master_signer(s: &signer) { + assert!( + !is_permissioned_signer(s), error::permission_denied(ENOT_MASTER_SIGNER) + ); + } + + /// ===================================================================================================== + /// StoredPermission operations + /// + /// check if StoredPermission has at least `threshold` capacity. + fun is_above(perm: &StoredPermission, threshold: u256): bool { + match (perm) { + StoredPermission::Capacity(capacity) => *capacity >= threshold, + StoredPermission::Unlimited => true, + } + } + + /// consume `threshold` capacity from StoredPermission + fun consume_capacity(perm: &mut StoredPermission, threshold: u256): bool { + match (perm) { + StoredPermission::Capacity(current_capacity) => { + if (*current_capacity >= threshold) { + *current_capacity = *current_capacity - threshold; + true + } else { false } + } + StoredPermission::Unlimited => true + } + } + + /// increase `threshold` capacity from StoredPermission + fun increase_capacity(perm: &mut StoredPermission, threshold: u256) { + match (perm) { + StoredPermission::Capacity(current_capacity) => { + *current_capacity = *current_capacity + threshold; + } + StoredPermission::Unlimited => (), + } + } + + /// merge the two stored permission + fun merge(lhs: &mut StoredPermission, rhs: StoredPermission) { + match (rhs) { + StoredPermission::Capacity(new_capacity) => { + match (lhs) { + StoredPermission::Capacity(current_capacity) => { + *current_capacity = *current_capacity + new_capacity; + } + StoredPermission::Unlimited => (), + } + } + StoredPermission::Unlimited => *lhs = StoredPermission::Unlimited, + } + } + + /// ===================================================================================================== + /// Permission Management + /// + /// Authorizes `permissioned` with the given permission. This requires to have access to the `master` + /// signer. + + inline fun map_or( + permissioned: &signer, + perm: PermKey, + mutate: |&mut StoredPermission| T, + default: T, + ): T { + let permission_signer_addr = permission_address(permissioned); + assert!( + exists(permission_signer_addr), + error::permission_denied(E_NOT_ACTIVE) + ); + let perms = + &mut borrow_global_mut(permission_signer_addr).perms; + let key = copyable_any::pack(perm); + if (big_ordered_map::contains(perms, &key)) { + let value = perms.remove(&key); + let return_ = mutate(&mut value); + perms.add(key, value); + return_ + } else { + default + } + } + + inline fun insert_or( + permissioned: &signer, + perm: PermKey, + mutate: |&mut StoredPermission|, + default: StoredPermission, + ) { + let permission_signer_addr = permission_address(permissioned); + assert!( + exists(permission_signer_addr), + error::permission_denied(E_NOT_ACTIVE) + ); + let perms = + &mut borrow_global_mut(permission_signer_addr).perms; + let key = copyable_any::pack(perm); + if (perms.contains(&key)) { + let value = perms.remove(&key); + mutate(&mut value); + perms.add(key, value); + } else { + perms.add(key, default); + } + } + + /// Authorizes `permissioned` with a given capacity and increment the existing capacity if present. + /// + /// Consumption using `check_permission_consume` will deduct the capacity. + public(package) fun authorize_increase( + master: &signer, + permissioned: &signer, + capacity: u256, + perm: PermKey + ) acquires PermissionStorage { + assert!( + is_permissioned_signer(permissioned) + && !is_permissioned_signer(master) + && signer::address_of(master) == signer::address_of(permissioned), + error::permission_denied(ECANNOT_AUTHORIZE) + ); + insert_or( + permissioned, + perm, + |stored_permission| { + increase_capacity(stored_permission, capacity); + }, + StoredPermission::Capacity(capacity), + ) + } + + /// Authorizes `permissioned` with the given unlimited permission. + /// Unlimited permission can be consumed however many times. + public(package) fun authorize_unlimited( + master: &signer, + permissioned: &signer, + perm: PermKey + ) acquires PermissionStorage { + assert!( + is_permissioned_signer(permissioned) + && !is_permissioned_signer(master) + && signer::address_of(master) == signer::address_of(permissioned), + error::permission_denied(ECANNOT_AUTHORIZE) + ); + insert_or( + permissioned, + perm, + |stored_permission| { + *stored_permission = StoredPermission::Unlimited; + }, + StoredPermission::Unlimited, + ) + } + + /// Grant an unlimited permission to a permissioned signer **without** master signer's approvoal. + public(package) fun grant_unlimited_with_permissioned_signer( + permissioned: &signer, + perm: PermKey + ) acquires PermissionStorage { + if(!is_permissioned_signer(permissioned)) { + return; + }; + insert_or( + permissioned, + perm, + |stored_permission| { + *stored_permission = StoredPermission::Unlimited; + }, + StoredPermission::Unlimited, + ) + } + + /// Increase the `capacity` of a permissioned signer **without** master signer's approvoal. + /// + /// The caller of the module will need to make sure the witness type `PermKey` can only be + /// constructed within its own module, otherwise attackers can refill the permission for itself + /// to bypass the checks. + public(package) fun increase_limit( + permissioned: &signer, + capacity: u256, + perm: PermKey + ) acquires PermissionStorage { + if(!is_permissioned_signer(permissioned)) { + return; + }; + insert_or( + permissioned, + perm, + |stored_permission| { + increase_capacity(stored_permission, capacity); + }, + StoredPermission::Capacity(capacity), + ) + } + + public(package) fun check_permission_exists( + s: &signer, perm: PermKey + ): bool acquires PermissionStorage { + // 0 capacity permissions will be treated as non-existant. + check_permission_capacity_above(s, 1, perm) + } + + public(package) fun check_permission_capacity_above( + s: &signer, threshold: u256, perm: PermKey + ): bool acquires PermissionStorage { + if (!is_permissioned_signer(s)) { + // master signer has all permissions + return true + }; + map_or( + s, + perm, + |stored_permission| { + is_above(stored_permission, threshold) + }, + false, + ) + } + + public(package) fun check_permission_consume( + s: &signer, threshold: u256, perm: PermKey + ): bool acquires PermissionStorage { + if (!is_permissioned_signer(s)) { + // master signer has all permissions + return true + }; + map_or( + s, + perm, + |stored_permission| { + consume_capacity(stored_permission, threshold) + }, + false, + ) + } + + public(package) fun capacity( + s: &signer, perm: PermKey + ): Option acquires PermissionStorage { + if (!is_permissioned_signer(s)) { + return option::some(U256_MAX) + }; + map_or( + s, + perm, + |stored_permission: &mut StoredPermission| { + option::some(match (stored_permission) { + StoredPermission::Capacity(capacity) => *capacity, + StoredPermission::Unlimited => U256_MAX, + }) + }, + option::none(), + ) + } + + public(package) fun revoke_permission( + permissioned: &signer, perm: PermKey + ) acquires PermissionStorage { + if (!is_permissioned_signer(permissioned)) { + // Master signer has no permissions associated with it. + return + }; + let addr = permission_address(permissioned); + if (!exists(addr)) { return }; + let perm_storage = &mut PermissionStorage[addr].perms; + let key = copyable_any::pack(perm); + if (perm_storage.contains(&key)) { + perm_storage.remove(&key); + } + } + + // ===================================================================================================== + // Native Functions + /// + /// Check whether this is a permissioned signer. + native fun is_permissioned_signer_impl(s: &signer): bool; + /// Return the address used for storing permissions. Aborts if not a permissioned signer. + native fun permission_address(permissioned: &signer): address; + /// Creates a permissioned signer from an existing universal signer. The function aborts if the + /// given signer is already a permissioned signer. + /// + /// The implementation of this function requires to extend the value representation for signers in the VM. + /// invariants: + /// signer::address_of(master) == signer::address_of(signer_from_permissioned_handle(create_permissioned_handle(master))), + /// + native fun signer_from_permissioned_handle_impl( + master_account_addr: address, permissions_storage_addr: address + ): signer; + + #[test(creator = @0xcafe)] + fun signer_address_roundtrip( + creator: &signer + ) acquires PermissionStorage, GrantedPermissionHandles { + let aptos_framework = create_signer(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let handle = create_permissioned_handle(creator); + let perm_signer = signer_from_permissioned_handle(&handle); + assert!(signer::address_of(&perm_signer) == signer::address_of(creator), 1); + assert!( + permission_address(&perm_signer) + == handle.permissions_storage_addr, + 1 + ); + assert!(exists(handle.permissions_storage_addr), 1); + + destroy_permissioned_handle(handle); + + let handle = create_storable_permissioned_handle(creator, 60); + let perm_signer = signer_from_storable_permissioned_handle(&handle); + assert!(signer::address_of(&perm_signer) == signer::address_of(creator), 1); + assert!( + permission_address(&perm_signer) + == handle.permissions_storage_addr, + 1 + ); + assert!(exists(handle.permissions_storage_addr), 1); + + destroy_storable_permissioned_handle(handle); + } + + #[test_only] + use aptos_std::bcs; + + #[test(creator = @0xcafe)] + #[expected_failure(abort_code = 0x1C5, location = aptos_std::bcs)] + fun signer_serialization( + creator: &signer + ) acquires PermissionStorage { + let aptos_framework = create_signer(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let handle = create_permissioned_handle(creator); + let perm_signer = signer_from_permissioned_handle(&handle); + + assert!(bcs::to_bytes(creator) == bcs::to_bytes(&signer::address_of(creator)), 1); + bcs::to_bytes(&perm_signer); + + destroy_permissioned_handle(handle); + } +} diff --git a/aptos-move/framework/aptos-framework/sources/permissioned_signer.spec.move b/aptos-move/framework/aptos-framework/sources/permissioned_signer.spec.move new file mode 100644 index 0000000000000..9e94c8952bccc --- /dev/null +++ b/aptos-move/framework/aptos-framework/sources/permissioned_signer.spec.move @@ -0,0 +1,170 @@ +spec aptos_framework::permissioned_signer { + + spec module { + pragma verify = false; + axiom forall a: GrantedPermissionHandles: + ( + forall i in 0..len(a.active_handles): + forall j in 0..len(a.active_handles): + i != j ==> + a.active_handles[i] != a.active_handles[j] + ); + } + + spec fun spec_is_permissioned_signer(s: signer): bool; + + spec is_permissioned_signer(s: &signer): bool { + pragma opaque; + aborts_if [abstract] false; + ensures [abstract] result == spec_is_permissioned_signer(s); + } + + spec fun spec_permission_address(s: signer): address; + + spec permission_address(permissioned: &signer): address { + pragma opaque; + aborts_if [abstract]!spec_is_permissioned_signer(permissioned); + ensures [abstract] result == spec_permission_address(permissioned); + } + + spec fun spec_signer_from_permissioned_handle_impl( + master_account_addr: address, permissions_storage_addr: address + ): signer; + + spec signer_from_permissioned_handle_impl( + master_account_addr: address, permissions_storage_addr: address + ): signer { + pragma opaque; + ensures [abstract] result + == spec_signer_from_permissioned_handle_impl( + master_account_addr, permissions_storage_addr + ); + } + + spec create_permissioned_handle(master: &signer): PermissionedHandle { + use aptos_framework::transaction_context; + pragma opaque; + aborts_if [abstract] spec_is_permissioned_signer(master); + let permissions_storage_addr = transaction_context::spec_generate_unique_address(); + modifies global(permissions_storage_addr); + let master_account_addr = signer::address_of(master); + ensures result.master_account_addr == master_account_addr; + ensures result.permissions_storage_addr == permissions_storage_addr; + } + + spec create_storable_permissioned_handle(master: &signer, expiration_time: u64): StorablePermissionedHandle { + use aptos_framework::transaction_context; + pragma opaque; + aborts_if [abstract] spec_is_permissioned_signer(master); + let permissions_storage_addr = transaction_context::spec_generate_unique_address(); + modifies global(permissions_storage_addr); + let master_account_addr = signer::address_of(master); + modifies global(master_account_addr); + ensures result.master_account_addr == master_account_addr; + ensures result.permissions_storage_addr == permissions_storage_addr; + ensures result.expiration_time == expiration_time; + ensures vector::spec_contains( + global(master_account_addr).active_handles, + permissions_storage_addr + ); + ensures exists(master_account_addr); + } + + spec destroy_permissioned_handle(p: PermissionedHandle) { + ensures !exists(p.permissions_storage_addr); + } + + spec destroy_storable_permissioned_handle(p: StorablePermissionedHandle) { + ensures !exists(p.permissions_storage_addr); + let post granted_permissions = global( + p.master_account_addr + ); + // ensures [abstract] !vector::spec_contains(granted_permissions.active_handles, p.permissions_storage_addr); + } + + spec revoke_permission_storage_address(s: &signer, permissions_storage_addr: address) { + // aborts_if spec_is_permissioned_signer(s); + } + + spec authorize_increase( + master: &signer, permissioned: &signer, capacity: u256, perm: PermKey + ) { + + // use aptos_std::type_info; + // use std::bcs; + pragma aborts_if_is_partial; + aborts_if !spec_is_permissioned_signer(permissioned); + aborts_if spec_is_permissioned_signer(master); + aborts_if signer::address_of(permissioned) != signer::address_of(master); + ensures exists( + spec_permission_address(permissioned) + ); + // let perms = global(permission_signer_addr).perms; + // let post post_perms = global(permission_signer_addr).perms; + // let key = Any { + // type_name: type_info::type_name>(), + // data: bcs::serialize(perm) + // }; + // ensures smart_table::spec_contains(perms, key) ==> + // smart_table::spec_get(post_perms, key) == old(smart_table::spec_get(perms, key)) + capacity; + // ensures !smart_table::spec_contains(perms, key) ==> + // smart_table::spec_get(post_perms, key) == capacity; + } + + spec check_permission_exists(s: &signer, perm: PermKey): bool { + pragma verify = false; + // pragma opaque; + // aborts_if false; + // ensures [abstract] result == spec_check_permission_exists(s, perm); + } + + spec fun spec_check_permission_exists(s: signer, perm: PermKey): bool { + use aptos_std::type_info; + use std::bcs; + let addr = spec_permission_address(s); + let key = Any { + type_name: type_info::type_name(), + data: bcs::serialize(perm) + }; + if (!spec_is_permissioned_signer(s)) { true } + else if (!exists(addr)) { false } + else { + // ordered_map::spec_contains_key(global(addr).perms, key) + // FIXME: ordered map spec doesn't exist yet. + true + } + } + + spec check_permission_capacity_above( + s: &signer, threshold: u256, perm: PermKey + ): bool { + let permissioned_signer_addr = spec_permission_address(s); + ensures !spec_is_permissioned_signer(s) ==> result == true; + ensures ( + spec_is_permissioned_signer(s) + && !exists(permissioned_signer_addr) + ) ==> result == false; + // ensures (spec_is_permissioned_signer(s) && exists(permissioned_signer_addr) && !smart_table::spec_contains(global(permissioned_signer_addr).perms, key)) ==> + // result == false; + // ensures (spec_is_permissioned_signer(s) && exists(permissioned_signer_addr) && smart_table::spec_contains(global(permissioned_signer_addr).perms, key)) ==> + // result == (smart_table::spec_get(global(permissioned_signer_addr).perms, key) > threshold); + } + + spec check_permission_consume( + s: &signer, threshold: u256, perm: PermKey + ): bool { + let permissioned_signer_addr = spec_permission_address(s); + ensures !spec_is_permissioned_signer(s) ==> result == true; + ensures ( + spec_is_permissioned_signer(s) + && !exists(permissioned_signer_addr) + ) ==> result == false; + + } + + spec capacity(s: &signer, perm: PermKey): Option { + // let permissioned_signer_addr = signer::address_of(spec_permission_address(s)); + // ensures !exists(permissioned_signer_addr) ==> + // option::is_none(result); + } +} diff --git a/aptos-move/framework/aptos-framework/sources/primary_fungible_store.move b/aptos-move/framework/aptos-framework/sources/primary_fungible_store.move index 4a69b78937a1b..2fc6ae2b27d7b 100644 --- a/aptos-move/framework/aptos-framework/sources/primary_fungible_store.move +++ b/aptos-move/framework/aptos-framework/sources/primary_fungible_store.move @@ -20,6 +20,9 @@ module aptos_framework::primary_fungible_store { use std::signer; use std::string::String; + #[test_only] + use aptos_framework::permissioned_signer; + #[resource_group_member(group = aptos_framework::object::ObjectGroup)] /// A resource that holds the derive ref for the fungible asset metadata object. This is used to create primary /// stores for users with deterministic addresses so that users can easily deposit/withdraw/transfer fungible @@ -124,6 +127,33 @@ module aptos_framework::primary_fungible_store { fungible_asset::store_exists(primary_store_address_inlined(account, metadata)) } + public fun grant_permission( + master: &signer, + permissioned: &signer, + metadata: Object, + amount: u64 + ) { + fungible_asset::grant_permission_by_address( + master, + permissioned, + primary_store_address_inlined(signer::address_of(permissioned), metadata), + amount + ); + } + + public fun grant_apt_permission( + master: &signer, + permissioned: &signer, + amount: u64 + ) { + fungible_asset::grant_permission_by_address( + master, + permissioned, + object::create_user_derived_object_address(signer::address_of(permissioned), @aptos_fungible_asset), + amount + ); + } + #[view] /// Get the balance of `account`'s primary store. public fun balance(account: address, metadata: Object): u64 { @@ -168,6 +198,24 @@ module aptos_framework::primary_fungible_store { dispatchable_fungible_asset::deposit(store, fa); } + /// Deposit fungible asset `fa` to the given account's primary store using signer. + /// + /// If `owner` is a permissioned signer, the signer will be granted with permission to withdraw + /// the same amount of fund in the future. + public fun deposit_with_signer(owner: &signer, fa: FungibleAsset) acquires DeriveRefPod { + fungible_asset::refill_permission( + owner, + fungible_asset::amount(&fa), + primary_store_address_inlined( + signer::address_of(owner), + fungible_asset::metadata_from_asset(&fa), + ) + ); + let metadata = fungible_asset::asset_metadata(&fa); + let store = ensure_primary_store_exists(signer::address_of(owner), metadata); + dispatchable_fungible_asset::deposit(store, fa); + } + /// Deposit fungible asset `fa` to the given account's primary store. public(friend) fun force_deposit(owner: address, fa: FungibleAsset) acquires DeriveRefPod { let metadata = fungible_asset::asset_metadata(&fa); @@ -402,4 +450,42 @@ module aptos_framework::primary_fungible_store { assert!(balance(user_2_address, metadata) == 10, 0); deposit(user_2_address, coins); } + + #[test(creator = @0xcafe, aaron = @0xface)] + fun test_permissioned_flow( + creator: &signer, + aaron: &signer, + ) acquires DeriveRefPod { + let (creator_ref, metadata) = create_test_token(creator); + let (mint_ref, _transfer_ref, _burn_ref) = init_test_metadata_with_primary_store_enabled(&creator_ref); + let creator_address = signer::address_of(creator); + let aaron_address = signer::address_of(aaron); + assert!(balance(creator_address, metadata) == 0, 1); + assert!(balance(aaron_address, metadata) == 0, 2); + mint(&mint_ref, creator_address, 100); + transfer(creator, metadata, aaron_address, 80); + + let aaron_permission_handle = permissioned_signer::create_permissioned_handle(aaron); + let aaron_permission_signer = permissioned_signer::signer_from_permissioned_handle(&aaron_permission_handle); + grant_permission(aaron, &aaron_permission_signer, metadata, 10); + + let fa = withdraw(&aaron_permission_signer, metadata, 10); + deposit(creator_address, fa); + + assert!(balance(creator_address, metadata) == 30, 3); + assert!(balance(aaron_address, metadata) == 70, 4); + + // Withdraw from creator and deposit back to aaron's account with permssioned signer. + let fa = withdraw(creator, metadata, 10); + deposit_with_signer(&aaron_permission_signer, fa); + + // deposit_with_signer refills the permission, can now withdraw again. + let fa = withdraw(&aaron_permission_signer, metadata, 10); + deposit(creator_address, fa); + + assert!(balance(creator_address, metadata) == 30, 3); + assert!(balance(aaron_address, metadata) == 70, 4); + + permissioned_signer::destroy_permissioned_handle(aaron_permission_handle); + } } diff --git a/aptos-move/framework/aptos-framework/sources/resource_account.spec.move b/aptos-move/framework/aptos-framework/sources/resource_account.spec.move index 847e77853bdc4..2bd5dd294f2e0 100644 --- a/aptos-move/framework/aptos-framework/sources/resource_account.spec.move +++ b/aptos-move/framework/aptos-framework/sources/resource_account.spec.move @@ -60,7 +60,7 @@ spec aptos_framework::resource_account { /// spec module { pragma verify = true; - pragma aborts_if_is_strict; + pragma aborts_if_is_partial; } spec create_resource_account( @@ -68,8 +68,10 @@ spec aptos_framework::resource_account { seed: vector, optional_auth_key: vector, ) { + use aptos_framework::create_signer; let source_addr = signer::address_of(origin); let resource_addr = account::spec_create_resource_address(source_addr, seed); + let resource = create_signer::spec_create_signer(resource_addr); include RotateAccountAuthenticationKeyAndStoreCapabilityAbortsIfWithoutAccountLimit; } @@ -116,6 +118,8 @@ spec aptos_framework::resource_account { resource_signer_cap: account::SignerCapability, optional_auth_key: vector, ) { + pragma aborts_if_is_partial; + let resource_addr = signer::address_of(resource); /// [high-level-req-1] include RotateAccountAuthenticationKeyAndStoreCapabilityAbortsIf; @@ -172,6 +176,8 @@ spec aptos_framework::resource_account { resource: &signer, source_addr: address, ) : account::SignerCapability { + pragma aborts_if_is_partial; + /// [high-level-req-6] aborts_if !exists(source_addr); let resource_addr = signer::address_of(resource); diff --git a/aptos-move/framework/aptos-framework/sources/stake.move b/aptos-move/framework/aptos-framework/sources/stake.move index b4f62d3df4004..190ceda38cb1e 100644 --- a/aptos-move/framework/aptos-framework/sources/stake.move +++ b/aptos-move/framework/aptos-framework/sources/stake.move @@ -34,6 +34,7 @@ module aptos_framework::stake { use aptos_framework::system_addresses; use aptos_framework::staking_config::{Self, StakingConfig, StakingRewardsConfig}; use aptos_framework::chain_status; + use aptos_framework::permissioned_signer; friend aptos_framework::block; friend aptos_framework::genesis; @@ -81,6 +82,8 @@ module aptos_framework::stake { const EFEES_TABLE_ALREADY_EXISTS: u64 = 19; /// Validator set change temporarily disabled because of in-progress reconfiguration. Please retry after 1 minute. const ERECONFIGURATION_IN_PROGRESS: u64 = 20; + /// Signer does not have permission to perform stake logic. + const ENO_STAKE_PERMISSION: u64 = 28; /// Validator status enum. We can switch to proper enum later once Move supports it. const VALIDATOR_STATUS_PENDING_ACTIVE: u64 = 1; @@ -204,6 +207,8 @@ module aptos_framework::stake { pool_address: address, } + struct StakeManagementPermission has copy, drop, store {} + #[event] struct RegisterValidatorCandidate has drop, store { pool_address: address, @@ -344,6 +349,19 @@ module aptos_framework::stake { fees_table: Table>, } + /// Permissions + inline fun check_stake_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, StakeManagementPermission {}), + error::permission_denied(ENO_STAKE_PERMISSION), + ); + } + + /// Grant permission to mutate staking on behalf of the master signer. + public fun grant_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, StakeManagementPermission {}) + } + #[view] /// Return the lockup expiration of the stake pool at `pool_address`. /// This will throw an error if there's no stake pool at `pool_address`. @@ -536,6 +554,7 @@ module aptos_framework::stake { operator: address, voter: address, ) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet { + check_stake_permission(owner); initialize_owner(owner); move_to(owner, ValidatorConfig { consensus_pubkey: vector::empty(), @@ -565,6 +584,7 @@ module aptos_framework::stake { network_addresses: vector, fullnode_addresses: vector, ) acquires AllowedValidators { + check_stake_permission(account); // Checks the public key has a valid proof-of-possession to prevent rogue-key attacks. let pubkey_from_pop = &bls12381::public_key_from_bytes_with_pop( consensus_pubkey, @@ -582,6 +602,7 @@ module aptos_framework::stake { } fun initialize_owner(owner: &signer) acquires AllowedValidators { + check_stake_permission(owner); let owner_address = signer::address_of(owner); assert!(is_allowed(owner_address), error::not_found(EINELIGIBLE_VALIDATOR)); assert!(!stake_pool_exists(owner_address), error::already_exists(EALREADY_REGISTERED)); @@ -616,6 +637,7 @@ module aptos_framework::stake { /// Extract and return owner capability from the signing account. public fun extract_owner_cap(owner: &signer): OwnerCapability acquires OwnerCapability { + check_stake_permission(owner); let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); move_from(owner_address) @@ -624,6 +646,7 @@ module aptos_framework::stake { /// Deposit `owner_cap` into `account`. This requires `account` to not already have ownership of another /// staking pool. public fun deposit_owner_cap(owner: &signer, owner_cap: OwnerCapability) { + check_stake_permission(owner); assert!(!exists(signer::address_of(owner)), error::not_found(EOWNER_CAP_ALREADY_EXISTS)); move_to(owner, owner_cap); } @@ -635,6 +658,7 @@ module aptos_framework::stake { /// Allows an owner to change the operator of the stake pool. public entry fun set_operator(owner: &signer, new_operator: address) acquires OwnerCapability, StakePool { + check_stake_permission(owner); let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); let ownership_cap = borrow_global(owner_address); @@ -671,6 +695,7 @@ module aptos_framework::stake { /// Allows an owner to change the delegated voter of the stake pool. public entry fun set_delegated_voter(owner: &signer, new_voter: address) acquires OwnerCapability, StakePool { + check_stake_permission(owner); let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); let ownership_cap = borrow_global(owner_address); @@ -687,6 +712,7 @@ module aptos_framework::stake { /// Add `amount` of coins from the `account` owning the StakePool. public entry fun add_stake(owner: &signer, amount: u64) acquires OwnerCapability, StakePool, ValidatorSet { + check_stake_permission(owner); let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); let ownership_cap = borrow_global(owner_address); @@ -748,6 +774,7 @@ module aptos_framework::stake { /// Move `amount` of coins from pending_inactive to active. public entry fun reactivate_stake(owner: &signer, amount: u64) acquires OwnerCapability, StakePool { + check_stake_permission(owner); assert_reconfig_not_in_progress(); let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); @@ -796,6 +823,7 @@ module aptos_framework::stake { new_consensus_pubkey: vector, proof_of_possession: vector, ) acquires StakePool, ValidatorConfig { + check_stake_permission(operator); assert_reconfig_not_in_progress(); assert_stake_pool_exists(pool_address); @@ -840,6 +868,7 @@ module aptos_framework::stake { new_network_addresses: vector, new_fullnode_addresses: vector, ) acquires StakePool, ValidatorConfig { + check_stake_permission(operator); assert_reconfig_not_in_progress(); assert_stake_pool_exists(pool_address); let stake_pool = borrow_global_mut(pool_address); @@ -877,6 +906,7 @@ module aptos_framework::stake { /// Similar to increase_lockup_with_cap but will use ownership capability from the signing account. public entry fun increase_lockup(owner: &signer) acquires OwnerCapability, StakePool { + check_stake_permission(owner); let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); let ownership_cap = borrow_global(owner_address); @@ -921,6 +951,7 @@ module aptos_framework::stake { operator: &signer, pool_address: address ) acquires StakePool, ValidatorConfig, ValidatorSet { + check_stake_permission(operator); assert!( staking_config::get_allow_validator_set_change(&staking_config::get()), error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED), @@ -984,6 +1015,7 @@ module aptos_framework::stake { /// Similar to unlock_with_cap but will use ownership capability from the signing account. public entry fun unlock(owner: &signer, amount: u64) acquires OwnerCapability, StakePool { + check_stake_permission(owner); assert_reconfig_not_in_progress(); let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); @@ -1032,6 +1064,7 @@ module aptos_framework::stake { owner: &signer, withdraw_amount: u64 ) acquires OwnerCapability, StakePool, ValidatorSet { + check_stake_permission(owner); let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); let ownership_cap = borrow_global(owner_address); @@ -1091,6 +1124,7 @@ module aptos_framework::stake { operator: &signer, pool_address: address ) acquires StakePool, ValidatorSet { + check_stake_permission(operator); assert_reconfig_not_in_progress(); let config = staking_config::get(); assert!( diff --git a/aptos-move/framework/aptos-framework/sources/stake.spec.move b/aptos-move/framework/aptos-framework/sources/stake.spec.move index f922821e8ac83..29eea04f434ce 100644 --- a/aptos-move/framework/aptos-framework/sources/stake.spec.move +++ b/aptos-move/framework/aptos-framework/sources/stake.spec.move @@ -42,6 +42,7 @@ spec aptos_framework::stake { // ----------------- spec module { pragma verify = true; + pragma aborts_if_is_partial; // The validator set should satisfy its desired invariant. invariant [suspendable] exists(@aptos_framework) ==> validator_set_is_valid(); // After genesis, `AptosCoinCapabilities`, `ValidatorPerformance` and `ValidatorSet` exist. @@ -125,6 +126,11 @@ spec aptos_framework::stake { network_addresses: vector, fullnode_addresses: vector, ){ + pragma verify = false; + + include AbortsIfSignerPermissionStake { + s: account + }; let pubkey_from_pop = bls12381::spec_public_key_from_bytes_with_pop( consensus_pubkey, proof_of_possession_from_bytes(proof_of_possession) @@ -170,6 +176,9 @@ spec aptos_framework::stake { // This function casue timeout (property proved) pragma verify_duration_estimate = 60; pragma disable_invariants_in_body; + include AbortsIfSignerPermissionStake { + s: operator + }; aborts_if !staking_config::get_allow_validator_set_change(staking_config::get()); aborts_if !exists(pool_address); aborts_if !exists(pool_address); @@ -223,6 +232,9 @@ spec aptos_framework::stake { { // TODO(fa_migration) pragma verify = false; + include AbortsIfSignerPermissionStake { + s: owner + }; aborts_if reconfiguration_state::spec_is_in_progress(); let addr = signer::address_of(owner); let ownership_cap = global(addr); @@ -262,6 +274,9 @@ spec aptos_framework::stake { ) { pragma disable_invariants_in_body; requires chain_status::is_operating(); + include AbortsIfSignerPermissionStake { + s: operator + }; aborts_if reconfiguration_state::spec_is_in_progress(); let config = staking_config::get(); aborts_if !staking_config::get_allow_validator_set_change(config); @@ -297,12 +312,18 @@ spec aptos_framework::stake { spec extract_owner_cap(owner: &signer): OwnerCapability { // TODO: set because of timeout (property proved) pragma verify_duration_estimate = 300; + include AbortsIfSignerPermissionStake { + s: owner + }; let owner_address = signer::address_of(owner); aborts_if !exists(owner_address); ensures !exists(owner_address); } spec deposit_owner_cap(owner: &signer, owner_cap: OwnerCapability) { + include AbortsIfSignerPermissionStake { + s: owner + }; let owner_address = signer::address_of(owner); aborts_if exists(owner_address); ensures exists(owner_address); @@ -351,6 +372,9 @@ spec aptos_framework::stake { new_network_addresses: vector, new_fullnode_addresses: vector, ) { + include AbortsIfSignerPermissionStake { + s: operator + }; let pre_stake_pool = global(pool_address); let post validator_info = global(pool_address); modifies global(pool_address); @@ -397,6 +421,9 @@ spec aptos_framework::stake { new_consensus_pubkey: vector, proof_of_possession: vector, ) { + include AbortsIfSignerPermissionStake { + s: operator + }; let pre_stake_pool = global(pool_address); let post validator_info = global(pool_address); aborts_if reconfiguration_state::spec_is_in_progress(); @@ -502,6 +529,13 @@ spec aptos_framework::stake { }; } + spec schema AbortsIfSignerPermissionStake { + use aptos_framework::permissioned_signer; + s: signer; + let perm = StakeManagementPermission {}; + aborts_if !permissioned_signer::spec_check_permission_exists(s, perm); + } + spec schema UpdateStakePoolAbortsIf { use aptos_std::type_info; @@ -521,6 +555,7 @@ spec aptos_framework::stake { } spec distribute_rewards { + pragma aborts_if_is_partial; include ResourceRequirement; requires rewards_rate <= MAX_REWARDS_RATE; requires rewards_rate_denominator > 0; @@ -594,6 +629,7 @@ spec aptos_framework::stake { pragma opaque; // TODO: set because of timeout (property proved) pragma verify_duration_estimate = 300; + pragma verify = false; requires rewards_rate <= MAX_REWARDS_RATE; requires rewards_rate_denominator > 0; requires rewards_rate <= rewards_rate_denominator; @@ -671,7 +707,7 @@ spec aptos_framework::stake { spec add_stake_with_cap { pragma disable_invariants_in_body; - pragma verify_duration_estimate = 300; + pragma verify = false; include ResourceRequirement; let amount = coins.value; aborts_if reconfiguration_state::spec_is_in_progress(); @@ -679,10 +715,13 @@ spec aptos_framework::stake { } spec add_stake { - // TODO: These function passed locally however failed in github CI - pragma verify_duration_estimate = 120; + // TODO: fix + pragma verify = false; // TODO(fa_migration) pragma aborts_if_is_partial; + include AbortsIfSignerPermissionStake { + s: owner + }; aborts_if reconfiguration_state::spec_is_in_progress(); include ResourceRequirement; include AddStakeAbortsIfAndEnsures; @@ -696,7 +735,11 @@ spec aptos_framework::stake { ) { // TODO: These function failed in github CI pragma verify_duration_estimate = 120; - + pragma verify = false; + pragma aborts_if_is_partial; + include AbortsIfSignerPermissionStake { + s: owner + }; include ResourceRequirement; let addr = signer::address_of(owner); ensures global(addr) == ValidatorConfig { diff --git a/aptos-move/framework/aptos-framework/sources/staking_contract.spec.move b/aptos-move/framework/aptos-framework/sources/staking_contract.spec.move index e5ad85e92ae43..29120af5ffe2a 100644 --- a/aptos-move/framework/aptos-framework/sources/staking_contract.spec.move +++ b/aptos-move/framework/aptos-framework/sources/staking_contract.spec.move @@ -135,6 +135,10 @@ spec aptos_framework::staking_contract { ensures result == spec_staking_contract_exists(staker, operator); } + spec get_expected_stake_pool_address { + pragma aborts_if_is_partial; + } + spec fun spec_staking_contract_exists(staker: address, operator: address): bool { if (!exists(staker)) { false diff --git a/aptos-move/framework/aptos-framework/sources/staking_proxy.move b/aptos-move/framework/aptos-framework/sources/staking_proxy.move index 26d1aa33372ce..76ffbd2182a63 100644 --- a/aptos-move/framework/aptos-framework/sources/staking_proxy.move +++ b/aptos-move/framework/aptos-framework/sources/staking_proxy.move @@ -1,11 +1,31 @@ module aptos_framework::staking_proxy { + use std::error; use std::signer; use std::vector; + use aptos_framework::permissioned_signer; use aptos_framework::stake; use aptos_framework::staking_contract; use aptos_framework::vesting; + struct StakeProxyPermission has copy, drop, store {} + + /// Signer does not have permission to perform stake proxy logic. + const ENO_STAKE_PERMISSION: u64 = 28; + + /// Permissions + inline fun check_stake_proxy_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, StakeProxyPermission {}), + error::permission_denied(ENO_STAKE_PERMISSION), + ); + } + + /// Grant permission to mutate staking on behalf of the master signer. + public fun grant_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, StakeProxyPermission {}) + } + public entry fun set_operator(owner: &signer, old_operator: address, new_operator: address) { set_vesting_contract_operator(owner, old_operator, new_operator); set_staking_contract_operator(owner, old_operator, new_operator); @@ -19,6 +39,7 @@ module aptos_framework::staking_proxy { } public entry fun set_vesting_contract_operator(owner: &signer, old_operator: address, new_operator: address) { + check_stake_proxy_permission(owner); let owner_address = signer::address_of(owner); let vesting_contracts = &vesting::vesting_contracts(owner_address); vector::for_each_ref(vesting_contracts, |vesting_contract| { @@ -31,6 +52,7 @@ module aptos_framework::staking_proxy { } public entry fun set_staking_contract_operator(owner: &signer, old_operator: address, new_operator: address) { + check_stake_proxy_permission(owner); let owner_address = signer::address_of(owner); if (staking_contract::staking_contract_exists(owner_address, old_operator)) { let current_commission_percentage = staking_contract::commission_percentage(owner_address, old_operator); @@ -39,6 +61,7 @@ module aptos_framework::staking_proxy { } public entry fun set_stake_pool_operator(owner: &signer, new_operator: address) { + check_stake_proxy_permission(owner); let owner_address = signer::address_of(owner); if (stake::stake_pool_exists(owner_address)) { stake::set_operator(owner, new_operator); @@ -46,6 +69,7 @@ module aptos_framework::staking_proxy { } public entry fun set_vesting_contract_voter(owner: &signer, operator: address, new_voter: address) { + check_stake_proxy_permission(owner); let owner_address = signer::address_of(owner); let vesting_contracts = &vesting::vesting_contracts(owner_address); vector::for_each_ref(vesting_contracts, |vesting_contract| { @@ -57,6 +81,7 @@ module aptos_framework::staking_proxy { } public entry fun set_staking_contract_voter(owner: &signer, operator: address, new_voter: address) { + check_stake_proxy_permission(owner); let owner_address = signer::address_of(owner); if (staking_contract::staking_contract_exists(owner_address, operator)) { staking_contract::update_voter(owner, operator, new_voter); @@ -64,6 +89,7 @@ module aptos_framework::staking_proxy { } public entry fun set_stake_pool_voter(owner: &signer, new_voter: address) { + check_stake_proxy_permission(owner); if (stake::stake_pool_exists(signer::address_of(owner))) { stake::set_delegated_voter(owner, new_voter); }; diff --git a/aptos-move/framework/aptos-framework/sources/staking_proxy.spec.move b/aptos-move/framework/aptos-framework/sources/staking_proxy.spec.move index a1da120f0eed4..9f72369b39c0c 100644 --- a/aptos-move/framework/aptos-framework/sources/staking_proxy.spec.move +++ b/aptos-move/framework/aptos-framework/sources/staking_proxy.spec.move @@ -41,7 +41,14 @@ spec aptos_framework::staking_proxy { /// spec module { pragma verify = true; - pragma aborts_if_is_strict; + pragma aborts_if_is_partial; + } + + spec grant_permission { + pragma aborts_if_is_partial; + aborts_if !permissioned_signer::spec_is_permissioned_signer(permissioned_signer); + aborts_if permissioned_signer::spec_is_permissioned_signer(master); + aborts_if signer::address_of(master) != signer::address_of(permissioned_signer); } /// Aborts if conditions of SetStakePoolOperator are not met @@ -58,6 +65,7 @@ spec aptos_framework::staking_proxy { spec set_voter(owner: &signer, operator: address, new_voter: address) { // TODO: Can't verify `set_vesting_contract_voter` pragma aborts_if_is_partial; + pragma verify_duration_estimate = 120; include SetStakingContractVoter; include SetStakePoolVoterAbortsIf; } @@ -122,12 +130,21 @@ spec aptos_framework::staking_proxy { /// One of them are not exists spec set_stake_pool_operator(owner: &signer, new_operator: address) { include SetStakePoolOperator; + include AbortsIfSignerPermissionStakeProxy { + s: owner + }; + include exists(signer::address_of(owner)) ==> stake::AbortsIfSignerPermissionStake { + s:owner + }; } spec schema SetStakePoolOperator { owner: &signer; new_operator: address; + include AbortsIfSignerPermissionStakeProxy { + s: owner + }; let owner_address = signer::address_of(owner); let ownership_cap = borrow_global(owner_address); let pool_address = ownership_cap.pool_address; @@ -137,6 +154,9 @@ spec aptos_framework::staking_proxy { spec set_staking_contract_voter(owner: &signer, operator: address, new_voter: address) { include SetStakingContractVoter; + include AbortsIfSignerPermissionStakeProxy { + s: owner + }; } /// Make sure staking_contract_exists first @@ -166,16 +186,32 @@ spec aptos_framework::staking_proxy { spec set_stake_pool_voter(owner: &signer, new_voter: address) { include SetStakePoolVoterAbortsIf; + include AbortsIfSignerPermissionStakeProxy { + s: owner + }; + include exists(signer::address_of(owner)) ==> stake::AbortsIfSignerPermissionStake { + s:owner + }; } spec schema SetStakePoolVoterAbortsIf { owner: &signer; new_voter: address; + include AbortsIfSignerPermissionStakeProxy { + s: owner + }; let owner_address = signer::address_of(owner); let ownership_cap = global(owner_address); let pool_address = ownership_cap.pool_address; aborts_if stake::stake_pool_exists(owner_address) && !(exists(owner_address) && stake::stake_pool_exists(pool_address)); ensures stake::stake_pool_exists(owner_address) ==> global(pool_address).delegated_voter == new_voter; } + + spec schema AbortsIfSignerPermissionStakeProxy { + use aptos_framework::permissioned_signer; + s: signer; + let perm = StakeProxyPermission {}; + aborts_if !permissioned_signer::spec_check_permission_exists(s, perm); + } } diff --git a/aptos-move/framework/aptos-framework/sources/transaction_context.spec.move b/aptos-move/framework/aptos-framework/sources/transaction_context.spec.move index f9837e26e6a75..07487cb0919ae 100644 --- a/aptos-move/framework/aptos-framework/sources/transaction_context.spec.move +++ b/aptos-move/framework/aptos-framework/sources/transaction_context.spec.move @@ -58,11 +58,13 @@ spec aptos_framework::transaction_context { } spec generate_unique_address(): address { pragma opaque; + aborts_if [abstract] false; ensures [abstract] result == spec_generate_unique_address(); } spec fun spec_generate_unique_address(): address; spec generate_auid_address(): address { pragma opaque; + aborts_if [abstract] false; // property 3: Generating the unique address should return a vector with 32 bytes, if the auid feature flag is enabled. /// [high-level-req-3] ensures [abstract] result == spec_generate_unique_address(); diff --git a/aptos-move/framework/aptos-framework/sources/transaction_validation.move b/aptos-move/framework/aptos-framework/sources/transaction_validation.move index f9821da0b5486..c70a191e1784f 100644 --- a/aptos-move/framework/aptos-framework/sources/transaction_validation.move +++ b/aptos-move/framework/aptos-framework/sources/transaction_validation.move @@ -2,14 +2,18 @@ module aptos_framework::transaction_validation { use std::bcs; use std::error; use std::features; + use std::option; + use std::option::Option; use std::signer; use std::vector; use aptos_framework::account; use aptos_framework::aptos_account; + use aptos_framework::account_abstraction; use aptos_framework::aptos_coin::AptosCoin; use aptos_framework::chain_id; use aptos_framework::coin; + use aptos_framework::create_signer; use aptos_framework::system_addresses; use aptos_framework::timestamp; use aptos_framework::transaction_fee; @@ -71,10 +75,10 @@ module aptos_framework::transaction_validation { } fun prologue_common( - sender: signer, - gas_payer: address, + sender: &signer, + gas_payer: &signer, txn_sequence_number: u64, - txn_authentication_key: vector, + txn_authentication_key: Option>, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, @@ -87,23 +91,33 @@ module aptos_framework::transaction_validation { ); assert!(chain_id::get() == chain_id, error::invalid_argument(PROLOGUE_EBAD_CHAIN_ID)); - let transaction_sender = signer::address_of(&sender); + let transaction_sender = signer::address_of(sender); + let gas_payer_address = signer::address_of(gas_payer); if ( - transaction_sender == gas_payer + transaction_sender == gas_payer_address || account::exists_at(transaction_sender) || !features::sponsored_automatic_account_creation_enabled() || txn_sequence_number > 0 ) { assert!(account::exists_at(transaction_sender), error::invalid_argument(PROLOGUE_EACCOUNT_DOES_NOT_EXIST)); if (!features::transaction_simulation_enhancement_enabled() || - !skip_auth_key_check(is_simulation, &txn_authentication_key)) { - assert!( - txn_authentication_key == account::get_authentication_key(transaction_sender), - error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), - ) + !skip_auth_key_check(is_simulation, &txn_authentication_key)) { + if (option::is_some(&txn_authentication_key)) { + assert!( + txn_authentication_key == option::some(account::get_authentication_key(transaction_sender)), + error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY) + ); + } else { + assert!( + features::is_account_abstraction_enabled( + ) && account_abstraction::using_dispatchable_authenticator( + transaction_sender + ), + error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY) + ) + }; }; - let account_sequence_number = account::get_sequence_number(transaction_sender); assert!( txn_sequence_number < (1u64 << 63), @@ -130,7 +144,7 @@ module aptos_framework::transaction_validation { if (!features::transaction_simulation_enhancement_enabled() || !skip_auth_key_check(is_simulation, &txn_authentication_key)) { assert!( - txn_authentication_key == bcs::to_bytes(&transaction_sender), + txn_authentication_key == option::some(bcs::to_bytes(&transaction_sender)), error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), ); } @@ -138,15 +152,18 @@ module aptos_framework::transaction_validation { let max_transaction_fee = txn_gas_price * txn_max_gas_units; - if (!features::transaction_simulation_enhancement_enabled() || !skip_gas_payment(is_simulation, gas_payer)) { + if (!features::transaction_simulation_enhancement_enabled() || !skip_gas_payment( + is_simulation, + gas_payer_address + )) { if (features::operations_default_to_fa_apt_store_enabled()) { assert!( - aptos_account::is_fungible_balance_at_least(gas_payer, max_transaction_fee), + aptos_account::is_fungible_balance_at_least(gas_payer_address, max_transaction_fee), error::invalid_argument(PROLOGUE_ECANT_PAY_GAS_DEPOSIT) ); } else { assert!( - coin::is_balance_at_least(gas_payer, max_transaction_fee), + coin::is_balance_at_least(gas_payer_address, max_transaction_fee), error::invalid_argument(PROLOGUE_ECANT_PAY_GAS_DEPOSIT) ); } @@ -163,13 +180,12 @@ module aptos_framework::transaction_validation { chain_id: u8, _script_hash: vector, ) { - let gas_payer = signer::address_of(&sender); // prologue_common with is_simulation set to false behaves identically to the original script_prologue function. prologue_common( - sender, - gas_payer, + &sender, + &sender, txn_sequence_number, - txn_public_key, + option::some(txn_public_key), txn_gas_price, txn_max_gas_units, txn_expiration_time, @@ -192,12 +208,11 @@ module aptos_framework::transaction_validation { _script_hash: vector, is_simulation: bool, ) { - let gas_payer = signer::address_of(&sender); prologue_common( - sender, - gas_payer, + &sender, + &sender, txn_sequence_number, - txn_public_key, + option::some(txn_public_key), txn_gas_price, txn_max_gas_units, txn_expiration_time, @@ -217,21 +232,24 @@ module aptos_framework::transaction_validation { txn_expiration_time: u64, chain_id: u8, ) { - let sender_addr = signer::address_of(&sender); // prologue_common and multi_agent_common_prologue with is_simulation set to false behaves identically to the // original multi_agent_script_prologue function. prologue_common( - sender, - sender_addr, + &sender, + &sender, txn_sequence_number, - txn_sender_public_key, + option::some(txn_sender_public_key), txn_gas_price, txn_max_gas_units, txn_expiration_time, chain_id, false, ); - multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, false); + multi_agent_common_prologue( + secondary_signer_addresses, + vector::map(secondary_signer_public_key_hashes, |x| option::some(x)), + false + ); } // This function extends the multi_agent_script_prologue by adding a parameter to indicate simulation mode. @@ -249,24 +267,27 @@ module aptos_framework::transaction_validation { chain_id: u8, is_simulation: bool, ) { - let sender_addr = signer::address_of(&sender); prologue_common( - sender, - sender_addr, + &sender, + &sender, txn_sequence_number, - txn_sender_public_key, + option::some(txn_sender_public_key), txn_gas_price, txn_max_gas_units, txn_expiration_time, chain_id, is_simulation, ); - multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, is_simulation); + multi_agent_common_prologue( + secondary_signer_addresses, + vector::map(secondary_signer_public_key_hashes, |x| option::some(x)), + is_simulation + ); } fun multi_agent_common_prologue( secondary_signer_addresses: vector
, - secondary_signer_public_key_hashes: vector>, + secondary_signer_public_key_hashes: vector>>, is_simulation: bool, ) { let num_secondary_signers = vector::length(&secondary_signer_addresses); @@ -277,27 +298,53 @@ module aptos_framework::transaction_validation { let i = 0; while ({ - spec { - invariant i <= num_secondary_signers; - invariant forall j in 0..i: - account::exists_at(secondary_signer_addresses[j]); - invariant forall j in 0..i: - secondary_signer_public_key_hashes[j] == account::get_authentication_key(secondary_signer_addresses[j]) || - (features::spec_simulation_enhancement_enabled() && is_simulation && vector::is_empty(secondary_signer_public_key_hashes[j])); - }; + // spec { + // invariant i <= num_secondary_signers; + // invariant forall j in 0..i: + // account::exists_at(secondary_signer_addresses[j]); + // invariant forall j in 0..i: + // secondary_signer_public_key_hashes[j] == account::get_authentication_key(secondary_signer_addresses[j]) || + // (features::spec_simulation_enhancement_enabled() && is_simulation && vector::is_empty(secondary_signer_public_key_hashes[j])); + // account::account_resource_exists_at(secondary_signer_addresses[j]) + // && secondary_signer_public_key_hashes[j] + // == account::get_authentication_key(secondary_signer_addresses[j]) + // || features::account_abstraction_enabled() && account_abstraction::using_native_authenticator( + // secondary_signer_addresses[j] + // ) && option::spec_some(secondary_signer_public_key_hashes[j]) == account_abstraction::native_authenticator( + // account::exists_at(secondary_signer_addresses[j]) + // && secondary_signer_public_key_hashes[j] + // == account::spec_get_authentication_key(secondary_signer_addresses[j]) + // || features::spec_account_abstraction_enabled() && account_abstraction::using_native_authenticator( + // secondary_signer_addresses[j] + // ) && option::spec_some( + // secondary_signer_public_key_hashes[j] + // ) == account_abstraction::spec_native_authenticator( + // secondary_signer_addresses[j] + // ); + // }; (i < num_secondary_signers) }) { let secondary_address = *vector::borrow(&secondary_signer_addresses, i); assert!(account::exists_at(secondary_address), error::invalid_argument(PROLOGUE_EACCOUNT_DOES_NOT_EXIST)); - let signer_public_key_hash = *vector::borrow(&secondary_signer_public_key_hashes, i); if (!features::transaction_simulation_enhancement_enabled() || - !skip_auth_key_check(is_simulation, &signer_public_key_hash)) { - assert!( - signer_public_key_hash == account::get_authentication_key(secondary_address), - error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), - ) + !skip_auth_key_check(is_simulation, &signer_public_key_hash)) { + if (option::is_some(&signer_public_key_hash)) { + assert!( + signer_public_key_hash == option::some(account::get_authentication_key(secondary_address)), + error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY) + ); + } else { + assert!( + features::is_account_abstraction_enabled( + ) && account_abstraction::using_dispatchable_authenticator( + secondary_address + ), + error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY) + ) + }; }; + i = i + 1; } } @@ -319,17 +366,21 @@ module aptos_framework::transaction_validation { // prologue_common and multi_agent_common_prologue with is_simulation set to false behaves identically to the // original fee_payer_script_prologue function. prologue_common( - sender, - fee_payer_address, + &sender, + &create_signer::create_signer(fee_payer_address), txn_sequence_number, - txn_sender_public_key, + option::some(txn_sender_public_key), txn_gas_price, txn_max_gas_units, txn_expiration_time, chain_id, false, ); - multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, false); + multi_agent_common_prologue( + secondary_signer_addresses, + vector::map(secondary_signer_public_key_hashes, |x| option::some(x)), + false + ); assert!( fee_payer_public_key_hash == account::get_authentication_key(fee_payer_address), error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), @@ -355,24 +406,25 @@ module aptos_framework::transaction_validation { ) { assert!(features::fee_payer_enabled(), error::invalid_state(PROLOGUE_EFEE_PAYER_NOT_ENABLED)); prologue_common( - sender, - fee_payer_address, + &sender, + &create_signer::create_signer(fee_payer_address), txn_sequence_number, - txn_sender_public_key, + option::some(txn_sender_public_key), txn_gas_price, txn_max_gas_units, txn_expiration_time, chain_id, is_simulation, ); - multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, is_simulation); - if (!features::transaction_simulation_enhancement_enabled() || - !skip_auth_key_check(is_simulation, &fee_payer_public_key_hash)) { - assert!( - fee_payer_public_key_hash == account::get_authentication_key(fee_payer_address), - error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), - ) - } + multi_agent_common_prologue( + secondary_signer_addresses, + vector::map(secondary_signer_public_key_hashes, |x| option::some(x)), + is_simulation + ); + assert!( + fee_payer_public_key_hash == account::get_authentication_key(fee_payer_address), + error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY), + ) } /// Epilogue function is run after a transaction is successfully executed. @@ -385,7 +437,14 @@ module aptos_framework::transaction_validation { gas_units_remaining: u64, ) { let addr = signer::address_of(&account); - epilogue_gas_payer(account, addr, storage_fee_refunded, txn_gas_price, txn_max_gas_units, gas_units_remaining); + epilogue_gas_payer( + account, + addr, + storage_fee_refunded, + txn_gas_price, + txn_max_gas_units, + gas_units_remaining + ); } // This function extends the epilogue by adding a parameter to indicate simulation mode. @@ -400,7 +459,15 @@ module aptos_framework::transaction_validation { is_simulation: bool, ) { let addr = signer::address_of(&account); - epilogue_gas_payer_extended(account, addr, storage_fee_refunded, txn_gas_price, txn_max_gas_units, gas_units_remaining, is_simulation); + epilogue_gas_payer_extended( + account, + addr, + storage_fee_refunded, + txn_gas_price, + txn_max_gas_units, + gas_units_remaining, + is_simulation + ); } /// Epilogue function with explicit gas payer specified, is run after a transaction is successfully executed. @@ -411,7 +478,7 @@ module aptos_framework::transaction_validation { storage_fee_refunded: u64, txn_gas_price: u64, txn_max_gas_units: u64, - gas_units_remaining: u64, + gas_units_remaining: u64 ) { // epilogue_gas_payer_extended with is_simulation set to false behaves identically to the original // epilogue_gas_payer function. @@ -476,11 +543,138 @@ module aptos_framework::transaction_validation { account::increment_sequence_number(addr); } - inline fun skip_auth_key_check(is_simulation: bool, auth_key: &vector): bool { - is_simulation && vector::is_empty(auth_key) + inline fun skip_auth_key_check(is_simulation: bool, auth_key: &Option>): bool { + is_simulation && (option::is_none(auth_key) || vector::is_empty(option::borrow(auth_key))) } inline fun skip_gas_payment(is_simulation: bool, gas_payer: address): bool { is_simulation && gas_payer == @0x0 } + + /////////////////////////////////////////////////////////// + /// new set of functions + /////////////////////////////////////////////////////////// + + fun unified_prologue( + sender: signer, + txn_sender_public_key: Option>, + txn_sequence_number: u64, + 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, + is_simulation: bool, + ) { + prologue_common( + &sender, + &sender, + txn_sequence_number, + txn_sender_public_key, + txn_gas_price, + txn_max_gas_units, + txn_expiration_time, + chain_id, + is_simulation, + ); + multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, is_simulation); + } + + /// If there is no fee_payer, fee_payer = sender + fun unified_prologue_fee_payer( + sender: signer, + fee_payer: signer, + txn_sender_public_key: Option>, + fee_payer_public_key_hash: Option>, + txn_sequence_number: u64, + 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, + is_simulation: bool, + ) { + prologue_common( + &sender, + &fee_payer, + txn_sequence_number, + txn_sender_public_key, + txn_gas_price, + txn_max_gas_units, + txn_expiration_time, + chain_id, + is_simulation, + ); + multi_agent_common_prologue(secondary_signer_addresses, secondary_signer_public_key_hashes, is_simulation); + if (!features::transaction_simulation_enhancement_enabled() || + !skip_auth_key_check(is_simulation, &fee_payer_public_key_hash)) { + let fee_payer_address = signer::address_of(&fee_payer); + if (option::is_some(&fee_payer_public_key_hash)) { + assert!( + fee_payer_public_key_hash == option::some(account::get_authentication_key(fee_payer_address)), + error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY) + ); + } else { + assert!( + features::is_account_abstraction_enabled() && account_abstraction::using_dispatchable_authenticator( + fee_payer_address + ), + error::invalid_argument(PROLOGUE_EINVALID_ACCOUNT_AUTH_KEY) + ) + }; + } + } + + fun unified_epilogue( + account: signer, + gas_payer: signer, + storage_fee_refunded: u64, + txn_gas_price: u64, + txn_max_gas_units: u64, + gas_units_remaining: u64, + is_simulation: bool, + ) { + assert!(txn_max_gas_units >= gas_units_remaining, error::invalid_argument(EOUT_OF_GAS)); + let gas_used = txn_max_gas_units - gas_units_remaining; + + assert!( + (txn_gas_price as u128) * (gas_used as u128) <= MAX_U64, + error::out_of_range(EOUT_OF_GAS) + ); + let transaction_fee_amount = txn_gas_price * gas_used; + + let gas_payer_address = signer::address_of(&gas_payer); + // it's important to maintain the error code consistent with vm + // to do failed transaction cleanup. + if (!features::transaction_simulation_enhancement_enabled() || !skip_gas_payment( + is_simulation, + gas_payer_address + )) { + if (features::operations_default_to_fa_apt_store_enabled()) { + assert!( + aptos_account::is_fungible_balance_at_least(gas_payer_address, transaction_fee_amount), + error::out_of_range(PROLOGUE_ECANT_PAY_GAS_DEPOSIT), + ); + } else { + assert!( + coin::is_balance_at_least(gas_payer_address, transaction_fee_amount), + error::out_of_range(PROLOGUE_ECANT_PAY_GAS_DEPOSIT), + ); + }; + + if (transaction_fee_amount > storage_fee_refunded) { + let burn_amount = transaction_fee_amount - storage_fee_refunded; + transaction_fee::burn_fee(gas_payer_address, burn_amount); + } else if (transaction_fee_amount < storage_fee_refunded) { + let mint_amount = storage_fee_refunded - transaction_fee_amount; + transaction_fee::mint_and_refund(gas_payer_address, mint_amount) + }; + }; + + // Increment sequence number + let addr = signer::address_of(&account); + account::increment_sequence_number(addr); + } } diff --git a/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move b/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move index d97568e00374a..461be606cba87 100644 --- a/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move +++ b/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move @@ -31,11 +31,11 @@ spec aptos_framework::transaction_validation { /// Ensure caller is `aptos_framework`. /// Aborts if TransactionValidation already exists. spec initialize( - aptos_framework: &signer, - script_prologue_name: vector, - module_prologue_name: vector, - multi_agent_prologue_name: vector, - user_epilogue_name: vector, + aptos_framework: &signer, + script_prologue_name: vector, + module_prologue_name: vector, + multi_agent_prologue_name: vector, + user_epilogue_name: vector, ) { use std::signer; let addr = signer::address_of(aptos_framework); @@ -53,10 +53,10 @@ spec aptos_framework::transaction_validation { use aptos_framework::chain_id::{ChainId}; use aptos_framework::account::{Account}; use aptos_framework::coin::{CoinStore}; - sender: signer; - gas_payer: address; + sender: &signer; + gas_payer: &signer; txn_sequence_number: u64; - txn_authentication_key: vector; + txn_authentication_key: Option>; txn_gas_price: u64; txn_max_gas_units: u64; txn_expiration_time: u64; @@ -68,45 +68,50 @@ spec aptos_framework::transaction_validation { aborts_if !exists(@aptos_framework); aborts_if !(chain_id::get() == chain_id); let transaction_sender = signer::address_of(sender); + let gas_payer_addr = signer::address_of(gas_payer); aborts_if ( !features::spec_is_enabled(features::SPONSORED_AUTOMATIC_ACCOUNT_CREATION) || account::exists_at(transaction_sender) - || transaction_sender == gas_payer + || transaction_sender == gas_payer_addr || txn_sequence_number > 0 ) && ( !(txn_sequence_number >= global(transaction_sender).sequence_number) - || !(txn_authentication_key == global(transaction_sender).authentication_key) + || !(option::spec_is_none(txn_authentication_key) || option::spec_borrow( + txn_authentication_key + ) == global(transaction_sender).authentication_key) || !account::exists_at(transaction_sender) || !(txn_sequence_number == global(transaction_sender).sequence_number) ); aborts_if features::spec_is_enabled(features::SPONSORED_AUTOMATIC_ACCOUNT_CREATION) - && transaction_sender != gas_payer + && transaction_sender != gas_payer_addr && txn_sequence_number == 0 && !account::exists_at(transaction_sender) - && txn_authentication_key != bcs::to_bytes(transaction_sender); + && (option::spec_is_none(txn_authentication_key) || option::spec_borrow( + txn_authentication_key + ) != bcs::to_bytes(transaction_sender)); aborts_if !(txn_sequence_number < (1u64 << 63)); let max_transaction_fee = txn_gas_price * txn_max_gas_units; aborts_if max_transaction_fee > MAX_U64; - aborts_if !exists>(gas_payer); + aborts_if !exists>(gas_payer_addr); // property 1: The sender of a transaction should have sufficient coin balance to pay the transaction fee. /// [high-level-req-1] - aborts_if !(global>(gas_payer).coin.value >= max_transaction_fee); + aborts_if !(global>(gas_payer_addr).coin.value >= max_transaction_fee); } spec prologue_common( - sender: signer, - gas_payer: address, - txn_sequence_number: u64, - txn_authentication_key: vector, - txn_gas_price: u64, - txn_max_gas_units: u64, - txn_expiration_time: u64, - chain_id: u8, - is_simulation: bool, + sender: &signer, + gas_payer: &signer, + txn_sequence_number: u64, + txn_authentication_key: Option>, + txn_gas_price: u64, + txn_max_gas_units: u64, + txn_expiration_time: u64, + chain_id: u8, + is_simulation: bool, ) { // TODO(fa_migration) pragma verify = false; @@ -116,7 +121,7 @@ spec aptos_framework::transaction_validation { spec script_prologue_extended( sender: signer, txn_sequence_number: u64, - txn_public_key: vector, + txn_public_key: vector, txn_gas_price: u64, txn_max_gas_units: u64, txn_expiration_time: u64, @@ -127,8 +132,8 @@ spec aptos_framework::transaction_validation { // TODO(fa_migration) pragma verify = false; include PrologueCommonAbortsIf { - gas_payer: signer::address_of(sender), - txn_authentication_key: txn_public_key + gas_payer: sender, + txn_authentication_key: option::spec_some(txn_public_key) }; } @@ -148,7 +153,7 @@ spec aptos_framework::transaction_validation { spec schema MultiAgentPrologueCommonAbortsIf { secondary_signer_addresses: vector
; - secondary_signer_public_key_hashes: vector>; + secondary_signer_public_key_hashes: vector>>; is_simulation: bool; // Vectors to be `zipped with` should be of equal length. @@ -162,30 +167,36 @@ spec aptos_framework::transaction_validation { !account::exists_at(secondary_signer_addresses[i]); aborts_if exists i in 0..num_secondary_signers: !can_skip(features::spec_simulation_enhancement_enabled(), is_simulation, secondary_signer_public_key_hashes[i]) && - secondary_signer_public_key_hashes[i] != + option::spec_is_some(secondary_signer_public_key_hashes[i]) && option::spec_borrow( + secondary_signer_public_key_hashes[i] + ) != account::get_authentication_key(secondary_signer_addresses[i]); // By the end, all secondary signers account should exist and public key hash should match. ensures forall i in 0..num_secondary_signers: account::exists_at(secondary_signer_addresses[i]); ensures forall i in 0..num_secondary_signers: - secondary_signer_public_key_hashes[i] == account::get_authentication_key(secondary_signer_addresses[i]) + option::spec_is_none(secondary_signer_public_key_hashes[i]) || option::spec_borrow( + secondary_signer_public_key_hashes[i] + ) == + account::get_authentication_key(secondary_signer_addresses[i]) || can_skip(features::spec_simulation_enhancement_enabled(), is_simulation, secondary_signer_public_key_hashes[i]); } - spec fun can_skip(feature_flag: bool, is_simulation: bool, auth_key: vector): bool { - features::spec_simulation_enhancement_enabled() && is_simulation && vector::is_empty(auth_key) + spec fun can_skip(feature_flag: bool, is_simulation: bool, auth_key: Option>): bool { + features::spec_simulation_enhancement_enabled() && is_simulation && option::spec_is_none(auth_key) } spec multi_agent_common_prologue( - secondary_signer_addresses: vector
, - secondary_signer_public_key_hashes: vector>, - is_simulation: bool, + secondary_signer_addresses: vector
, + secondary_signer_public_key_hashes: vector>>, + is_simulation: bool, ) { - include MultiAgentPrologueCommonAbortsIf { - secondary_signer_addresses, - secondary_signer_public_key_hashes, - is_simulation, - }; + pragma aborts_if_is_partial; + // include MultiAgentPrologueCommonAbortsIf { + // secondary_signer_addresses, + // secondary_signer_public_key_hashes, + // is_simulation, + // }; } /// Aborts if length of public key hashed vector @@ -193,9 +204,9 @@ spec aptos_framework::transaction_validation { spec multi_agent_script_prologue_extended( sender: signer, txn_sequence_number: u64, - txn_sender_public_key: vector, - secondary_signer_addresses: vector
, - secondary_signer_public_key_hashes: vector>, + 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, @@ -203,19 +214,19 @@ spec aptos_framework::transaction_validation { is_simulation: bool, ) { pragma verify_duration_estimate = 120; - let gas_payer = signer::address_of(sender); + let gas_payer = sender; // TODO(fa_migration) pragma verify = false; - include PrologueCommonAbortsIf { - gas_payer, - txn_sequence_number, - txn_authentication_key: txn_sender_public_key, - }; - include MultiAgentPrologueCommonAbortsIf { - secondary_signer_addresses, - secondary_signer_public_key_hashes, - is_simulation, - }; + // include PrologueCommonAbortsIf { + // gas_payer, + // txn_sequence_number, + // txn_authentication_key: txn_sender_public_key, + // }; + // include MultiAgentPrologueCommonAbortsIf { + // secondary_signer_addresses, + // vector::map(secondary_signer_public_key_hashes, |x| option::spec_some(x)), + // is_simulation, + // }; } spec multi_agent_script_prologue( @@ -234,36 +245,37 @@ spec aptos_framework::transaction_validation { } spec fee_payer_script_prologue_extended( - sender: signer, - txn_sequence_number: u64, - txn_sender_public_key: vector, - secondary_signer_addresses: vector
, - secondary_signer_public_key_hashes: vector>, - fee_payer_address: address, - fee_payer_public_key_hash: vector, - txn_gas_price: u64, - txn_max_gas_units: u64, - txn_expiration_time: u64, - chain_id: u8, - is_simulation: bool, + sender: signer, + txn_sequence_number: u64, + txn_sender_public_key: vector, + secondary_signer_addresses: vector
, + secondary_signer_public_key_hashes: vector>, + fee_payer_address: address, + fee_payer_public_key_hash: vector, + txn_gas_price: u64, + txn_max_gas_units: u64, + txn_expiration_time: u64, + chain_id: u8, + is_simulation: bool, ) { + pragma aborts_if_is_partial; pragma verify_duration_estimate = 120; aborts_if !features::spec_is_enabled(features::FEE_PAYER_ENABLED); - let gas_payer = fee_payer_address; + let gas_payer = create_signer::create_signer(fee_payer_address); include PrologueCommonAbortsIf { gas_payer, txn_sequence_number, - txn_authentication_key: txn_sender_public_key, - }; - include MultiAgentPrologueCommonAbortsIf { - secondary_signer_addresses, - secondary_signer_public_key_hashes, - is_simulation, + txn_authentication_key: option::spec_some(txn_sender_public_key), }; - - aborts_if !account::exists_at(gas_payer); - aborts_if !(fee_payer_public_key_hash == account::get_authentication_key(gas_payer)); + // include MultiAgentPrologueCommonAbortsIf { + // secondary_signer_addresses, + // secondary_signer_public_key_hashes, + // is_simulation, + // }; + + aborts_if !account::exists_at(fee_payer_address); + aborts_if !(fee_payer_public_key_hash == account::get_authentication_key(fee_payer_address)); aborts_if !features::spec_fee_payer_enabled(); } @@ -340,6 +352,53 @@ spec aptos_framework::transaction_validation { pragma verify = false; } + spec unified_prologue( + sender: signer, + txn_sender_public_key: Option>, + txn_sequence_number: u64, + 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, + is_simulation: bool, + ) { + // TODO: temporary mockup + pragma verify = false; + } + + spec unified_prologue_fee_payer( + sender: signer, + fee_payer: signer, + txn_sender_public_key: Option>, + fee_payer_public_key_hash: Option>, + txn_sequence_number: u64, + 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, + is_simulation: bool, + ) { + // TODO: temporary mockup + pragma verify = false; + } + + spec unified_epilogue( + account: signer, + gas_payer: signer, + storage_fee_refunded: u64, + txn_gas_price: u64, + txn_max_gas_units: u64, + gas_units_remaining: u64, + is_simulation: bool, + ) { + // TODO: temporary mockup + pragma verify = false; + } + spec schema EpilogueGasPayerAbortsIf { use std::option; use aptos_std::type_info; diff --git a/aptos-move/framework/aptos-framework/sources/util.move b/aptos-move/framework/aptos-framework/sources/util.move index 332afa299c784..1ae94623447f5 100644 --- a/aptos-move/framework/aptos-framework/sources/util.move +++ b/aptos-move/framework/aptos-framework/sources/util.move @@ -8,9 +8,20 @@ module aptos_framework::util { /// Note that this function does not put any constraint on `T`. If code uses this function to /// deserialized a linear value, its their responsibility that the data they deserialize is /// owned. + /// + /// Function would abort if T has signer in it. public(friend) native fun from_bytes(bytes: vector): T; public fun address_from_bytes(bytes: vector): address { from_bytes(bytes) } + + #[test_only] + use std::bcs; + + #[test(s1 = @0x123)] + #[expected_failure(abort_code = 0x10001, location = Self)] + fun test_signer_roundtrip(s1: signer) { + from_bytes(bcs::to_bytes(&s1)); + } } diff --git a/aptos-move/framework/aptos-framework/sources/vesting.move b/aptos-move/framework/aptos-framework/sources/vesting.move index 34424b882a7e3..069cd18abbc6d 100644 --- a/aptos-move/framework/aptos-framework/sources/vesting.move +++ b/aptos-move/framework/aptos-framework/sources/vesting.move @@ -53,6 +53,7 @@ module aptos_framework::vesting { use aptos_framework::staking_contract; use aptos_framework::system_addresses; use aptos_framework::timestamp; + use aptos_framework::permissioned_signer; friend aptos_framework::genesis; @@ -90,6 +91,8 @@ module aptos_framework::vesting { const EPERMISSION_DENIED: u64 = 15; /// Zero items were provided to a *_many function. const EVEC_EMPTY_FOR_MANY_FUNCTION: u64 = 16; + /// Current permissioned signer cannot perform vesting operations. + const ENO_VESTING_PERMISSION: u64 = 17; /// Maximum number of shareholders a vesting pool can support. const MAXIMUM_SHAREHOLDERS: u64 = 30; @@ -328,6 +331,22 @@ module aptos_framework::vesting { amount: u64, } + /// Permissions to mutate the vesting config for a given account. + struct VestPermission has copy, drop, store {} + + /// Permissions + inline fun check_vest_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, VestPermission {}), + error::permission_denied(ENO_VESTING_PERMISSION), + ); + } + + /// Grant permission to perform vesting operations on behalf of the master signer. + public fun grant_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, VestPermission {}) + } + #[view] /// Return the address of the underlying stake pool (separate resource account) of the vesting contract. /// @@ -535,6 +554,7 @@ module aptos_framework::vesting { // Optional seed used when creating the staking contract account. contract_creation_seed: vector, ): address acquires AdminStore { + check_vest_permission(admin); assert!( !system_addresses::is_reserved_address(withdrawal_address), error::invalid_argument(EINVALID_WITHDRAWAL_ADDRESS), @@ -1053,6 +1073,7 @@ module aptos_framework::vesting { contract_address: address, shareholder: address, ) acquires VestingAccountManagement, VestingContract { + check_vest_permission(account); let vesting_contract = borrow_global_mut(contract_address); let addr = signer::address_of(account); assert!( @@ -1132,6 +1153,7 @@ module aptos_framework::vesting { admin: &signer, contract_creation_seed: vector, ): (signer, SignerCapability) acquires AdminStore { + check_vest_permission(admin); let admin_store = borrow_global_mut(signer::address_of(admin)); let seed = bcs::to_bytes(&signer::address_of(admin)); vector::append(&mut seed, bcs::to_bytes(&admin_store.nonce)); @@ -1151,6 +1173,7 @@ module aptos_framework::vesting { } fun verify_admin(admin: &signer, vesting_contract: &VestingContract) { + check_vest_permission(admin); assert!(signer::address_of(admin) == vesting_contract.admin, error::unauthenticated(ENOT_ADMIN)); } diff --git a/aptos-move/framework/aptos-framework/sources/vesting.spec.move b/aptos-move/framework/aptos-framework/sources/vesting.spec.move index 3bcbcbb11c0de..66244215a7ea7 100644 --- a/aptos-move/framework/aptos-framework/sources/vesting.spec.move +++ b/aptos-move/framework/aptos-framework/sources/vesting.spec.move @@ -105,13 +105,20 @@ spec aptos_framework::vesting { /// spec module { pragma verify = true; - pragma aborts_if_is_strict; + pragma aborts_if_is_partial; // property 2: The vesting pool should not exceed a maximum of 30 shareholders. /// [high-level-spec-2] invariant forall a: address where exists(a): global(a).grant_pool.shareholders_limit <= MAXIMUM_SHAREHOLDERS; } + spec schema AbortsIfPermissionedSigner { + use aptos_framework::permissioned_signer; + s: signer; + let perm = VestPermission {}; + aborts_if !permissioned_signer::spec_check_permission_exists(s, perm); + } + spec stake_pool_address(vesting_contract_address: address): address { aborts_if !exists(vesting_contract_address); } @@ -487,6 +494,7 @@ spec aptos_framework::vesting { } spec get_vesting_account_signer(admin: &signer, contract_address: address): signer { + pragma verify_duration_estimate = 120; include VerifyAdminAbortsIf; } @@ -530,8 +538,11 @@ spec aptos_framework::vesting { } spec verify_admin(admin: &signer, vesting_contract: &VestingContract) { + pragma verify_duration_estimate = 120; + aborts_if permissioned_signer::spec_is_permissioned_signer(admin); /// [high-level-req-9] aborts_if signer::address_of(admin) != vesting_contract.admin; + // include AbortsIfPermissionedSigner { s: admin }; } spec assert_vesting_contract_exists(contract_address: address) { @@ -630,6 +641,8 @@ spec aptos_framework::vesting { spec schema VerifyAdminAbortsIf { contract_address: address; admin: signer; + + aborts_if permissioned_signer::spec_is_permissioned_signer(admin); aborts_if !exists(contract_address); let vesting_contract = global(contract_address); aborts_if signer::address_of(admin) != vesting_contract.admin; diff --git a/aptos-move/framework/aptos-framework/sources/voting.move b/aptos-move/framework/aptos-framework/sources/voting.move index 8312ac17b7619..8dd1b0cb2e9a5 100644 --- a/aptos-move/framework/aptos-framework/sources/voting.move +++ b/aptos-move/framework/aptos-framework/sources/voting.move @@ -34,6 +34,7 @@ module aptos_framework::voting { use aptos_framework::account; use aptos_framework::event::{Self, EventHandle}; + use aptos_framework::permissioned_signer; use aptos_framework::timestamp; use aptos_framework::transaction_context; use aptos_std::from_bcs; @@ -63,6 +64,8 @@ module aptos_framework::voting { const ESINGLE_STEP_PROPOSAL_CANNOT_HAVE_NEXT_EXECUTION_HASH: u64 = 11; /// Cannot call `is_multi_step_proposal_in_execution()` on single-step proposals. const EPROPOSAL_IS_SINGLE_STEP: u64 = 12; + /// Cannot call `is_multi_step_proposal_in_execution()` on single-step proposals. + const ENO_VOTE_PERMISSION: u64 = 13; /// ProposalStateEnum representing proposal state. const PROPOSAL_STATE_PENDING: u64 = 0; @@ -188,7 +191,23 @@ module aptos_framework::voting { num_votes: u64, } + struct VotePermission has copy, drop, store {} + + /// Permissions + inline fun check_vote_permission(s: &signer) { + assert!( + permissioned_signer::check_permission_exists(s, VotePermission {}), + error::permission_denied(ENO_VOTE_PERMISSION), + ); + } + + /// Grant permission to vote on behalf of the master signer. + public fun grant_permission(master: &signer, permissioned_signer: &signer) { + permissioned_signer::authorize_unlimited(master, permissioned_signer, VotePermission {}) + } + public fun register(account: &signer) { + check_vote_permission(account); let addr = signer::address_of(account); assert!(!exists>(addr), error::already_exists(EVOTING_FORUM_ALREADY_REGISTERED)); diff --git a/aptos-move/framework/aptos-framework/sources/voting.spec.move b/aptos-move/framework/aptos-framework/sources/voting.spec.move index a1c05091e54b6..296593c5c9f25 100644 --- a/aptos-move/framework/aptos-framework/sources/voting.spec.move +++ b/aptos-move/framework/aptos-framework/sources/voting.spec.move @@ -40,10 +40,18 @@ spec aptos_framework::voting { /// spec module { pragma verify = true; - pragma aborts_if_is_strict; + pragma aborts_if_is_partial; + } + + spec schema AbortsIfPermissionedSigner { + use aptos_framework::permissioned_signer; + s: signer; + let perm = VotePermission {}; + aborts_if !permissioned_signer::spec_check_permission_exists(s, perm); } spec register(account: &signer) { + // include AbortsIfPermissionedSigner { s: account }; let addr = signer::address_of(account); // Will abort if there's already a `VotingForum` under addr diff --git a/aptos-move/framework/aptos-framework/tests/account_abstraction_tests.move b/aptos-move/framework/aptos-framework/tests/account_abstraction_tests.move new file mode 100644 index 0000000000000..a54d835a5bef3 --- /dev/null +++ b/aptos-move/framework/aptos-framework/tests/account_abstraction_tests.move @@ -0,0 +1,6 @@ +#[test_only] +module aptos_framework::account_abstraction_tests { + use aptos_framework::auth_data::AbstractionAuthData; + + public fun test_auth(account: signer, _data: AbstractionAuthData): signer { account } +} diff --git a/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/object_code_deployment.md b/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/object_code_deployment.md index 210d0a1e6b892..354117d123444 100644 --- a/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/object_code_deployment.md +++ b/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/object_code_deployment.md @@ -39,7 +39,10 @@ Once modules are marked as immutable, they cannot be made mutable again. - [Struct `Publish`](#0x1_object_code_deployment_Publish) - [Struct `Upgrade`](#0x1_object_code_deployment_Upgrade) - [Struct `Freeze`](#0x1_object_code_deployment_Freeze) +- [Struct `ObjectCodePermission`](#0x1_object_code_deployment_ObjectCodePermission) - [Constants](#@Constants_0) +- [Function `check_signer_permission`](#0x1_object_code_deployment_check_signer_permission) +- [Function `grant_permission`](#0x1_object_code_deployment_grant_permission) - [Function `publish`](#0x1_object_code_deployment_publish) - [Function `object_seed`](#0x1_object_code_deployment_object_seed) - [Function `upgrade`](#0x1_object_code_deployment_upgrade) @@ -53,6 +56,7 @@ Once modules are marked as immutable, they cannot be made mutable again. use 0x1::event; use 0x1::features; use 0x1::object; +use 0x1::permissioned_signer; use 0x1::signer; use 0x1::vector;
@@ -173,6 +177,33 @@ Event emitted when code in an existing object is made immutable. + + + + +## Struct `ObjectCodePermission` + + + +
struct ObjectCodePermission has copy, drop, store
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ +
@@ -190,6 +221,16 @@ Event emitted when code in an existing object is made immutable. + + +Current permissioned signer cannot deploy object code. + + +
const ENO_CODE_PERMISSION: u64 = 4;
+
+ + + Not the owner of the code_object @@ -219,6 +260,59 @@ Object code deployment feature not supported. + + +## Function `check_signer_permission` + +Permissions + + +
fun check_signer_permission(s: &signer)
+
+ + + +
+Implementation + + +
inline fun check_signer_permission(s: &signer) {
+    assert!(
+        permissioned_signer::check_permission_exists(s, ObjectCodePermission {}),
+        error::permission_denied(ENO_CODE_PERMISSION),
+    );
+}
+
+ + + +
+ + + +## Function `grant_permission` + +Grant permission to publish code on behalf of the master signer. + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer)
+
+ + + +
+Implementation + + +
public fun grant_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, ObjectCodePermission {})
+}
+
+ + + +
+ ## Function `publish` @@ -243,6 +337,7 @@ the code to be published via code. T metadata_serialized: vector<u8>, code: vector<vector<u8>>, ) { + check_signer_permission(publisher); assert!( features::is_object_code_deployment_enabled(), error::unavailable(EOBJECT_CODE_DEPLOYMENT_NOT_SUPPORTED), @@ -319,6 +414,7 @@ Requires the publisher to be the owner of the code_object. code: vector<vector<u8>>, code_object: Object<PackageRegistry>, ) acquires ManagingRefs { + check_signer_permission(publisher); let publisher_address = signer::address_of(publisher); assert!( object::is_owner(code_object, publisher_address), diff --git a/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/permissioned_signer.md b/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/permissioned_signer.md new file mode 100644 index 0000000000000..c4c76a6d0bea9 --- /dev/null +++ b/aptos-move/framework/aptos-framework/tests/compiler-v2-doc/permissioned_signer.md @@ -0,0 +1,1930 @@ + + + +# Module `0x1::permissioned_signer` + +A _permissioned signer_ consists of a pair of the original signer and a generated +address which is used store information about associated permissions. + +A permissioned signer is a restricted version of a signer. Functions move_to and +address_of behave the same, and can be passed wherever signer is needed. However, +code can internally query for the permissions to assert additional restrictions on +the use of the signer. + +A client which is interested in restricting access granted via a signer can create a permissioned signer +and pass on to other existing code without changes to existing APIs. Core functions in the framework, for +example account functions, can then assert availability of permissions, effectively restricting +existing code in a compatible way. + +After introducing the core functionality, examples are provided for withdraw limit on accounts, and +for blind signing. + + +- [Resource `GrantedPermissionHandles`](#0x1_permissioned_signer_GrantedPermissionHandles) +- [Enum `PermissionedHandle`](#0x1_permissioned_signer_PermissionedHandle) +- [Enum `StorablePermissionedHandle`](#0x1_permissioned_signer_StorablePermissionedHandle) +- [Enum Resource `PermissionStorage`](#0x1_permissioned_signer_PermissionStorage) +- [Enum `StoredPermission`](#0x1_permissioned_signer_StoredPermission) +- [Enum `Permission`](#0x1_permissioned_signer_Permission) +- [Constants](#@Constants_0) +- [Function `create_permissioned_handle`](#0x1_permissioned_signer_create_permissioned_handle) +- [Function `create_storable_permissioned_handle`](#0x1_permissioned_signer_create_storable_permissioned_handle) +- [Function `destroy_permissioned_handle`](#0x1_permissioned_signer_destroy_permissioned_handle) +- [Function `destroy_storable_permissioned_handle`](#0x1_permissioned_signer_destroy_storable_permissioned_handle) +- [Function `destroy_permissions_storage_address`](#0x1_permissioned_signer_destroy_permissions_storage_address) +- [Function `signer_from_permissioned_handle`](#0x1_permissioned_signer_signer_from_permissioned_handle) +- [Function `signer_from_storable_permissioned_handle`](#0x1_permissioned_signer_signer_from_storable_permissioned_handle) +- [Function `revoke_permission_storage_address`](#0x1_permissioned_signer_revoke_permission_storage_address) +- [Function `revoke_all_handles`](#0x1_permissioned_signer_revoke_all_handles) +- [Function `permissions_storage_address`](#0x1_permissioned_signer_permissions_storage_address) +- [Function `assert_master_signer`](#0x1_permissioned_signer_assert_master_signer) +- [Function `is_above`](#0x1_permissioned_signer_is_above) +- [Function `consume_capacity`](#0x1_permissioned_signer_consume_capacity) +- [Function `increase_capacity`](#0x1_permissioned_signer_increase_capacity) +- [Function `merge`](#0x1_permissioned_signer_merge) +- [Function `map_or`](#0x1_permissioned_signer_map_or) +- [Function `insert_or`](#0x1_permissioned_signer_insert_or) +- [Function `authorize`](#0x1_permissioned_signer_authorize) +- [Function `authorize_unlimited`](#0x1_permissioned_signer_authorize_unlimited) +- [Function `check_permission_exists`](#0x1_permissioned_signer_check_permission_exists) +- [Function `check_permission_capacity_above`](#0x1_permissioned_signer_check_permission_capacity_above) +- [Function `check_permission_consume`](#0x1_permissioned_signer_check_permission_consume) +- [Function `capacity`](#0x1_permissioned_signer_capacity) +- [Function `revoke_permission`](#0x1_permissioned_signer_revoke_permission) +- [Function `extract_permission`](#0x1_permissioned_signer_extract_permission) +- [Function `extract_all_permission`](#0x1_permissioned_signer_extract_all_permission) +- [Function `address_of`](#0x1_permissioned_signer_address_of) +- [Function `consume_permission`](#0x1_permissioned_signer_consume_permission) +- [Function `store_permission`](#0x1_permissioned_signer_store_permission) +- [Function `is_permissioned_signer`](#0x1_permissioned_signer_is_permissioned_signer) +- [Function `permission_address`](#0x1_permissioned_signer_permission_address) +- [Function `signer_from_permissioned_handle_impl`](#0x1_permissioned_signer_signer_from_permissioned_handle_impl) +- [Specification](#@Specification_1) + - [Function `create_permissioned_handle`](#@Specification_1_create_permissioned_handle) + - [Function `create_storable_permissioned_handle`](#@Specification_1_create_storable_permissioned_handle) + - [Function `destroy_permissioned_handle`](#@Specification_1_destroy_permissioned_handle) + - [Function `destroy_storable_permissioned_handle`](#@Specification_1_destroy_storable_permissioned_handle) + - [Function `revoke_permission_storage_address`](#@Specification_1_revoke_permission_storage_address) + - [Function `authorize`](#@Specification_1_authorize) + - [Function `check_permission_exists`](#@Specification_1_check_permission_exists) + - [Function `check_permission_capacity_above`](#@Specification_1_check_permission_capacity_above) + - [Function `check_permission_consume`](#@Specification_1_check_permission_consume) + - [Function `capacity`](#@Specification_1_capacity) + - [Function `consume_permission`](#@Specification_1_consume_permission) + - [Function `is_permissioned_signer`](#@Specification_1_is_permissioned_signer) + - [Function `permission_address`](#@Specification_1_permission_address) + - [Function `signer_from_permissioned_handle_impl`](#@Specification_1_signer_from_permissioned_handle_impl) + + +
use 0x1::copyable_any;
+use 0x1::create_signer;
+use 0x1::error;
+use 0x1::option;
+use 0x1::signer;
+use 0x1::simple_map;
+use 0x1::timestamp;
+use 0x1::transaction_context;
+use 0x1::vector;
+
+ + + + + +## Resource `GrantedPermissionHandles` + + + +
struct GrantedPermissionHandles has key
+
+ + + +
+Fields + + +
+
+active_handles: vector<address> +
+
+ +
+
+ + +
+ + + +## Enum `PermissionedHandle` + + + +
enum PermissionedHandle
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+master_account_addr: address +
+
+ +
+
+permissions_storage_addr: address +
+
+ +
+
+ + +
+ +
+ +
+ + + +## Enum `StorablePermissionedHandle` + + + +
enum StorablePermissionedHandle has store
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+master_account_addr: address +
+
+ +
+
+permissions_storage_addr: address +
+
+ +
+
+expiration_time: u64 +
+
+ +
+
+ + +
+ +
+ +
+ + + +## Enum Resource `PermissionStorage` + + + +
enum PermissionStorage has key
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+perms: simple_map::SimpleMap<copyable_any::Any, permissioned_signer::StoredPermission> +
+
+ +
+
+ + +
+ +
+ +
+ + + +## Enum `StoredPermission` + + + +
enum StoredPermission has copy, drop, store
+
+ + + +
+Variants + + +
+Unlimited + + +
+Fields + + +
+
+ + +
+ +
+ +
+Capacity + + +
+Fields + + +
+
+0: u256 +
+
+ +
+
+ + +
+ +
+ +
+ + + +## Enum `Permission` + + + +
enum Permission<K>
+
+ + + +
+Variants + + +
+V1 + + +
+Fields + + +
+
+owner_address: address +
+
+ +
+
+key: K +
+
+ +
+
+perm: permissioned_signer::StoredPermission +
+
+ +
+
+ + +
+ +
+ +
+ + + +## Constants + + + + +Cannot authorize a permission. + + +
const ECANNOT_AUTHORIZE: u64 = 2;
+
+ + + + + +signer doesn't have enough capacity to extract permission. + + +
const ECANNOT_EXTRACT_PERMISSION: u64 = 4;
+
+ + + + + +Trying to grant permission using master signer. + + +
const ENOT_MASTER_SIGNER: u64 = 1;
+
+ + + + + +Access permission information from a master signer. + + +
const ENOT_PERMISSIONED_SIGNER: u64 = 3;
+
+ + + + + +destroying permission handle that has already been revoked or not owned by the +given master signer. + + +
const E_NOT_ACTIVE: u64 = 8;
+
+ + + + + +permission handle has expired. + + +
const E_PERMISSION_EXPIRED: u64 = 5;
+
+ + + + + +storing extracted permission into a different signer. + + +
const E_PERMISSION_MISMATCH: u64 = 6;
+
+ + + + + +permission handle has been revoked by the original signer. + + +
const E_PERMISSION_REVOKED: u64 = 7;
+
+ + + + + + + +
const U256_MAX: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;
+
+ + + + + +## Function `create_permissioned_handle` + +Create an ephermeral permission handle based on the master signer. + +This handle can be used to derive a signer that can be used in the context of +the current transaction. + + +
public fun create_permissioned_handle(master: &signer): permissioned_signer::PermissionedHandle
+
+ + + +
+Implementation + + +
public fun create_permissioned_handle(master: &signer): PermissionedHandle {
+    assert_master_signer(master);
+    let permissions_storage_addr = generate_auid_address();
+    let master_account_addr = signer::address_of(master);
+
+    move_to(
+        &create_signer(permissions_storage_addr),
+        PermissionStorage::V1 { perms: simple_map::new() }
+    );
+
+    PermissionedHandle::V1 { master_account_addr, permissions_storage_addr }
+}
+
+ + + +
+ + + +## Function `create_storable_permissioned_handle` + +Create an storable permission handle based on the master signer. + +This handle can be used to derive a signer that can be stored by a smart contract. +This is as dangerous as key delegation, thus it remains public(package) for now. + +The caller should check if expiration_time is not too far in the future. + + +
public(friend) fun create_storable_permissioned_handle(master: &signer, expiration_time: u64): permissioned_signer::StorablePermissionedHandle
+
+ + + +
+Implementation + + +
public(package) fun create_storable_permissioned_handle(
+    master: &signer, expiration_time: u64
+): StorablePermissionedHandle acquires GrantedPermissionHandles {
+    assert_master_signer(master);
+    let permissions_storage_addr = generate_auid_address();
+    let master_account_addr = signer::address_of(master);
+
+    assert!(
+        timestamp::now_seconds() < expiration_time,
+        error::permission_denied(E_PERMISSION_EXPIRED)
+    );
+
+    if (!exists<GrantedPermissionHandles>(master_account_addr)) {
+        move_to<GrantedPermissionHandles>(
+            master, GrantedPermissionHandles { active_handles: vector::empty() }
+        );
+    };
+
+    vector::push_back(
+        &mut borrow_global_mut<GrantedPermissionHandles>(master_account_addr).active_handles,
+        permissions_storage_addr
+    );
+
+    move_to(
+        &create_signer(permissions_storage_addr),
+        PermissionStorage::V1 { perms: simple_map::new() }
+    );
+
+    StorablePermissionedHandle::V1 {
+        master_account_addr,
+        permissions_storage_addr,
+        expiration_time
+    }
+}
+
+ + + +
+ + + +## Function `destroy_permissioned_handle` + +Destroys an ephermeral permission handle. Clean up the permission stored in that handle + + +
public fun destroy_permissioned_handle(p: permissioned_signer::PermissionedHandle)
+
+ + + +
+Implementation + + +
public fun destroy_permissioned_handle(p: PermissionedHandle) acquires PermissionStorage {
+    let PermissionedHandle::V1 { master_account_addr: _, permissions_storage_addr } =
+        p;
+    destroy_permissions_storage_address(permissions_storage_addr);
+}
+
+ + + +
+ + + +## Function `destroy_storable_permissioned_handle` + +Destroys a storable permission handle. Clean up the permission stored in that handle + + +
public(friend) fun destroy_storable_permissioned_handle(p: permissioned_signer::StorablePermissionedHandle)
+
+ + + +
+Implementation + + +
public(package) fun destroy_storable_permissioned_handle(
+    p: StorablePermissionedHandle
+) acquires PermissionStorage, GrantedPermissionHandles {
+    let StorablePermissionedHandle::V1 {
+        master_account_addr,
+        permissions_storage_addr,
+        expiration_time: _
+    } = p;
+
+    assert!(
+        exists<GrantedPermissionHandles>(master_account_addr),
+        error::permission_denied(E_PERMISSION_REVOKED),
+    );
+    let granted_permissions =
+        borrow_global_mut<GrantedPermissionHandles>(master_account_addr);
+    let (found, idx) = vector::index_of(
+        &granted_permissions.active_handles, &permissions_storage_addr
+    );
+
+    // Removing the address from the active handle list if it's still active.
+    if(found) {
+        vector::swap_remove(&mut granted_permissions.active_handles, idx);
+    };
+
+    destroy_permissions_storage_address(permissions_storage_addr);
+}
+
+ + + +
+ + + +## Function `destroy_permissions_storage_address` + + + +
fun destroy_permissions_storage_address(permissions_storage_addr: address)
+
+ + + +
+Implementation + + +
inline fun destroy_permissions_storage_address(
+    permissions_storage_addr: address
+) acquires PermissionStorage {
+    if (exists<PermissionStorage>(permissions_storage_addr)) {
+        let PermissionStorage::V1 { perms } =
+            move_from<PermissionStorage>(permissions_storage_addr);
+        simple_map::destroy(
+            perms,
+            |_dk| {},
+            |_dv| {}
+        );
+    }
+}
+
+ + + +
+ + + +## Function `signer_from_permissioned_handle` + +Generate the permissioned signer based on the ephermeral permission handle. + +This signer can be used as a regular signer for other smart contracts. However when such +signer interacts with various framework functions, it would subject to permission checks +and would abort if check fails. + + +
public fun signer_from_permissioned_handle(p: &permissioned_signer::PermissionedHandle): signer
+
+ + + +
+Implementation + + +
public fun signer_from_permissioned_handle(p: &PermissionedHandle): signer {
+    signer_from_permissioned_handle_impl(
+        p.master_account_addr, p.permissions_storage_addr
+    )
+}
+
+ + + +
+ + + +## Function `signer_from_storable_permissioned_handle` + +Generate the permissioned signer based on the storable permission handle. + + +
public(friend) fun signer_from_storable_permissioned_handle(p: &permissioned_signer::StorablePermissionedHandle): signer
+
+ + + +
+Implementation + + +
public(package) fun signer_from_storable_permissioned_handle(
+    p: &StorablePermissionedHandle
+): signer {
+    assert!(
+        timestamp::now_seconds() < p.expiration_time,
+        error::permission_denied(E_PERMISSION_EXPIRED)
+    );
+    assert!(
+        exists<PermissionStorage>(p.permissions_storage_addr),
+        error::permission_denied(E_PERMISSION_REVOKED)
+    );
+    signer_from_permissioned_handle_impl(
+        p.master_account_addr, p.permissions_storage_addr
+    )
+}
+
+ + + +
+ + + +## Function `revoke_permission_storage_address` + +Revoke a specific storable permission handle immediately. This would disallow owner of +the storable permission handle to derive signer from it anymore. + + +
public entry fun revoke_permission_storage_address(s: &signer, permissions_storage_addr: address)
+
+ + + +
+Implementation + + +
public entry fun revoke_permission_storage_address(
+    s: &signer, permissions_storage_addr: address
+) acquires GrantedPermissionHandles, PermissionStorage {
+    assert!(
+        !is_permissioned_signer(s), error::permission_denied(ENOT_MASTER_SIGNER)
+    );
+    let master_account_addr = signer::address_of(s);
+
+    assert!(
+        exists<GrantedPermissionHandles>(master_account_addr),
+        error::permission_denied(E_PERMISSION_REVOKED),
+    );
+    let granted_permissions =
+        borrow_global_mut<GrantedPermissionHandles>(master_account_addr);
+    let (found, idx) = vector::index_of(
+        &granted_permissions.active_handles, &permissions_storage_addr
+    );
+
+    // The address has to be in the activated list in the master account address.
+    assert!(found, error::permission_denied(E_NOT_ACTIVE));
+    vector::swap_remove(&mut granted_permissions.active_handles, idx);
+    destroy_permissions_storage_address(permissions_storage_addr);
+}
+
+ + + +
+ + + +## Function `revoke_all_handles` + +Revoke all storable permission handle of the signer immediately. + + +
public entry fun revoke_all_handles(s: &signer)
+
+ + + +
+Implementation + + +
public entry fun revoke_all_handles(s: &signer) acquires GrantedPermissionHandles, PermissionStorage {
+    assert!(
+        !is_permissioned_signer(s), error::permission_denied(ENOT_MASTER_SIGNER)
+    );
+    let master_account_addr = signer::address_of(s);
+    if (!exists<GrantedPermissionHandles>(master_account_addr)) { return };
+
+    let granted_permissions =
+        borrow_global_mut<GrantedPermissionHandles>(master_account_addr);
+    let delete_list = vector::trim_reverse(
+        &mut granted_permissions.active_handles, 0
+    );
+    vector::destroy(
+        delete_list,
+        |address| {
+            destroy_permissions_storage_address(address);
+        }
+    )
+}
+
+ + + +
+ + + +## Function `permissions_storage_address` + +Return the permission handle address so that it could be used for revocation purpose. + + +
public(friend) fun permissions_storage_address(p: &permissioned_signer::StorablePermissionedHandle): address
+
+ + + +
+Implementation + + +
public(package) fun permissions_storage_address(
+    p: &StorablePermissionedHandle
+): address {
+    p.permissions_storage_addr
+}
+
+ + + +
+ + + +## Function `assert_master_signer` + +Helper function that would abort if the signer passed in is a permissioned signer. + + +
public fun assert_master_signer(s: &signer)
+
+ + + +
+Implementation + + +
public fun assert_master_signer(s: &signer) {
+    assert!(
+        !is_permissioned_signer(s), error::permission_denied(ENOT_MASTER_SIGNER)
+    );
+}
+
+ + + +
+ + + +## Function `is_above` + +===================================================================================================== +StoredPermission operations + +check if StoredPermission has at least threshold capacity. + + +
fun is_above(perm: &permissioned_signer::StoredPermission, threshold: u256): bool
+
+ + + +
+Implementation + + +
fun is_above(perm: &StoredPermission, threshold: u256): bool {
+    match (perm) {
+        StoredPermission::Capacity(capacity) => *capacity > threshold,
+        StoredPermission::Unlimited => true,
+    }
+}
+
+ + + +
+ + + +## Function `consume_capacity` + +consume threshold capacity from StoredPermission + + +
fun consume_capacity(perm: &mut permissioned_signer::StoredPermission, threshold: u256): bool
+
+ + + +
+Implementation + + +
fun consume_capacity(perm: &mut StoredPermission, threshold: u256): bool {
+    match (perm) {
+        StoredPermission::Capacity(current_capacity) => {
+            if (*current_capacity >= threshold) {
+                *current_capacity = *current_capacity - threshold;
+                true
+            } else { false }
+        }
+        StoredPermission::Unlimited => true
+    }
+}
+
+ + + +
+ + + +## Function `increase_capacity` + +increase threshold capacity from StoredPermission + + +
fun increase_capacity(perm: &mut permissioned_signer::StoredPermission, threshold: u256)
+
+ + + +
+Implementation + + +
fun increase_capacity(perm: &mut StoredPermission, threshold: u256) {
+    match (perm) {
+        StoredPermission::Capacity(current_capacity) => {
+            *current_capacity = *current_capacity + threshold;
+        }
+        StoredPermission::Unlimited => (),
+    }
+}
+
+ + + +
+ + + +## Function `merge` + +merge the two stored permission + + +
fun merge(lhs: &mut permissioned_signer::StoredPermission, rhs: permissioned_signer::StoredPermission)
+
+ + + +
+Implementation + + +
fun merge(lhs: &mut StoredPermission, rhs: StoredPermission) {
+    match (rhs) {
+        StoredPermission::Capacity(new_capacity) => {
+            match (lhs) {
+                StoredPermission::Capacity(current_capacity) => {
+                    *current_capacity = *current_capacity + new_capacity;
+                }
+                StoredPermission::Unlimited => (),
+            }
+        }
+        StoredPermission::Unlimited => *lhs = StoredPermission::Unlimited,
+    }
+}
+
+ + + +
+ + + +## Function `map_or` + +===================================================================================================== +Permission Management + +Authorizes permissioned with the given permission. This requires to have access to the master +signer. + + +
fun map_or<PermKey: copy, drop, store, T>(permissioned: &signer, perm: PermKey, mutate: |&mut permissioned_signer::StoredPermission|T, default: T): T
+
+ + + +
+Implementation + + +
inline fun map_or<PermKey: copy + drop + store, T>(
+    permissioned: &signer,
+    perm: PermKey,
+    mutate: |&mut StoredPermission| T,
+    default: T,
+): T {
+    let permission_signer_addr = permission_address(permissioned);
+    assert!(
+        exists<PermissionStorage>(permission_signer_addr),
+        error::permission_denied(E_NOT_ACTIVE)
+    );
+    let perms =
+        &mut borrow_global_mut<PermissionStorage>(permission_signer_addr).perms;
+    let key = copyable_any::pack(perm);
+    if (simple_map::contains_key(perms, &key)) {
+        mutate(simple_map::borrow_mut(perms, &key))
+    } else {
+        default
+    }
+}
+
+ + + +
+ + + +## Function `insert_or` + + + +
fun insert_or<PermKey: copy, drop, store>(permissioned: &signer, perm: PermKey, mutate: |&mut permissioned_signer::StoredPermission|, default: permissioned_signer::StoredPermission)
+
+ + + +
+Implementation + + +
inline fun insert_or<PermKey: copy + drop + store>(
+    permissioned: &signer,
+    perm: PermKey,
+    mutate: |&mut StoredPermission|,
+    default: StoredPermission,
+) {
+    let permission_signer_addr = permission_address(permissioned);
+    assert!(
+        exists<PermissionStorage>(permission_signer_addr),
+        error::permission_denied(E_NOT_ACTIVE)
+    );
+    let perms =
+        &mut borrow_global_mut<PermissionStorage>(permission_signer_addr).perms;
+    let key = copyable_any::pack(perm);
+    if (simple_map::contains_key(perms, &key)) {
+        mutate(simple_map::borrow_mut(perms, &key));
+    } else {
+        simple_map::add(perms, key, default);
+    }
+}
+
+ + + +
+ + + +## Function `authorize` + + + +
public fun authorize<PermKey: copy, drop, store>(master: &signer, permissioned: &signer, capacity: u256, perm: PermKey)
+
+ + + +
+Implementation + + +
public fun authorize<PermKey: copy + drop + store>(
+    master: &signer,
+    permissioned: &signer,
+    capacity: u256,
+    perm: PermKey
+) acquires PermissionStorage {
+    assert!(
+        is_permissioned_signer(permissioned)
+            && !is_permissioned_signer(master)
+            && signer::address_of(master) == signer::address_of(permissioned),
+        error::permission_denied(ECANNOT_AUTHORIZE)
+    );
+    insert_or(
+        permissioned,
+        perm,
+        |stored_permission| {
+            increase_capacity(stored_permission, capacity);
+        },
+        StoredPermission::Capacity(capacity),
+    )
+}
+
+ + + +
+ + + +## Function `authorize_unlimited` + +Authorizes permissioned with the given unlimited permission. +Unlimited permission can be consumed however many times. + + +
public fun authorize_unlimited<PermKey: copy, drop, store>(master: &signer, permissioned: &signer, perm: PermKey)
+
+ + + +
+Implementation + + +
public fun authorize_unlimited<PermKey: copy + drop + store>(
+    master: &signer,
+    permissioned: &signer,
+    perm: PermKey
+) acquires PermissionStorage {
+    assert!(
+        is_permissioned_signer(permissioned)
+            && !is_permissioned_signer(master)
+            && signer::address_of(master) == signer::address_of(permissioned),
+        error::permission_denied(ECANNOT_AUTHORIZE)
+    );
+    insert_or(
+        permissioned,
+        perm,
+        |stored_permission| {
+            *stored_permission = StoredPermission::Unlimited;
+        },
+        StoredPermission::Unlimited,
+    )
+}
+
+ + + +
+ + + +## Function `check_permission_exists` + + + +
public fun check_permission_exists<PermKey: copy, drop, store>(s: &signer, perm: PermKey): bool
+
+ + + +
+Implementation + + +
public fun check_permission_exists<PermKey: copy + drop + store>(
+    s: &signer, perm: PermKey
+): bool acquires PermissionStorage {
+    check_permission_capacity_above(s, 0, perm)
+}
+
+ + + +
+ + + +## Function `check_permission_capacity_above` + + + +
public fun check_permission_capacity_above<PermKey: copy, drop, store>(s: &signer, threshold: u256, perm: PermKey): bool
+
+ + + +
+Implementation + + +
public fun check_permission_capacity_above<PermKey: copy + drop + store>(
+    s: &signer, threshold: u256, perm: PermKey
+): bool acquires PermissionStorage {
+    if (!is_permissioned_signer(s)) {
+        // master signer has all permissions
+        return true
+    };
+    map_or(
+        s,
+        perm,
+        |stored_permission| {
+            is_above(stored_permission, threshold)
+        },
+        false,
+    )
+}
+
+ + + +
+ + + +## Function `check_permission_consume` + + + +
public fun check_permission_consume<PermKey: copy, drop, store>(s: &signer, threshold: u256, perm: PermKey): bool
+
+ + + +
+Implementation + + +
public fun check_permission_consume<PermKey: copy + drop + store>(
+    s: &signer, threshold: u256, perm: PermKey
+): bool acquires PermissionStorage {
+    if (!is_permissioned_signer(s)) {
+        // master signer has all permissions
+        return true
+    };
+    map_or(
+        s,
+        perm,
+        |stored_permission| {
+             consume_capacity(stored_permission, threshold)
+        },
+        false,
+    )
+}
+
+ + + +
+ + + +## Function `capacity` + + + +
public fun capacity<PermKey: copy, drop, store>(s: &signer, perm: PermKey): option::Option<u256>
+
+ + + +
+Implementation + + +
public fun capacity<PermKey: copy + drop + store>(
+    s: &signer, perm: PermKey
+): Option<u256> acquires PermissionStorage {
+    if (!is_permissioned_signer(s)) {
+        return option::some(U256_MAX)
+    };
+    map_or(
+        s,
+        perm,
+        |stored_permission: &mut StoredPermission| {
+            option::some(match (stored_permission) {
+                StoredPermission::Capacity(capacity) => *capacity,
+                StoredPermission::Unlimited => U256_MAX,
+            })
+        },
+        option::none(),
+    )
+}
+
+ + + +
+ + + +## Function `revoke_permission` + + + +
public fun revoke_permission<PermKey: copy, drop, store>(permissioned: &signer, perm: PermKey)
+
+ + + +
+Implementation + + +
public fun revoke_permission<PermKey: copy + drop + store>(
+    permissioned: &signer, perm: PermKey
+) acquires PermissionStorage {
+    if (!is_permissioned_signer(permissioned)) {
+        // Master signer has no permissions associated with it.
+        return
+    };
+    let addr = permission_address(permissioned);
+    if (!exists<PermissionStorage>(addr)) { return };
+    let perm_storage = &mut borrow_global_mut<PermissionStorage>(addr).perms;
+    let key = copyable_any::pack(perm);
+    if (simple_map::contains_key(perm_storage, &key)) {
+        simple_map::remove(
+            &mut borrow_global_mut<PermissionStorage>(addr).perms,
+            &copyable_any::pack(perm)
+        );
+    }
+}
+
+ + + +
+ + + +## Function `extract_permission` + +===================================================================================================== +Another flavor of api to extract and store permissions + + +
public(friend) fun extract_permission<PermKey: copy, drop, store>(s: &signer, weight: u256, perm: PermKey): permissioned_signer::Permission<PermKey>
+
+ + + +
+Implementation + + +
public(package) fun extract_permission<PermKey: copy + drop + store>(
+    s: &signer, weight: u256, perm: PermKey
+): Permission<PermKey> acquires PermissionStorage {
+    assert!(
+        check_permission_consume(s, weight, perm),
+        error::permission_denied(ECANNOT_EXTRACT_PERMISSION)
+    );
+    Permission::V1 {
+        owner_address: signer::address_of(s),
+        key: perm,
+        perm: StoredPermission::Capacity(weight),
+    }
+}
+
+ + + +
+ + + +## Function `extract_all_permission` + + + +
public(friend) fun extract_all_permission<PermKey: copy, drop, store>(s: &signer, perm_key: PermKey): permissioned_signer::Permission<PermKey>
+
+ + + +
+Implementation + + +
public(package) fun extract_all_permission<PermKey: copy + drop + store>(
+    s: &signer, perm_key: PermKey
+): Permission<PermKey> acquires PermissionStorage {
+    assert!(
+        is_permissioned_signer(s),
+        error::permission_denied(ECANNOT_EXTRACT_PERMISSION)
+    );
+    let addr = permission_address(s);
+    assert!(
+        exists<PermissionStorage>(addr),
+        error::permission_denied(ECANNOT_EXTRACT_PERMISSION)
+    );
+    let key = copyable_any::pack(perm_key);
+    let storage = &mut borrow_global_mut<PermissionStorage>(addr).perms;
+    let (_, value) = simple_map::remove(storage, &key);
+
+    Permission::V1 {
+        owner_address: signer::address_of(s),
+        key: perm_key,
+        perm: value,
+    }
+}
+
+ + + +
+ + + +## Function `address_of` + + + +
public(friend) fun address_of<PermKey>(perm: &permissioned_signer::Permission<PermKey>): address
+
+ + + +
+Implementation + + +
public(package) fun address_of<PermKey>(perm: &Permission<PermKey>): address {
+    perm.owner_address
+}
+
+ + + +
+ + + +## Function `consume_permission` + + + +
public(friend) fun consume_permission<PermKey: copy, drop, store>(perm: &mut permissioned_signer::Permission<PermKey>, weight: u256, perm_key: PermKey): bool
+
+ + + +
+Implementation + + +
public(package) fun consume_permission<PermKey: copy + drop + store>(
+    perm: &mut Permission<PermKey>, weight: u256, perm_key: PermKey
+): bool {
+    if (perm.key != perm_key) {
+        return false
+    };
+    consume_capacity(&mut perm.perm, weight)
+}
+
+ + + +
+ + + +## Function `store_permission` + + + +
public(friend) fun store_permission<PermKey: copy, drop, store>(s: &signer, perm: permissioned_signer::Permission<PermKey>)
+
+ + + +
+Implementation + + +
public(package) fun store_permission<PermKey: copy + drop + store>(
+    s: &signer, perm: Permission<PermKey>
+) acquires PermissionStorage {
+    assert!(
+        is_permissioned_signer(s),
+        error::permission_denied(ENOT_PERMISSIONED_SIGNER)
+    );
+    let Permission::V1 { key, perm, owner_address } = perm;
+
+    assert!(
+        signer::address_of(s) == owner_address,
+        error::permission_denied(E_PERMISSION_MISMATCH)
+    );
+
+    insert_or(
+        s,
+        key,
+        |stored_permission| {
+            merge(stored_permission, perm);
+        },
+        perm,
+    )
+}
+
+ + + +
+ + + +## Function `is_permissioned_signer` + + +Check whether this is a permissioned signer. + + +
public fun is_permissioned_signer(s: &signer): bool
+
+ + + +
+Implementation + + +
public native fun is_permissioned_signer(s: &signer): bool;
+
+ + + +
+ + + +## Function `permission_address` + +Return the address used for storing permissions. Aborts if not a permissioned signer. + + +
fun permission_address(permissioned: &signer): address
+
+ + + +
+Implementation + + +
native fun permission_address(permissioned: &signer): address;
+
+ + + +
+ + + +## Function `signer_from_permissioned_handle_impl` + +Creates a permissioned signer from an existing universal signer. The function aborts if the +given signer is already a permissioned signer. + +The implementation of this function requires to extend the value representation for signers in the VM. +invariants: +signer::address_of(master) == signer::address_of(signer_from_permissioned_handle(create_permissioned_handle(master))), + + +
fun signer_from_permissioned_handle_impl(master_account_addr: address, permissions_storage_addr: address): signer
+
+ + + +
+Implementation + + +
native fun signer_from_permissioned_handle_impl(
+    master_account_addr: address, permissions_storage_addr: address
+): signer;
+
+ + + +
+ + + +## Specification + + + +
pragma verify = false;
+axiom forall a: GrantedPermissionHandles:
+    (
+        forall i in 0..len(a.active_handles):
+            forall j in 0..len(a.active_handles):
+                i != j ==>
+                    a.active_handles[i] != a.active_handles[j]
+    );
+
+ + + + + + + +
fun spec_is_permissioned_signer(s: signer): bool;
+
+ + + + + +### Function `create_permissioned_handle` + + +
public fun create_permissioned_handle(master: &signer): permissioned_signer::PermissionedHandle
+
+ + + + +
pragma opaque;
+aborts_if [abstract] spec_is_permissioned_signer(master);
+let permissions_storage_addr = transaction_context::spec_generate_unique_address();
+modifies global<PermissionStorage>(permissions_storage_addr);
+let master_account_addr = signer::address_of(master);
+ensures result.master_account_addr == master_account_addr;
+ensures result.permissions_storage_addr == permissions_storage_addr;
+
+ + + + + +### Function `create_storable_permissioned_handle` + + +
public(friend) fun create_storable_permissioned_handle(master: &signer, expiration_time: u64): permissioned_signer::StorablePermissionedHandle
+
+ + + + +
pragma opaque;
+aborts_if [abstract] spec_is_permissioned_signer(master);
+let permissions_storage_addr = transaction_context::spec_generate_unique_address();
+modifies global<PermissionStorage>(permissions_storage_addr);
+let master_account_addr = signer::address_of(master);
+modifies global<GrantedPermissionHandles>(master_account_addr);
+ensures result.master_account_addr == master_account_addr;
+ensures result.permissions_storage_addr == permissions_storage_addr;
+ensures result.expiration_time == expiration_time;
+ensures vector::spec_contains(
+    global<GrantedPermissionHandles>(master_account_addr).active_handles,
+    permissions_storage_addr
+);
+ensures exists<GrantedPermissionHandles>(master_account_addr);
+
+ + + + + +### Function `destroy_permissioned_handle` + + +
public fun destroy_permissioned_handle(p: permissioned_signer::PermissionedHandle)
+
+ + + + +
ensures !exists<PermissionStorage>(p.permissions_storage_addr);
+
+ + + + + +### Function `destroy_storable_permissioned_handle` + + +
public(friend) fun destroy_storable_permissioned_handle(p: permissioned_signer::StorablePermissionedHandle)
+
+ + + + +
ensures !exists<PermissionStorage>(p.permissions_storage_addr);
+let post granted_permissions = global<GrantedPermissionHandles>(
+    p.master_account_addr
+);
+
+ + + + + +### Function `revoke_permission_storage_address` + + +
public entry fun revoke_permission_storage_address(s: &signer, permissions_storage_addr: address)
+
+ + + + + + +### Function `authorize` + + +
public fun authorize<PermKey: copy, drop, store>(master: &signer, permissioned: &signer, capacity: u256, perm: PermKey)
+
+ + + + +
pragma aborts_if_is_partial;
+aborts_if !spec_is_permissioned_signer(permissioned);
+aborts_if spec_is_permissioned_signer(master);
+aborts_if signer::address_of(permissioned) != signer::address_of(master);
+ensures exists<PermissionStorage>(
+    spec_permission_address(permissioned)
+);
+
+ + + + + +### Function `check_permission_exists` + + +
public fun check_permission_exists<PermKey: copy, drop, store>(s: &signer, perm: PermKey): bool
+
+ + + + +
pragma verify = false;
+
+ + + + + + + +
fun spec_check_permission_exists<PermKey: copy + drop + store>(s: signer, perm: PermKey): bool {
+   use aptos_std::type_info;
+   use std::bcs;
+   let addr = spec_permission_address(s);
+   let key = Any {
+       type_name: type_info::type_name<PermKey>(),
+       data: bcs::serialize(perm)
+   };
+   if (!spec_is_permissioned_signer(s)) { true }
+   else if (!exists<PermissionStorage>(addr)) { false }
+   else {
+       simple_map::spec_contains_key(global<PermissionStorage>(addr).perms, key)
+   }
+}
+
+ + + + + +### Function `check_permission_capacity_above` + + +
public fun check_permission_capacity_above<PermKey: copy, drop, store>(s: &signer, threshold: u256, perm: PermKey): bool
+
+ + + + +
let permissioned_signer_addr = spec_permission_address(s);
+ensures !spec_is_permissioned_signer(s) ==> result == true;
+ensures (
+    spec_is_permissioned_signer(s)
+        && !exists<PermissionStorage>(permissioned_signer_addr)
+) ==> result == false;
+let key = Any {
+    type_name: type_info::type_name<SimpleMap<Any, u256>>(),
+    data: bcs::serialize(perm)
+};
+
+ + + + + +### Function `check_permission_consume` + + +
public fun check_permission_consume<PermKey: copy, drop, store>(s: &signer, threshold: u256, perm: PermKey): bool
+
+ + + + +
let permissioned_signer_addr = spec_permission_address(s);
+ensures !spec_is_permissioned_signer(s) ==> result == true;
+ensures (
+    spec_is_permissioned_signer(s)
+        && !exists<PermissionStorage>(permissioned_signer_addr)
+) ==> result == false;
+
+ + + + + +### Function `capacity` + + +
public fun capacity<PermKey: copy, drop, store>(s: &signer, perm: PermKey): option::Option<u256>
+
+ + + + + + +### Function `consume_permission` + + +
public(friend) fun consume_permission<PermKey: copy, drop, store>(perm: &mut permissioned_signer::Permission<PermKey>, weight: u256, perm_key: PermKey): bool
+
+ + + + + + +### Function `is_permissioned_signer` + + +
public fun is_permissioned_signer(s: &signer): bool
+
+ + + + +
pragma opaque;
+aborts_if [abstract] false;
+ensures [abstract] result == spec_is_permissioned_signer(s);
+
+ + + + + + + +
fun spec_permission_address(s: signer): address;
+
+ + + + + +### Function `permission_address` + + +
fun permission_address(permissioned: &signer): address
+
+ + + + +
pragma opaque;
+aborts_if [abstract]!spec_is_permissioned_signer(permissioned);
+ensures [abstract] result == spec_permission_address(permissioned);
+
+ + + + + + + +
fun spec_signer_from_permissioned_handle_impl(
+   master_account_addr: address, permissions_storage_addr: address
+): signer;
+
+ + + + + +### Function `signer_from_permissioned_handle_impl` + + +
fun signer_from_permissioned_handle_impl(master_account_addr: address, permissions_storage_addr: address): signer
+
+ + + + +
pragma opaque;
+ensures [abstract] result
+    == spec_signer_from_permissioned_handle_impl(
+        master_account_addr, permissions_storage_addr
+    );
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/tests/function_info_tests.move b/aptos-move/framework/aptos-framework/tests/function_info_tests.move index 93a7776f5974b..1850930e88487 100644 --- a/aptos-move/framework/aptos-framework/tests/function_info_tests.move +++ b/aptos-move/framework/aptos-framework/tests/function_info_tests.move @@ -45,7 +45,7 @@ module aptos_framework::function_info_tests { } #[test] - #[expected_failure(abort_code = 0x2, location = aptos_framework::function_info)] + #[expected_failure(abort_code = 0x1, location = Self)] fun test_func_type_eq_reject_same_module() { let m2 = string::utf8(b"function_info_tests"); let lhs = function_info::new_function_info_from_address(@aptos_framework, m2, string::utf8(b"lhs")); diff --git a/aptos-move/framework/aptos-framework/tests/permissioned_signer_tests.move b/aptos-move/framework/aptos-framework/tests/permissioned_signer_tests.move new file mode 100644 index 0000000000000..ec8393fd07ae0 --- /dev/null +++ b/aptos-move/framework/aptos-framework/tests/permissioned_signer_tests.move @@ -0,0 +1,381 @@ +#[test_only] +module aptos_framework::permissioned_signer_tests { + use std::bcs; + use std::features; + use aptos_framework::account::create_signer_for_test; + use aptos_framework::permissioned_signer; + use aptos_framework::timestamp; + use std::option; + use std::signer; + + struct OnePermission has copy, drop, store {} + + struct AddressPermission has copy, drop, store { + addr: address + } + + #[test(creator = @0xcafe)] + fun test_permission_e2e(creator: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = permissioned_signer::create_permissioned_handle(creator); + let perm_signer = permissioned_signer::signer_from_permissioned_handle(&perm_handle); + + assert!(permissioned_signer::is_permissioned_signer(&perm_signer), 1); + assert!(!permissioned_signer::is_permissioned_signer(creator), 1); + assert!(signer::address_of(&perm_signer) == signer::address_of(creator), 1); + + permissioned_signer::authorize_increase(creator, &perm_signer, 100, OnePermission {}); + assert!( + permissioned_signer::capacity(&perm_signer, OnePermission {}) + == option::some(100), + 1 + ); + + assert!( + permissioned_signer::check_permission_consume( + &perm_signer, 10, OnePermission {} + ), + 1 + ); + assert!( + permissioned_signer::capacity(&perm_signer, OnePermission {}) + == option::some(90), + 1 + ); + + permissioned_signer::authorize_increase( + creator, + &perm_signer, + 5, + AddressPermission { addr: @0x1 } + ); + + assert!( + permissioned_signer::capacity(&perm_signer, AddressPermission { addr: @0x1 }) + == option::some(5), + 1 + ); + assert!( + permissioned_signer::capacity(&perm_signer, AddressPermission { addr: @0x2 }) + == option::none(), + 1 + ); + + // Not enough capacity, check permission should return false + assert!( + !permissioned_signer::check_permission_consume( + &perm_signer, 10, AddressPermission { addr: @0x1 } + ), + 1 + ); + + assert!( + permissioned_signer::check_permission_consume( + &perm_signer, 5, AddressPermission { addr: @0x1 } + ), + 1 + ); + + // Remaining capacity is 0, should be viewed as non-exist. + assert!( + !permissioned_signer::check_permission_exists( + &perm_signer, AddressPermission { addr: @0x1 } + ), + 1 + ); + + permissioned_signer::revoke_permission(&perm_signer, OnePermission {}); + assert!( + permissioned_signer::capacity(&perm_signer, OnePermission {}) + == option::none(), + 1 + ); + + permissioned_signer::destroy_permissioned_handle(perm_handle); + } + + #[test(creator = @0xcafe)] + fun test_storable_permission_e2e(creator: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = + permissioned_signer::create_storable_permissioned_handle(creator, 60); + let perm_signer = + permissioned_signer::signer_from_storable_permissioned_handle(&perm_handle); + + assert!(permissioned_signer::is_permissioned_signer(&perm_signer), 1); + assert!(!permissioned_signer::is_permissioned_signer(creator), 1); + assert!(signer::address_of(&perm_signer) == signer::address_of(creator), 1); + + permissioned_signer::authorize_increase(creator, &perm_signer, 100, OnePermission {}); + assert!( + permissioned_signer::capacity(&perm_signer, OnePermission {}) + == option::some(100), + 1 + ); + + assert!( + permissioned_signer::check_permission_consume( + &perm_signer, 10, OnePermission {} + ), + 1 + ); + assert!( + permissioned_signer::capacity(&perm_signer, OnePermission {}) + == option::some(90), + 1 + ); + + permissioned_signer::authorize_increase( + creator, + &perm_signer, + 5, + AddressPermission { addr: @0x1 } + ); + + assert!( + permissioned_signer::capacity(&perm_signer, AddressPermission { addr: @0x1 }) + == option::some(5), + 1 + ); + assert!( + permissioned_signer::capacity(&perm_signer, AddressPermission { addr: @0x2 }) + == option::none(), + 1 + ); + + // Not enough capacity, check permission should return false + assert!( + !permissioned_signer::check_permission_consume( + &perm_signer, 10, AddressPermission { addr: @0x1 } + ), + 1 + ); + + permissioned_signer::revoke_permission(&perm_signer, OnePermission {}); + assert!( + permissioned_signer::capacity(&perm_signer, OnePermission {}) + == option::none(), + 1 + ); + + permissioned_signer::destroy_storable_permissioned_handle(perm_handle); + } + + #[test(creator = @0xcafe)] + #[expected_failure( + abort_code = 0x50005, location = aptos_framework::permissioned_signer + )] + fun test_permission_expiration(creator: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = + permissioned_signer::create_storable_permissioned_handle(creator, 60); + let _perm_signer = + permissioned_signer::signer_from_storable_permissioned_handle(&perm_handle); + + timestamp::fast_forward_seconds(60); + let _perm_signer = + permissioned_signer::signer_from_storable_permissioned_handle(&perm_handle); + + permissioned_signer::destroy_storable_permissioned_handle(perm_handle); + } + + // invalid authorization + // 1. master signer is a permissioned signer + // 2. permissioned signer is a master signer + // 3. permissioned and main signer address mismatch + #[test(creator = @0xcafe)] + #[expected_failure( + abort_code = 0x50002, location = aptos_framework::permissioned_signer + )] + fun test_auth_1(creator: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = permissioned_signer::create_permissioned_handle(creator); + let perm_signer = permissioned_signer::signer_from_permissioned_handle(&perm_handle); + + permissioned_signer::authorize_increase( + &perm_signer, + &perm_signer, + 100, + OnePermission {} + ); + permissioned_signer::destroy_permissioned_handle(perm_handle); + } + + #[test(creator = @0xcafe)] + #[expected_failure( + abort_code = 0x50002, location = aptos_framework::permissioned_signer + )] + fun test_auth_2(creator: &signer) { + permissioned_signer::authorize_increase(creator, creator, 100, OnePermission {}); + } + + #[test(creator = @0xcafe, creator2 = @0xbeef)] + #[expected_failure( + abort_code = 0x50002, location = aptos_framework::permissioned_signer + )] + fun test_auth_3(creator: &signer, creator2: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = permissioned_signer::create_permissioned_handle(creator); + let perm_signer = permissioned_signer::signer_from_permissioned_handle(&perm_handle); + + permissioned_signer::authorize_increase(creator2, &perm_signer, 100, OnePermission {}); + permissioned_signer::destroy_permissioned_handle(perm_handle); + } + + // Accessing capacity on a master signer + #[test(creator = @0xcafe)] + fun test_invalid_capacity(creator: &signer) { + assert!( + permissioned_signer::capacity(creator, OnePermission {}) + == option::some( + 115792089237316195423570985008687907853269984665640564039457584007913129639935 + ), + 1 + ); + } + + // Making sure master signer always have all permissions even when feature is disabled. + #[test(creator = @aptos_framework)] + fun test_master_signer_permission(creator: &signer) { + assert!( + permissioned_signer::check_permission_exists(creator, OnePermission {}), + 1 + ); + + // Disable the permissioned signer feature. + features::change_feature_flags_for_testing( + creator, + vector[], + vector[features::get_permissioned_signer_feature()] + ); + + // Master signer should still have permission after feature is disabled. + assert!( + permissioned_signer::check_permission_exists(creator, OnePermission {}), + 1 + ); + } + + // creating permission using a permissioned signer + #[test(creator = @0xcafe)] + #[expected_failure( + abort_code = 0x50001, location = aptos_framework::permissioned_signer + )] + fun test_invalid_creation(creator: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = permissioned_signer::create_permissioned_handle(creator); + let perm_signer = permissioned_signer::signer_from_permissioned_handle(&perm_handle); + + let perm_handle_2 = permissioned_signer::create_permissioned_handle(&perm_signer); + permissioned_signer::destroy_permissioned_handle(perm_handle); + permissioned_signer::destroy_permissioned_handle(perm_handle_2); + } + + #[test(creator = @0xcafe)] + fun test_permission_revocation_success(creator: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = + permissioned_signer::create_storable_permissioned_handle(creator, 60); + let _perm_signer = + permissioned_signer::signer_from_storable_permissioned_handle(&perm_handle); + + permissioned_signer::revoke_permission_storage_address( + creator, permissioned_signer::permissions_storage_address(&perm_handle) + ); + + permissioned_signer::destroy_storable_permissioned_handle(perm_handle); + } + + #[test(creator = @0xcafe)] + fun test_permission_revocation_success_with_permissioned_signer(creator: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = + permissioned_signer::create_storable_permissioned_handle(creator, 60); + let perm_signer = + permissioned_signer::signer_from_storable_permissioned_handle(&perm_handle); + + permissioned_signer::grant_revoke_permission(creator, &perm_signer); + + permissioned_signer::revoke_permission_storage_address( + &perm_signer, permissioned_signer::permissions_storage_address(&perm_handle) + ); + + permissioned_signer::destroy_storable_permissioned_handle(perm_handle); + } + + #[test(creator = @0xcafe)] + #[expected_failure( + abort_code = 0x50007, location = aptos_framework::permissioned_signer + )] + fun test_permission_revocation_and_access(creator: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = + permissioned_signer::create_storable_permissioned_handle(creator, 60); + let _perm_signer = + permissioned_signer::signer_from_storable_permissioned_handle(&perm_handle); + + permissioned_signer::revoke_permission_storage_address( + creator, permissioned_signer::permissions_storage_address(&perm_handle) + ); + let _perm_signer = + permissioned_signer::signer_from_storable_permissioned_handle(&perm_handle); + + permissioned_signer::destroy_storable_permissioned_handle(perm_handle); + } + + #[test(creator1 = @0xcafe, creator2 = @0xbafe)] + #[expected_failure( + abort_code = 0x50008, location = aptos_framework::permissioned_signer + )] + fun test_permission_revoke_other(creator1: &signer, creator2: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle_1 = + permissioned_signer::create_storable_permissioned_handle(creator1, 60); + + let perm_handle_2 = + permissioned_signer::create_storable_permissioned_handle(creator2, 60); + + permissioned_signer::revoke_permission_storage_address( + creator1, permissioned_signer::permissions_storage_address(&perm_handle_2) + ); + + permissioned_signer::destroy_storable_permissioned_handle(perm_handle_1); + permissioned_signer::destroy_storable_permissioned_handle(perm_handle_2); + } + + #[test(creator = @0xcafe)] + #[expected_failure(abort_code = 453, location = std::bcs)] + fun test_permissioned_signer_serialization(creator: &signer) { + let aptos_framework = create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let perm_handle = + permissioned_signer::create_storable_permissioned_handle(creator, 60); + let perm_signer = + permissioned_signer::signer_from_storable_permissioned_handle(&perm_handle); + + bcs::to_bytes(&perm_signer); + + permissioned_signer::destroy_storable_permissioned_handle(perm_handle); + } +} diff --git a/aptos-move/framework/aptos-stdlib/doc/bcs_stream.md b/aptos-move/framework/aptos-stdlib/doc/bcs_stream.md new file mode 100644 index 0000000000000..4800eafcd5d47 --- /dev/null +++ b/aptos-move/framework/aptos-stdlib/doc/bcs_stream.md @@ -0,0 +1,663 @@ + + + +# Module `0x1::bcs_stream` + +This module enables the deserialization of BCS-formatted byte arrays into Move primitive types. +Deserialization Strategies: +- Per-Byte Deserialization: Employed for most types to ensure lower gas consumption, this method processes each byte +individually to match the length and type requirements of target Move types. +- Exception: For the deserialize_address function, the function-based approach from aptos_std::from_bcs is used +due to type constraints, even though it is generally more gas-intensive. +- This can be optimized further by introducing native vector slices. +Application: +- This deserializer is particularly valuable for processing BCS serialized data within Move modules, +especially useful for systems requiring cross-chain message interpretation or off-chain data verification. + + +- [Struct `BCSStream`](#0x1_bcs_stream_BCSStream) +- [Constants](#@Constants_0) +- [Function `new`](#0x1_bcs_stream_new) +- [Function `deserialize_uleb128`](#0x1_bcs_stream_deserialize_uleb128) +- [Function `deserialize_bool`](#0x1_bcs_stream_deserialize_bool) +- [Function `deserialize_address`](#0x1_bcs_stream_deserialize_address) +- [Function `deserialize_u8`](#0x1_bcs_stream_deserialize_u8) +- [Function `deserialize_u16`](#0x1_bcs_stream_deserialize_u16) +- [Function `deserialize_u32`](#0x1_bcs_stream_deserialize_u32) +- [Function `deserialize_u64`](#0x1_bcs_stream_deserialize_u64) +- [Function `deserialize_u128`](#0x1_bcs_stream_deserialize_u128) +- [Function `deserialize_u256`](#0x1_bcs_stream_deserialize_u256) +- [Function `deserialize_u256_entry`](#0x1_bcs_stream_deserialize_u256_entry) +- [Function `deserialize_vector`](#0x1_bcs_stream_deserialize_vector) +- [Function `deserialize_string`](#0x1_bcs_stream_deserialize_string) +- [Function `deserialize_option`](#0x1_bcs_stream_deserialize_option) +- [Specification](#@Specification_1) + + +
use 0x1::error;
+use 0x1::from_bcs;
+use 0x1::string;
+use 0x1::vector;
+
+ + + + + +## Struct `BCSStream` + + + +
struct BCSStream has drop
+
+ + + +
+Fields + + +
+
+data: vector<u8> +
+
+ Byte buffer containing the serialized data. +
+
+cur: u64 +
+
+ Cursor indicating the current position in the byte buffer. +
+
+ + +
+ + + +## Constants + + + + +The data does not fit the expected format. + + +
const EMALFORMED_DATA: u64 = 1;
+
+ + + + + +There are not enough bytes to deserialize for the given type. + + +
const EOUT_OF_BYTES: u64 = 2;
+
+ + + + + +## Function `new` + +Constructs a new BCSStream instance from the provided byte array. + + +
public fun new(data: vector<u8>): bcs_stream::BCSStream
+
+ + + +
+Implementation + + +
public fun new(data: vector<u8>): BCSStream {
+    BCSStream {
+        data,
+        cur: 0,
+    }
+}
+
+ + + +
+ + + +## Function `deserialize_uleb128` + +Deserializes a ULEB128-encoded integer from the stream. +In the BCS format, lengths of vectors are represented using ULEB128 encoding. + + +
public fun deserialize_uleb128(stream: &mut bcs_stream::BCSStream): u64
+
+ + + +
+Implementation + + +
public fun deserialize_uleb128(stream: &mut BCSStream): u64 {
+    let res = 0;
+    let shift = 0;
+
+    while (stream.cur < vector::length(&stream.data)) {
+        let byte = *vector::borrow(&stream.data, stream.cur);
+        stream.cur = stream.cur + 1;
+
+        let val = ((byte & 0x7f) as u64);
+        if (((val << shift) >> shift) != val) {
+            abort error::invalid_argument(EMALFORMED_DATA)
+        };
+        res = res | (val << shift);
+
+        if ((byte & 0x80) == 0) {
+            if (shift > 0 && val == 0) {
+                abort error::invalid_argument(EMALFORMED_DATA)
+            };
+            return res
+        };
+
+        shift = shift + 7;
+        if (shift > 64) {
+            abort error::invalid_argument(EMALFORMED_DATA)
+        };
+    };
+
+    abort error::out_of_range(EOUT_OF_BYTES)
+}
+
+ + + +
+ + + +## Function `deserialize_bool` + +Deserializes a bool value from the stream. + + +
public fun deserialize_bool(stream: &mut bcs_stream::BCSStream): bool
+
+ + + +
+Implementation + + +
public fun deserialize_bool(stream: &mut BCSStream): bool {
+    assert!(stream.cur < vector::length(&stream.data), error::out_of_range(EOUT_OF_BYTES));
+    let byte = *vector::borrow(&stream.data, stream.cur);
+    stream.cur = stream.cur + 1;
+    if (byte == 0) {
+        false
+    } else if (byte == 1) {
+        true
+    } else {
+        abort error::invalid_argument(EMALFORMED_DATA)
+    }
+}
+
+ + + +
+ + + +## Function `deserialize_address` + +Deserializes an address value from the stream. +32-byte address values are serialized using little-endian byte order. +This function utilizes the to_address function from the aptos_std::from_bcs module, +because the Move type system does not permit per-byte referencing of addresses. + + +
public fun deserialize_address(stream: &mut bcs_stream::BCSStream): address
+
+ + + +
+Implementation + + +
public fun deserialize_address(stream: &mut BCSStream): address {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 32 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res = from_bcs::to_address(vector::slice(data, cur, cur + 32));
+
+    stream.cur = cur + 32;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u8` + +Deserializes a u8 value from the stream. +1-byte u8 values are serialized using little-endian byte order. + + +
public fun deserialize_u8(stream: &mut bcs_stream::BCSStream): u8
+
+ + + +
+Implementation + + +
public fun deserialize_u8(stream: &mut BCSStream): u8 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur < vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+
+    let res = *vector::borrow(data, cur);
+
+    stream.cur = cur + 1;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u16` + +Deserializes a u16 value from the stream. +2-byte u16 values are serialized using little-endian byte order. + + +
public fun deserialize_u16(stream: &mut bcs_stream::BCSStream): u16
+
+ + + +
+Implementation + + +
public fun deserialize_u16(stream: &mut BCSStream): u16 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 2 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u16) |
+            ((*vector::borrow(data, cur + 1) as u16) << 8)
+    ;
+
+    stream.cur = stream.cur + 2;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u32` + +Deserializes a u32 value from the stream. +4-byte u32 values are serialized using little-endian byte order. + + +
public fun deserialize_u32(stream: &mut bcs_stream::BCSStream): u32
+
+ + + +
+Implementation + + +
public fun deserialize_u32(stream: &mut BCSStream): u32 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 4 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u32) |
+            ((*vector::borrow(data, cur + 1) as u32) << 8) |
+            ((*vector::borrow(data, cur + 2) as u32) << 16) |
+            ((*vector::borrow(data, cur + 3) as u32) << 24)
+    ;
+
+    stream.cur = stream.cur + 4;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u64` + +Deserializes a u64 value from the stream. +8-byte u64 values are serialized using little-endian byte order. + + +
public fun deserialize_u64(stream: &mut bcs_stream::BCSStream): u64
+
+ + + +
+Implementation + + +
public fun deserialize_u64(stream: &mut BCSStream): u64 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 8 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u64) |
+            ((*vector::borrow(data, cur + 1) as u64) << 8) |
+            ((*vector::borrow(data, cur + 2) as u64) << 16) |
+            ((*vector::borrow(data, cur + 3) as u64) << 24) |
+            ((*vector::borrow(data, cur + 4) as u64) << 32) |
+            ((*vector::borrow(data, cur + 5) as u64) << 40) |
+            ((*vector::borrow(data, cur + 6) as u64) << 48) |
+            ((*vector::borrow(data, cur + 7) as u64) << 56)
+    ;
+
+    stream.cur = stream.cur + 8;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u128` + +Deserializes a u128 value from the stream. +16-byte u128 values are serialized using little-endian byte order. + + +
public fun deserialize_u128(stream: &mut bcs_stream::BCSStream): u128
+
+ + + +
+Implementation + + +
public fun deserialize_u128(stream: &mut BCSStream): u128 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 16 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u128) |
+            ((*vector::borrow(data, cur + 1) as u128) << 8) |
+            ((*vector::borrow(data, cur + 2) as u128) << 16) |
+            ((*vector::borrow(data, cur + 3) as u128) << 24) |
+            ((*vector::borrow(data, cur + 4) as u128) << 32) |
+            ((*vector::borrow(data, cur + 5) as u128) << 40) |
+            ((*vector::borrow(data, cur + 6) as u128) << 48) |
+            ((*vector::borrow(data, cur + 7) as u128) << 56) |
+            ((*vector::borrow(data, cur + 8) as u128) << 64) |
+            ((*vector::borrow(data, cur + 9) as u128) << 72) |
+            ((*vector::borrow(data, cur + 10) as u128) << 80) |
+            ((*vector::borrow(data, cur + 11) as u128) << 88) |
+            ((*vector::borrow(data, cur + 12) as u128) << 96) |
+            ((*vector::borrow(data, cur + 13) as u128) << 104) |
+            ((*vector::borrow(data, cur + 14) as u128) << 112) |
+            ((*vector::borrow(data, cur + 15) as u128) << 120)
+    ;
+
+    stream.cur = stream.cur + 16;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u256` + +Deserializes a u256 value from the stream. +32-byte u256 values are serialized using little-endian byte order. + + +
public fun deserialize_u256(stream: &mut bcs_stream::BCSStream): u256
+
+ + + +
+Implementation + + +
public fun deserialize_u256(stream: &mut BCSStream): u256 {
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + 32 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+    let res =
+        (*vector::borrow(data, cur) as u256) |
+            ((*vector::borrow(data, cur + 1) as u256) << 8) |
+            ((*vector::borrow(data, cur + 2) as u256) << 16) |
+            ((*vector::borrow(data, cur + 3) as u256) << 24) |
+            ((*vector::borrow(data, cur + 4) as u256) << 32) |
+            ((*vector::borrow(data, cur + 5) as u256) << 40) |
+            ((*vector::borrow(data, cur + 6) as u256) << 48) |
+            ((*vector::borrow(data, cur + 7) as u256) << 56) |
+            ((*vector::borrow(data, cur + 8) as u256) << 64) |
+            ((*vector::borrow(data, cur + 9) as u256) << 72) |
+            ((*vector::borrow(data, cur + 10) as u256) << 80) |
+            ((*vector::borrow(data, cur + 11) as u256) << 88) |
+            ((*vector::borrow(data, cur + 12) as u256) << 96) |
+            ((*vector::borrow(data, cur + 13) as u256) << 104) |
+            ((*vector::borrow(data, cur + 14) as u256) << 112) |
+            ((*vector::borrow(data, cur + 15) as u256) << 120) |
+            ((*vector::borrow(data, cur + 16) as u256) << 128) |
+            ((*vector::borrow(data, cur + 17) as u256) << 136) |
+            ((*vector::borrow(data, cur + 18) as u256) << 144) |
+            ((*vector::borrow(data, cur + 19) as u256) << 152) |
+            ((*vector::borrow(data, cur + 20) as u256) << 160) |
+            ((*vector::borrow(data, cur + 21) as u256) << 168) |
+            ((*vector::borrow(data, cur + 22) as u256) << 176) |
+            ((*vector::borrow(data, cur + 23) as u256) << 184) |
+            ((*vector::borrow(data, cur + 24) as u256) << 192) |
+            ((*vector::borrow(data, cur + 25) as u256) << 200) |
+            ((*vector::borrow(data, cur + 26) as u256) << 208) |
+            ((*vector::borrow(data, cur + 27) as u256) << 216) |
+            ((*vector::borrow(data, cur + 28) as u256) << 224) |
+            ((*vector::borrow(data, cur + 29) as u256) << 232) |
+            ((*vector::borrow(data, cur + 30) as u256) << 240) |
+            ((*vector::borrow(data, cur + 31) as u256) << 248)
+    ;
+
+    stream.cur = stream.cur + 32;
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_u256_entry` + +Deserializes a u256 value from the stream. + + +
public entry fun deserialize_u256_entry(data: vector<u8>, cursor: u64)
+
+ + + +
+Implementation + + +
public entry fun deserialize_u256_entry(data: vector<u8>, cursor: u64) {
+    let stream = BCSStream {
+        data: data,
+        cur: cursor,
+    };
+    deserialize_u256(&mut stream);
+}
+
+ + + +
+ + + +## Function `deserialize_vector` + +Deserializes an array of BCS deserializable elements from the stream. +First, reads the length of the vector, which is in uleb128 format. +After determining the length, it then reads the contents of the vector. +The elem_deserializer lambda expression is used sequentially to deserialize each element of the vector. + + +
public fun deserialize_vector<E>(stream: &mut bcs_stream::BCSStream, elem_deserializer: |&mut bcs_stream::BCSStream|E): vector<E>
+
+ + + +
+Implementation + + +
public inline fun deserialize_vector<E>(stream: &mut BCSStream, elem_deserializer: |&mut BCSStream| E): vector<E> {
+    let len = deserialize_uleb128(stream);
+    let v = vector::empty();
+
+    let i = 0;
+    while (i < len) {
+        vector::push_back(&mut v, elem_deserializer(stream));
+        i = i + 1;
+    };
+
+    v
+}
+
+ + + +
+ + + +## Function `deserialize_string` + +Deserializes utf-8 String from the stream. +First, reads the length of the String, which is in uleb128 format. +After determining the length, it then reads the contents of the String. + + +
public fun deserialize_string(stream: &mut bcs_stream::BCSStream): string::String
+
+ + + +
+Implementation + + +
public fun deserialize_string(stream: &mut BCSStream): String {
+    let len = deserialize_uleb128(stream);
+    let data = &stream.data;
+    let cur = stream.cur;
+
+    assert!(cur + len <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+
+    let res = string::utf8(vector::slice(data, cur, cur + len));
+    stream.cur = cur + len;
+
+    res
+}
+
+ + + +
+ + + +## Function `deserialize_option` + +Deserializes Option from the stream. +First, reads a single byte representing the presence (0x01) or absence (0x00) of data. +After determining the presence of data, it then reads the actual data if present. +The elem_deserializer lambda expression is used to deserialize the element contained within the Option. + + +
public fun deserialize_option<E>(stream: &mut bcs_stream::BCSStream, elem_deserializer: |&mut bcs_stream::BCSStream|E): option::Option<E>
+
+ + + +
+Implementation + + +
public inline fun deserialize_option<E>(stream: &mut BCSStream, elem_deserializer: |&mut BCSStream| E): Option<E> {
+    let is_data = deserialize_bool(stream);
+    if (is_data) {
+        option::some(elem_deserializer(stream))
+    } else {
+        option::none()
+    }
+}
+
+ + + +
+ + + +## Specification + + + +
pragma verify = false;
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-stdlib/doc/fixed_point64.md b/aptos-move/framework/aptos-stdlib/doc/fixed_point64.md index c9d35f6de494e..d13fba14f020f 100644 --- a/aptos-move/framework/aptos-stdlib/doc/fixed_point64.md +++ b/aptos-move/framework/aptos-stdlib/doc/fixed_point64.md @@ -144,22 +144,22 @@ The multiplied value would be too large to be held in a u128 - + -The computed ratio when converting to a FixedPoint64 would be unrepresentable +Abort code on calculation result is negative. -
const ERATIO_OUT_OF_RANGE: u64 = 131077;
+
const ENEGATIVE_RESULT: u64 = 65542;
 
- + -Abort code on calculation result is negative. +The computed ratio when converting to a FixedPoint64 would be unrepresentable -
const ENEGATIVE_RESULT: u64 = 65542;
+
const ERATIO_OUT_OF_RANGE: u64 = 131077;
 
diff --git a/aptos-move/framework/aptos-stdlib/doc/from_bcs.md b/aptos-move/framework/aptos-stdlib/doc/from_bcs.md index cdcd6b3e1223e..34406eeb53b0c 100644 --- a/aptos-move/framework/aptos-stdlib/doc/from_bcs.md +++ b/aptos-move/framework/aptos-stdlib/doc/from_bcs.md @@ -306,6 +306,8 @@ Note that this function does not put any constraint on T. If code u deserialize a linear value, its their responsibility that the data they deserialize is owned. +Function would abort if T has signer in it. +
public(friend) fun from_bytes<T>(bytes: vector<u8>): T
 
diff --git a/aptos-move/framework/aptos-stdlib/doc/overview.md b/aptos-move/framework/aptos-stdlib/doc/overview.md index fa811e7bef51d..a35ae63f6359a 100644 --- a/aptos-move/framework/aptos-stdlib/doc/overview.md +++ b/aptos-move/framework/aptos-stdlib/doc/overview.md @@ -14,7 +14,7 @@ This is the reference documentation of the Aptos standard library. - [`0x1::any`](any.md#0x1_any) - [`0x1::aptos_hash`](hash.md#0x1_aptos_hash) -- [`0x1::big_ordered_map`](big_ordered_map.md#0x1_big_ordered_map) +- [`0x1::bcs_stream`](bcs_stream.md#0x1_bcs_stream) - [`0x1::big_vector`](big_vector.md#0x1_big_vector) - [`0x1::bls12381`](bls12381.md#0x1_bls12381) - [`0x1::bls12381_algebra`](bls12381_algebra.md#0x1_bls12381_algebra) @@ -32,7 +32,6 @@ This is the reference documentation of the Aptos standard library. - [`0x1::math_fixed`](math_fixed.md#0x1_math_fixed) - [`0x1::math_fixed64`](math_fixed64.md#0x1_math_fixed64) - [`0x1::multi_ed25519`](multi_ed25519.md#0x1_multi_ed25519) -- [`0x1::ordered_map`](ordered_map.md#0x1_ordered_map) - [`0x1::pool_u64`](pool_u64.md#0x1_pool_u64) - [`0x1::pool_u64_unbound`](pool_u64_unbound.md#0x1_pool_u64_unbound) - [`0x1::ristretto255`](ristretto255.md#0x1_ristretto255) diff --git a/aptos-move/framework/aptos-stdlib/doc/simple_map.md b/aptos-move/framework/aptos-stdlib/doc/simple_map.md index a79e7e4cec288..62eabb8dffa60 100644 --- a/aptos-move/framework/aptos-stdlib/doc/simple_map.md +++ b/aptos-move/framework/aptos-stdlib/doc/simple_map.md @@ -11,7 +11,7 @@ This module provides a solution for unsorted maps, that is it has the properties 5) Adds and removals take O(N) time DEPRECATED: since it's implementation is inneficient, it -has been deprecated in favor of ordered_map.move. +has been deprecated in favor of ordered_map.move. - [Struct `SimpleMap`](#0x1_simple_map_SimpleMap) @@ -66,7 +66,7 @@ has been deprecated in favor of o ## Struct `SimpleMap` DEPRECATED: since it's implementation is inneficient, it -has been deprecated in favor of ordered_map.move. +has been deprecated in favor of ordered_map.move.
struct SimpleMap<Key, Value> has copy, drop, store
diff --git a/aptos-move/framework/aptos-stdlib/doc/smart_table.md b/aptos-move/framework/aptos-stdlib/doc/smart_table.md
index ac5388661f2ca..83eb27ba47fff 100644
--- a/aptos-move/framework/aptos-stdlib/doc/smart_table.md
+++ b/aptos-move/framework/aptos-stdlib/doc/smart_table.md
@@ -1479,6 +1479,7 @@ map_spec_has_key = spec_contains;
 
 
 
pragma verify = false;
+pragma opaque;
 
@@ -1495,6 +1496,7 @@ map_spec_has_key = spec_contains;
pragma verify = false;
+pragma opaque;
 
diff --git a/aptos-move/framework/aptos-stdlib/doc/storage_slots_allocator.md b/aptos-move/framework/aptos-stdlib/doc/storage_slots_allocator.md index dc8def915b4d1..c421dfe6cf7d7 100644 --- a/aptos-move/framework/aptos-stdlib/doc/storage_slots_allocator.md +++ b/aptos-move/framework/aptos-stdlib/doc/storage_slots_allocator.md @@ -33,7 +33,7 @@ for example: - [Function `new_config`](#0x1_storage_slots_allocator_new_config) - [Function `add`](#0x1_storage_slots_allocator_add) - [Function `remove`](#0x1_storage_slots_allocator_remove) -- [Function `destroy_known_empty_unsafe`](#0x1_storage_slots_allocator_destroy_known_empty_unsafe) +- [Function `destroy_empty`](#0x1_storage_slots_allocator_destroy_empty) - [Function `borrow`](#0x1_storage_slots_allocator_borrow) - [Function `borrow_mut`](#0x1_storage_slots_allocator_borrow_mut) - [Function `reserve_slot`](#0x1_storage_slots_allocator_reserve_slot) @@ -53,7 +53,7 @@ for example:
use 0x1::option;
-use 0x1::table;
+use 0x1::table_with_length;
 
@@ -190,7 +190,7 @@ Data stored in an individual slot
-slots: option::Option<table::Table<u64, storage_slots_allocator::Link<T>>> +slots: option::Option<table_with_length::TableWithLength<u64, storage_slots_allocator::Link<T>>>
@@ -472,15 +472,13 @@ and there is unique owner for each slot. - + -## Function `destroy_known_empty_unsafe` +## Function `destroy_empty` -We cannot know if allocator is empty or not, so this method is not public, -and can be used only in modules that know by themselves that allocator is empty. -
public(friend) fun destroy_known_empty_unsafe<T: store>(self: storage_slots_allocator::StorageSlotsAllocator<T>)
+
public fun destroy_empty<T: store>(self: storage_slots_allocator::StorageSlotsAllocator<T>)
 
@@ -489,7 +487,7 @@ and can be used only in modules that know by themselves that allocator is empty. Implementation -
public(friend) fun destroy_known_empty_unsafe<T: store>(self: StorageSlotsAllocator<T>) {
+
public fun destroy_empty<T: store>(self: StorageSlotsAllocator<T>) {
     loop {
         let reuse_index = self.maybe_pop_from_reuse_queue();
         if (reuse_index == NULL_INDEX) {
@@ -506,7 +504,7 @@ and can be used only in modules that know by themselves that allocator is empty.
         } => {
             assert!(reuse_head_index == NULL_INDEX, EINTERNAL_INVARIANT_BROKEN);
             if (slots.is_some()) {
-                slots.destroy_some().destroy_known_empty_unsafe();
+                slots.destroy_some().destroy_empty();
             } else {
                 slots.destroy_none();
             }
@@ -851,7 +849,7 @@ Remove storage slot, but reserve it for later.
     let slot_index = self.new_slot_index;
     self.new_slot_index = self.new_slot_index + 1;
     if (self.slots.is_none()) {
-        self.slots.fill(table::new<u64, Link<T>>());
+        self.slots.fill(table_with_length::new<u64, Link<T>>());
     };
     slot_index
 }
diff --git a/aptos-move/framework/aptos-stdlib/sources/bcs_stream.move b/aptos-move/framework/aptos-stdlib/sources/bcs_stream.move
new file mode 100644
index 0000000000000..b576fb7e3373c
--- /dev/null
+++ b/aptos-move/framework/aptos-stdlib/sources/bcs_stream.move
@@ -0,0 +1,300 @@
+/// This module enables the deserialization of BCS-formatted byte arrays into Move primitive types.
+/// Deserialization Strategies:
+/// - Per-Byte Deserialization: Employed for most types to ensure lower gas consumption, this method processes each byte
+///   individually to match the length and type requirements of target Move types.
+/// - Exception: For the `deserialize_address` function, the function-based approach from `aptos_std::from_bcs` is used
+///   due to type constraints, even though it is generally more gas-intensive.
+/// - This can be optimized further by introducing native vector slices.
+/// Application:
+/// - This deserializer is particularly valuable for processing BCS serialized data within Move modules,
+///   especially useful for systems requiring cross-chain message interpretation or off-chain data verification.
+module aptos_std::bcs_stream {
+    use std::error;
+    use std::vector;
+    use std::option::{Self, Option};
+    use std::string::{Self, String};
+
+    use aptos_std::from_bcs;
+
+    /// The data does not fit the expected format.
+    const EMALFORMED_DATA: u64 = 1;
+    /// There are not enough bytes to deserialize for the given type.
+    const EOUT_OF_BYTES: u64 = 2;
+
+    struct BCSStream has drop {
+        /// Byte buffer containing the serialized data.
+        data: vector,
+        /// Cursor indicating the current position in the byte buffer.
+        cur: u64,
+    }
+
+    /// Constructs a new BCSStream instance from the provided byte array.
+    public fun new(data: vector): BCSStream {
+        BCSStream {
+            data,
+            cur: 0,
+        }
+    }
+
+    /// Deserializes a ULEB128-encoded integer from the stream.
+    /// In the BCS format, lengths of vectors are represented using ULEB128 encoding.
+    public fun deserialize_uleb128(stream: &mut BCSStream): u64 {
+        let res = 0;
+        let shift = 0;
+
+        while (stream.cur < vector::length(&stream.data)) {
+            let byte = *vector::borrow(&stream.data, stream.cur);
+            stream.cur = stream.cur + 1;
+
+            let val = ((byte & 0x7f) as u64);
+            if (((val << shift) >> shift) != val) {
+                abort error::invalid_argument(EMALFORMED_DATA)
+            };
+            res = res | (val << shift);
+
+            if ((byte & 0x80) == 0) {
+                if (shift > 0 && val == 0) {
+                    abort error::invalid_argument(EMALFORMED_DATA)
+                };
+                return res
+            };
+
+            shift = shift + 7;
+            if (shift > 64) {
+                abort error::invalid_argument(EMALFORMED_DATA)
+            };
+        };
+
+        abort error::out_of_range(EOUT_OF_BYTES)
+    }
+
+    /// Deserializes a `bool` value from the stream.
+    public fun deserialize_bool(stream: &mut BCSStream): bool {
+        assert!(stream.cur < vector::length(&stream.data), error::out_of_range(EOUT_OF_BYTES));
+        let byte = *vector::borrow(&stream.data, stream.cur);
+        stream.cur = stream.cur + 1;
+        if (byte == 0) {
+            false
+        } else if (byte == 1) {
+            true
+        } else {
+            abort error::invalid_argument(EMALFORMED_DATA)
+        }
+    }
+
+    /// Deserializes an `address` value from the stream.
+    /// 32-byte `address` values are serialized using little-endian byte order.
+    /// This function utilizes the `to_address` function from the `aptos_std::from_bcs` module,
+    /// because the Move type system does not permit per-byte referencing of addresses.
+    public fun deserialize_address(stream: &mut BCSStream): address {
+        let data = &stream.data;
+        let cur = stream.cur;
+
+        assert!(cur + 32 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+        let res = from_bcs::to_address(vector::slice(data, cur, cur + 32));
+
+        stream.cur = cur + 32;
+        res
+    }
+
+    /// Deserializes a `u8` value from the stream.
+    /// 1-byte `u8` values are serialized using little-endian byte order.
+    public fun deserialize_u8(stream: &mut BCSStream): u8 {
+        let data = &stream.data;
+        let cur = stream.cur;
+
+        assert!(cur < vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+
+        let res = *vector::borrow(data, cur);
+
+        stream.cur = cur + 1;
+        res
+    }
+
+    /// Deserializes a `u16` value from the stream.
+    /// 2-byte `u16` values are serialized using little-endian byte order.
+    public fun deserialize_u16(stream: &mut BCSStream): u16 {
+        let data = &stream.data;
+        let cur = stream.cur;
+
+        assert!(cur + 2 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+        let res =
+            (*vector::borrow(data, cur) as u16) |
+                ((*vector::borrow(data, cur + 1) as u16) << 8)
+        ;
+
+        stream.cur = stream.cur + 2;
+        res
+    }
+
+    /// Deserializes a `u32` value from the stream.
+    /// 4-byte `u32` values are serialized using little-endian byte order.
+    public fun deserialize_u32(stream: &mut BCSStream): u32 {
+        let data = &stream.data;
+        let cur = stream.cur;
+
+        assert!(cur + 4 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+        let res =
+            (*vector::borrow(data, cur) as u32) |
+                ((*vector::borrow(data, cur + 1) as u32) << 8) |
+                ((*vector::borrow(data, cur + 2) as u32) << 16) |
+                ((*vector::borrow(data, cur + 3) as u32) << 24)
+        ;
+
+        stream.cur = stream.cur + 4;
+        res
+    }
+
+    /// Deserializes a `u64` value from the stream.
+    /// 8-byte `u64` values are serialized using little-endian byte order.
+    public fun deserialize_u64(stream: &mut BCSStream): u64 {
+        let data = &stream.data;
+        let cur = stream.cur;
+
+        assert!(cur + 8 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+        let res =
+            (*vector::borrow(data, cur) as u64) |
+                ((*vector::borrow(data, cur + 1) as u64) << 8) |
+                ((*vector::borrow(data, cur + 2) as u64) << 16) |
+                ((*vector::borrow(data, cur + 3) as u64) << 24) |
+                ((*vector::borrow(data, cur + 4) as u64) << 32) |
+                ((*vector::borrow(data, cur + 5) as u64) << 40) |
+                ((*vector::borrow(data, cur + 6) as u64) << 48) |
+                ((*vector::borrow(data, cur + 7) as u64) << 56)
+        ;
+
+        stream.cur = stream.cur + 8;
+        res
+    }
+
+    /// Deserializes a `u128` value from the stream.
+    /// 16-byte `u128` values are serialized using little-endian byte order.
+    public fun deserialize_u128(stream: &mut BCSStream): u128 {
+        let data = &stream.data;
+        let cur = stream.cur;
+
+        assert!(cur + 16 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+        let res =
+            (*vector::borrow(data, cur) as u128) |
+                ((*vector::borrow(data, cur + 1) as u128) << 8) |
+                ((*vector::borrow(data, cur + 2) as u128) << 16) |
+                ((*vector::borrow(data, cur + 3) as u128) << 24) |
+                ((*vector::borrow(data, cur + 4) as u128) << 32) |
+                ((*vector::borrow(data, cur + 5) as u128) << 40) |
+                ((*vector::borrow(data, cur + 6) as u128) << 48) |
+                ((*vector::borrow(data, cur + 7) as u128) << 56) |
+                ((*vector::borrow(data, cur + 8) as u128) << 64) |
+                ((*vector::borrow(data, cur + 9) as u128) << 72) |
+                ((*vector::borrow(data, cur + 10) as u128) << 80) |
+                ((*vector::borrow(data, cur + 11) as u128) << 88) |
+                ((*vector::borrow(data, cur + 12) as u128) << 96) |
+                ((*vector::borrow(data, cur + 13) as u128) << 104) |
+                ((*vector::borrow(data, cur + 14) as u128) << 112) |
+                ((*vector::borrow(data, cur + 15) as u128) << 120)
+        ;
+
+        stream.cur = stream.cur + 16;
+        res
+    }
+
+    /// Deserializes a `u256` value from the stream.
+    /// 32-byte `u256` values are serialized using little-endian byte order.
+    public fun deserialize_u256(stream: &mut BCSStream): u256 {
+        let data = &stream.data;
+        let cur = stream.cur;
+
+        assert!(cur + 32 <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+        let res =
+            (*vector::borrow(data, cur) as u256) |
+                ((*vector::borrow(data, cur + 1) as u256) << 8) |
+                ((*vector::borrow(data, cur + 2) as u256) << 16) |
+                ((*vector::borrow(data, cur + 3) as u256) << 24) |
+                ((*vector::borrow(data, cur + 4) as u256) << 32) |
+                ((*vector::borrow(data, cur + 5) as u256) << 40) |
+                ((*vector::borrow(data, cur + 6) as u256) << 48) |
+                ((*vector::borrow(data, cur + 7) as u256) << 56) |
+                ((*vector::borrow(data, cur + 8) as u256) << 64) |
+                ((*vector::borrow(data, cur + 9) as u256) << 72) |
+                ((*vector::borrow(data, cur + 10) as u256) << 80) |
+                ((*vector::borrow(data, cur + 11) as u256) << 88) |
+                ((*vector::borrow(data, cur + 12) as u256) << 96) |
+                ((*vector::borrow(data, cur + 13) as u256) << 104) |
+                ((*vector::borrow(data, cur + 14) as u256) << 112) |
+                ((*vector::borrow(data, cur + 15) as u256) << 120) |
+                ((*vector::borrow(data, cur + 16) as u256) << 128) |
+                ((*vector::borrow(data, cur + 17) as u256) << 136) |
+                ((*vector::borrow(data, cur + 18) as u256) << 144) |
+                ((*vector::borrow(data, cur + 19) as u256) << 152) |
+                ((*vector::borrow(data, cur + 20) as u256) << 160) |
+                ((*vector::borrow(data, cur + 21) as u256) << 168) |
+                ((*vector::borrow(data, cur + 22) as u256) << 176) |
+                ((*vector::borrow(data, cur + 23) as u256) << 184) |
+                ((*vector::borrow(data, cur + 24) as u256) << 192) |
+                ((*vector::borrow(data, cur + 25) as u256) << 200) |
+                ((*vector::borrow(data, cur + 26) as u256) << 208) |
+                ((*vector::borrow(data, cur + 27) as u256) << 216) |
+                ((*vector::borrow(data, cur + 28) as u256) << 224) |
+                ((*vector::borrow(data, cur + 29) as u256) << 232) |
+                ((*vector::borrow(data, cur + 30) as u256) << 240) |
+                ((*vector::borrow(data, cur + 31) as u256) << 248)
+        ;
+
+        stream.cur = stream.cur + 32;
+        res
+    }
+
+    /// Deserializes a `u256` value from the stream.
+    public entry fun deserialize_u256_entry(data: vector, cursor: u64) {
+        let stream = BCSStream {
+            data: data,
+            cur: cursor,
+        };
+        deserialize_u256(&mut stream);
+    }
+
+    /// Deserializes an array of BCS deserializable elements from the stream.
+    /// First, reads the length of the vector, which is in uleb128 format.
+    /// After determining the length, it then reads the contents of the vector.
+    /// The `elem_deserializer` lambda expression is used sequentially to deserialize each element of the vector.
+    public inline fun deserialize_vector(stream: &mut BCSStream, elem_deserializer: |&mut BCSStream| E): vector {
+        let len = deserialize_uleb128(stream);
+        let v = vector::empty();
+
+        let i = 0;
+        while (i < len) {
+            vector::push_back(&mut v, elem_deserializer(stream));
+            i = i + 1;
+        };
+
+        v
+    }
+
+    /// Deserializes utf-8 `String` from the stream.
+    /// First, reads the length of the String, which is in uleb128 format.
+    /// After determining the length, it then reads the contents of the String.
+    public fun deserialize_string(stream: &mut BCSStream): String {
+        let len = deserialize_uleb128(stream);
+        let data = &stream.data;
+        let cur = stream.cur;
+
+        assert!(cur + len <= vector::length(data), error::out_of_range(EOUT_OF_BYTES));
+
+        let res = string::utf8(vector::slice(data, cur, cur + len));
+        stream.cur = cur + len;
+
+        res
+    }
+
+    /// Deserializes `Option` from the stream.
+    /// First, reads a single byte representing the presence (0x01) or absence (0x00) of data.
+    /// After determining the presence of data, it then reads the actual data if present.
+    /// The `elem_deserializer` lambda expression is used to deserialize the element contained within the `Option`.
+    public inline fun deserialize_option(stream: &mut BCSStream, elem_deserializer: |&mut BCSStream| E): Option {
+        let is_data = deserialize_bool(stream);
+        if (is_data) {
+            option::some(elem_deserializer(stream))
+        } else {
+            option::none()
+        }
+    }
+}
diff --git a/aptos-move/framework/aptos-stdlib/sources/bcs_stream.spec.move b/aptos-move/framework/aptos-stdlib/sources/bcs_stream.spec.move
new file mode 100644
index 0000000000000..d1088fd5c393e
--- /dev/null
+++ b/aptos-move/framework/aptos-stdlib/sources/bcs_stream.spec.move
@@ -0,0 +1,5 @@
+spec aptos_std::bcs_stream {
+    spec module {
+        pragma verify = false;
+    }
+}
diff --git a/aptos-move/framework/aptos-stdlib/sources/data_structures/smart_table.spec.move b/aptos-move/framework/aptos-stdlib/sources/data_structures/smart_table.spec.move
index d905a0a40bb3a..4344eb2329efb 100644
--- a/aptos-move/framework/aptos-stdlib/sources/data_structures/smart_table.spec.move
+++ b/aptos-move/framework/aptos-stdlib/sources/data_structures/smart_table.spec.move
@@ -24,10 +24,12 @@ spec aptos_std::smart_table {
 
     spec destroy(self: SmartTable) {
         pragma verify = false;
+        pragma opaque;
     }
 
     spec clear(self: &mut SmartTable) {
         pragma verify = false;
+        pragma opaque;
     }
 
     spec split_one_bucket(self: &mut SmartTable) {
diff --git a/aptos-move/framework/aptos-stdlib/sources/data_structures/storage_slots_allocator.move b/aptos-move/framework/aptos-stdlib/sources/data_structures/storage_slots_allocator.move
index a58c59bdb78c9..c608052582fa6 100644
--- a/aptos-move/framework/aptos-stdlib/sources/data_structures/storage_slots_allocator.move
+++ b/aptos-move/framework/aptos-stdlib/sources/data_structures/storage_slots_allocator.move
@@ -16,9 +16,7 @@
 /// * inlining some nodes
 /// * having a fee-payer for any storage creation operations
 module aptos_std::storage_slots_allocator {
-    friend aptos_std::big_ordered_map;
-
-    use aptos_std::table::{Self, Table};
+    use aptos_std::table_with_length::{Self, TableWithLength};
     use std::option::{Self, Option};
 
     const EINVALID_ARGUMENT: u64 = 1;
@@ -48,8 +46,11 @@ module aptos_std::storage_slots_allocator {
     }
 
     enum StorageSlotsAllocator has store {
+        // V1 is sequential - any two operations on the StorageSlotsAllocator will conflict.
+        // In general, StorageSlotsAllocator is invoked on less frequent operations, so
+        // that shouldn't be a big issue.
         V1 {
-            slots: Option>>, // Lazily create slots table only when needed
+            slots: Option>>, // Lazily create slots table only when needed
             new_slot_index: u64,
             should_reuse: bool,
             reuse_head_index: u64,
@@ -114,9 +115,7 @@ module aptos_std::storage_slots_allocator {
         value
     }
 
-    /// We cannot know if allocator is empty or not, so this method is not public,
-    /// and can be used only in modules that know by themselves that allocator is empty.
-    public(friend) fun destroy_known_empty_unsafe(self: StorageSlotsAllocator) {
+    public fun destroy_empty(self: StorageSlotsAllocator) {
         loop {
             let reuse_index = self.maybe_pop_from_reuse_queue();
             if (reuse_index == NULL_INDEX) {
@@ -133,7 +132,7 @@ module aptos_std::storage_slots_allocator {
             } => {
                 assert!(reuse_head_index == NULL_INDEX, EINTERNAL_INVARIANT_BROKEN);
                 if (slots.is_some()) {
-                    slots.destroy_some().destroy_known_empty_unsafe();
+                    slots.destroy_some().destroy_empty();
                 } else {
                     slots.destroy_none();
                 }
@@ -227,7 +226,7 @@ module aptos_std::storage_slots_allocator {
         let slot_index = self.new_slot_index;
         self.new_slot_index = self.new_slot_index + 1;
         if (self.slots.is_none()) {
-            self.slots.fill(table::new>());
+            self.slots.fill(table_with_length::new>());
         };
         slot_index
     }
diff --git a/aptos-move/framework/aptos-stdlib/sources/from_bcs.move b/aptos-move/framework/aptos-stdlib/sources/from_bcs.move
index 3eb6e2177d2f4..5cc33845d1b17 100644
--- a/aptos-move/framework/aptos-stdlib/sources/from_bcs.move
+++ b/aptos-move/framework/aptos-stdlib/sources/from_bcs.move
@@ -64,11 +64,12 @@ module aptos_std::from_bcs {
     /// Note that this function does not put any constraint on `T`. If code uses this function to
     /// deserialize a linear value, its their responsibility that the data they deserialize is
     /// owned.
+    ///
+    /// Function would abort if T has signer in it.
     public(friend) native fun from_bytes(bytes: vector): T;
     friend aptos_std::any;
     friend aptos_std::copyable_any;
 
-
     #[test_only]
     use std::bcs;
 
@@ -88,4 +89,10 @@ module aptos_std::from_bcs {
         let bad_vec = b"01";
         to_address(bad_vec);
     }
+
+    #[test(s1 = @0x123)]
+    #[expected_failure(abort_code = 0x10001, location = Self)]
+    fun test_signer_roundtrip(s1: signer) {
+        from_bytes(bcs::to_bytes(&s1));
+    }
 }
diff --git a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs
index c7fe5a59010e1..ccfc2c1b68590 100644
--- a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs
+++ b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs
@@ -165,6 +165,24 @@ pub enum EntryFunctionCall {
     /// authority of the new authentication key.
     AccountSetOriginatingAddress {},
 
+    /// Update dispatchable authenticator that enables account abstraction.
+    /// Note: it is a private entry function that can only be called directly from transaction.
+    AccountAbstractionAddDispatchableAuthenticationFunction {
+        module_address: AccountAddress,
+        module_name: Vec,
+        function_name: Vec,
+    },
+
+    AccountAbstractionRemoveDispatchableAuthenticationFunction {
+        module_address: AccountAddress,
+        module_name: Vec,
+        function_name: Vec,
+    },
+
+    /// Update dispatchable authenticator that disables account abstraction.
+    /// Note: it is a private entry function that can only be called directly from transaction.
+    AccountAbstractionRemoveDispatchableAuthenticator {},
+
     /// Batch version of APT transfer.
     AptosAccountBatchTransfer {
         recipients: Vec,
@@ -810,6 +828,15 @@ pub enum EntryFunctionCall {
         code: Vec>,
     },
 
+    /// Revoke all storable permission handle of the signer immediately.
+    PermissionedSignerRevokeAllHandles {},
+
+    /// Revoke a specific storable permission handle immediately. This will disallow owner of
+    /// the storable permission handle to derive signer from it anymore.
+    PermissionedSignerRevokePermissionStorageAddress {
+        permissions_storage_addr: AccountAddress,
+    },
+
     /// Creates a new resource account and rotates the authentication key to either
     /// the optional auth key if it is non-empty (though auth keys are 32-bytes)
     /// or the source accounts current auth key.
@@ -1216,6 +1243,27 @@ impl EntryFunctionCall {
                 cap_update_table,
             ),
             AccountSetOriginatingAddress {} => account_set_originating_address(),
+            AccountAbstractionAddDispatchableAuthenticationFunction {
+                module_address,
+                module_name,
+                function_name,
+            } => account_abstraction_add_dispatchable_authentication_function(
+                module_address,
+                module_name,
+                function_name,
+            ),
+            AccountAbstractionRemoveDispatchableAuthenticationFunction {
+                module_address,
+                module_name,
+                function_name,
+            } => account_abstraction_remove_dispatchable_authentication_function(
+                module_address,
+                module_name,
+                function_name,
+            ),
+            AccountAbstractionRemoveDispatchableAuthenticator {} => {
+                account_abstraction_remove_dispatchable_authenticator()
+            },
             AptosAccountBatchTransfer {
                 recipients,
                 amounts,
@@ -1593,6 +1641,10 @@ impl EntryFunctionCall {
                 metadata_serialized,
                 code,
             } => object_code_deployment_publish(metadata_serialized, code),
+            PermissionedSignerRevokeAllHandles {} => permissioned_signer_revoke_all_handles(),
+            PermissionedSignerRevokePermissionStorageAddress {
+                permissions_storage_addr,
+            } => permissioned_signer_revoke_permission_storage_address(permissions_storage_addr),
             ResourceAccountCreateResourceAccount {
                 seed,
                 optional_auth_key,
@@ -2093,6 +2145,71 @@ pub fn account_set_originating_address() -> TransactionPayload {
     ))
 }
 
+/// Update dispatchable authenticator that enables account abstraction.
+/// Note: it is a private entry function that can only be called directly from transaction.
+pub fn account_abstraction_add_dispatchable_authentication_function(
+    module_address: AccountAddress,
+    module_name: Vec,
+    function_name: Vec,
+) -> TransactionPayload {
+    TransactionPayload::EntryFunction(EntryFunction::new(
+        ModuleId::new(
+            AccountAddress::new([
+                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,
+            ]),
+            ident_str!("account_abstraction").to_owned(),
+        ),
+        ident_str!("add_dispatchable_authentication_function").to_owned(),
+        vec![],
+        vec![
+            bcs::to_bytes(&module_address).unwrap(),
+            bcs::to_bytes(&module_name).unwrap(),
+            bcs::to_bytes(&function_name).unwrap(),
+        ],
+    ))
+}
+
+pub fn account_abstraction_remove_dispatchable_authentication_function(
+    module_address: AccountAddress,
+    module_name: Vec,
+    function_name: Vec,
+) -> TransactionPayload {
+    TransactionPayload::EntryFunction(EntryFunction::new(
+        ModuleId::new(
+            AccountAddress::new([
+                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,
+            ]),
+            ident_str!("account_abstraction").to_owned(),
+        ),
+        ident_str!("remove_dispatchable_authentication_function").to_owned(),
+        vec![],
+        vec![
+            bcs::to_bytes(&module_address).unwrap(),
+            bcs::to_bytes(&module_name).unwrap(),
+            bcs::to_bytes(&function_name).unwrap(),
+        ],
+    ))
+}
+
+/// Update dispatchable authenticator that disables account abstraction.
+/// Note: it is a private entry function that can only be called directly from transaction.
+pub fn account_abstraction_remove_dispatchable_authenticator() -> TransactionPayload {
+    TransactionPayload::EntryFunction(EntryFunction::new(
+        ModuleId::new(
+            AccountAddress::new([
+                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,
+            ]),
+            ident_str!("account_abstraction").to_owned(),
+        ),
+        ident_str!("remove_dispatchable_authenticator").to_owned(),
+        vec![],
+        vec![],
+    ))
+}
+
 /// Batch version of APT transfer.
 pub fn aptos_account_batch_transfer(
     recipients: Vec,
@@ -3891,6 +4008,41 @@ pub fn object_code_deployment_publish(
     ))
 }
 
+/// Revoke all storable permission handle of the signer immediately.
+pub fn permissioned_signer_revoke_all_handles() -> TransactionPayload {
+    TransactionPayload::EntryFunction(EntryFunction::new(
+        ModuleId::new(
+            AccountAddress::new([
+                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,
+            ]),
+            ident_str!("permissioned_signer").to_owned(),
+        ),
+        ident_str!("revoke_all_handles").to_owned(),
+        vec![],
+        vec![],
+    ))
+}
+
+/// Revoke a specific storable permission handle immediately. This will disallow owner of
+/// the storable permission handle to derive signer from it anymore.
+pub fn permissioned_signer_revoke_permission_storage_address(
+    permissions_storage_addr: AccountAddress,
+) -> TransactionPayload {
+    TransactionPayload::EntryFunction(EntryFunction::new(
+        ModuleId::new(
+            AccountAddress::new([
+                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,
+            ]),
+            ident_str!("permissioned_signer").to_owned(),
+        ),
+        ident_str!("revoke_permission_storage_address").to_owned(),
+        vec![],
+        vec![bcs::to_bytes(&permissions_storage_addr).unwrap()],
+    ))
+}
+
 /// Creates a new resource account and rotates the authentication key to either
 /// the optional auth key if it is non-empty (though auth keys are 32-bytes)
 /// or the source accounts current auth key.
@@ -5153,6 +5305,48 @@ mod decoder {
         }
     }
 
+    pub fn account_abstraction_add_dispatchable_authentication_function(
+        payload: &TransactionPayload,
+    ) -> Option {
+        if let TransactionPayload::EntryFunction(script) = payload {
+            Some(
+                EntryFunctionCall::AccountAbstractionAddDispatchableAuthenticationFunction {
+                    module_address: bcs::from_bytes(script.args().get(0)?).ok()?,
+                    module_name: bcs::from_bytes(script.args().get(1)?).ok()?,
+                    function_name: bcs::from_bytes(script.args().get(2)?).ok()?,
+                },
+            )
+        } else {
+            None
+        }
+    }
+
+    pub fn account_abstraction_remove_dispatchable_authentication_function(
+        payload: &TransactionPayload,
+    ) -> Option {
+        if let TransactionPayload::EntryFunction(script) = payload {
+            Some(
+                EntryFunctionCall::AccountAbstractionRemoveDispatchableAuthenticationFunction {
+                    module_address: bcs::from_bytes(script.args().get(0)?).ok()?,
+                    module_name: bcs::from_bytes(script.args().get(1)?).ok()?,
+                    function_name: bcs::from_bytes(script.args().get(2)?).ok()?,
+                },
+            )
+        } else {
+            None
+        }
+    }
+
+    pub fn account_abstraction_remove_dispatchable_authenticator(
+        payload: &TransactionPayload,
+    ) -> Option {
+        if let TransactionPayload::EntryFunction(_script) = payload {
+            Some(EntryFunctionCall::AccountAbstractionRemoveDispatchableAuthenticator {})
+        } else {
+            None
+        }
+    }
+
     pub fn aptos_account_batch_transfer(payload: &TransactionPayload) -> Option {
         if let TransactionPayload::EntryFunction(script) = payload {
             Some(EntryFunctionCall::AptosAccountBatchTransfer {
@@ -6174,6 +6368,30 @@ mod decoder {
         }
     }
 
+    pub fn permissioned_signer_revoke_all_handles(
+        payload: &TransactionPayload,
+    ) -> Option {
+        if let TransactionPayload::EntryFunction(_script) = payload {
+            Some(EntryFunctionCall::PermissionedSignerRevokeAllHandles {})
+        } else {
+            None
+        }
+    }
+
+    pub fn permissioned_signer_revoke_permission_storage_address(
+        payload: &TransactionPayload,
+    ) -> Option {
+        if let TransactionPayload::EntryFunction(script) = payload {
+            Some(
+                EntryFunctionCall::PermissionedSignerRevokePermissionStorageAddress {
+                    permissions_storage_addr: bcs::from_bytes(script.args().get(0)?).ok()?,
+                },
+            )
+        } else {
+            None
+        }
+    }
+
     pub fn resource_account_create_resource_account(
         payload: &TransactionPayload,
     ) -> Option {
@@ -6897,6 +7115,18 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazyv in BCS (Binary Canonical Serialization) format.
 Aborts with 0x1c5 error code if serialization fails.
 
diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md
index ba2122e8a9788..69b1082ad9b59 100644
--- a/aptos-move/framework/move-stdlib/doc/features.md
+++ b/aptos-move/framework/move-stdlib/doc/features.md
@@ -135,6 +135,10 @@ return true.
 -  [Function `is_collection_owner_enabled`](#0x1_features_is_collection_owner_enabled)
 -  [Function `get_native_memory_operations_feature`](#0x1_features_get_native_memory_operations_feature)
 -  [Function `is_native_memory_operations_enabled`](#0x1_features_is_native_memory_operations_enabled)
+-  [Function `get_permissioned_signer_feature`](#0x1_features_get_permissioned_signer_feature)
+-  [Function `is_permissioned_signer_enabled`](#0x1_features_is_permissioned_signer_enabled)
+-  [Function `get_account_abstraction_feature`](#0x1_features_get_account_abstraction_feature)
+-  [Function `is_account_abstraction_enabled`](#0x1_features_is_account_abstraction_enabled)
 -  [Function `change_feature_flags`](#0x1_features_change_feature_flags)
 -  [Function `change_feature_flags_internal`](#0x1_features_change_feature_flags_internal)
 -  [Function `change_feature_flags_for_next_epoch`](#0x1_features_change_feature_flags_for_next_epoch)
@@ -242,6 +246,18 @@ Lifetime: transient
 
 
 
+
+
+Whether the account abstraction is enabled.
+
+Lifetime: transient
+
+
+
const ACCOUNT_ABSTRACTION: u64 = 85;
+
+ + + @@ -754,6 +770,15 @@ Lifetime: transient + + + + +
const PERMISSIONED_SIGNER: u64 = 84;
+
+ + + @@ -3330,6 +3355,98 @@ Deprecated feature + + + + +## Function `get_permissioned_signer_feature` + + + +
public fun get_permissioned_signer_feature(): u64
+
+ + + +
+Implementation + + +
public fun get_permissioned_signer_feature(): u64 { PERMISSIONED_SIGNER }
+
+ + + +
+ + + +## Function `is_permissioned_signer_enabled` + + + +
public fun is_permissioned_signer_enabled(): bool
+
+ + + +
+Implementation + + +
public fun is_permissioned_signer_enabled(): bool acquires Features {
+    is_enabled(PERMISSIONED_SIGNER)
+}
+
+ + + +
+ + + +## Function `get_account_abstraction_feature` + + + +
public fun get_account_abstraction_feature(): u64
+
+ + + +
+Implementation + + +
public fun get_account_abstraction_feature(): u64 { ACCOUNT_ABSTRACTION }
+
+ + + +
+ + + +## Function `is_account_abstraction_enabled` + + + +
public fun is_account_abstraction_enabled(): bool
+
+ + + +
+Implementation + + +
public fun is_account_abstraction_enabled(): bool acquires Features {
+    is_enabled(ACCOUNT_ABSTRACTION)
+}
+
+ + +
diff --git a/aptos-move/framework/move-stdlib/doc/signer.md b/aptos-move/framework/move-stdlib/doc/signer.md index f6de8799b571c..13e9e008ef8d3 100644 --- a/aptos-move/framework/move-stdlib/doc/signer.md +++ b/aptos-move/framework/move-stdlib/doc/signer.md @@ -18,12 +18,26 @@ ## Function `borrow_address` -Borrows the address of the signer -Conceptually, you can think of the signer as being a struct wrapper around an -address +signer is a builtin move type that represents an address that has been verfied by the VM. + +VM Runtime representation is equivalent to following: +``` +enum signer has drop { +Master { account: address }, +Permissioned { account: address, permissions_address: address }, +} +``` + +for bcs serialization: + ``` -struct signer has drop { addr: address } +struct signer has drop { +account: address, +} ``` +^ The discrepency is needed to maintain backwards compatibility of signer serialization +semantics. + borrow_address borrows this inner field diff --git a/aptos-move/framework/move-stdlib/sources/bcs.move b/aptos-move/framework/move-stdlib/sources/bcs.move index b803428eef991..1113a02c9c269 100644 --- a/aptos-move/framework/move-stdlib/sources/bcs.move +++ b/aptos-move/framework/move-stdlib/sources/bcs.move @@ -5,6 +5,8 @@ module std::bcs { use std::option::Option; + /// Note: all natives would fail if the MoveValue contains a permissioned signer in it. + /// Returns the binary representation of `v` in BCS (Binary Canonical Serialization) format. /// Aborts with `0x1c5` error code if serialization fails. native public fun to_bytes(v: &MoveValue): vector; diff --git a/aptos-move/framework/move-stdlib/sources/configs/features.move b/aptos-move/framework/move-stdlib/sources/configs/features.move index 2b3a5291c600d..28de7017df8d9 100644 --- a/aptos-move/framework/move-stdlib/sources/configs/features.move +++ b/aptos-move/framework/move-stdlib/sources/configs/features.move @@ -615,6 +615,25 @@ module std::features { is_enabled(NATIVE_MEMORY_OPERATIONS) } + const PERMISSIONED_SIGNER: u64 = 84; + + public fun get_permissioned_signer_feature(): u64 { PERMISSIONED_SIGNER } + + public fun is_permissioned_signer_enabled(): bool acquires Features { + is_enabled(PERMISSIONED_SIGNER) + } + + /// Whether the account abstraction is enabled. + /// + /// Lifetime: transient + const ACCOUNT_ABSTRACTION: u64 = 85; + + public fun get_account_abstraction_feature(): u64 { ACCOUNT_ABSTRACTION } + + public fun is_account_abstraction_enabled(): bool acquires Features { + is_enabled(ACCOUNT_ABSTRACTION) + } + // ============================================================================================ // Feature Flag Implementation diff --git a/aptos-move/framework/move-stdlib/sources/signer.move b/aptos-move/framework/move-stdlib/sources/signer.move index c2e3ab3f559f8..16d5c2cc8ddae 100644 --- a/aptos-move/framework/move-stdlib/sources/signer.move +++ b/aptos-move/framework/move-stdlib/sources/signer.move @@ -1,10 +1,24 @@ module std::signer { - /// Borrows the address of the signer - /// Conceptually, you can think of the `signer` as being a struct wrapper around an - /// address + /// signer is a builtin move type that represents an address that has been verfied by the VM. + /// + /// VM Runtime representation is equivalent to following: /// ``` - /// struct signer has drop { addr: address } + /// enum signer has drop { + /// Master { account: address }, + /// Permissioned { account: address, permissions_address: address }, + /// } /// ``` + /// + /// for bcs serialization: + /// + /// ``` + /// struct signer has drop { + /// account: address, + /// } + /// ``` + /// ^ The discrepency is needed to maintain backwards compatibility of signer serialization + /// semantics. + /// /// `borrow_address` borrows this inner field native public fun borrow_address(s: &signer): &address; diff --git a/aptos-move/framework/move-stdlib/src/natives/bcs.rs b/aptos-move/framework/move-stdlib/src/natives/bcs.rs index d7cd0e9d258c4..0028d48319cbb 100644 --- a/aptos-move/framework/move-stdlib/src/natives/bcs.rs +++ b/aptos-move/framework/move-stdlib/src/natives/bcs.rs @@ -70,6 +70,7 @@ fn native_to_bytes( let val = ref_to_val.read_ref()?; let serialized_value = match ValueSerDeContext::new() + .with_legacy_signer() .with_func_args_deserialization(context.function_value_extension()) .serialize(&val, &layout)? { @@ -136,6 +137,7 @@ fn serialized_size_impl( let ty_layout = context.type_to_type_layout(ty)?; ValueSerDeContext::new() + .with_legacy_signer() .with_func_args_deserialization(context.function_value_extension()) .with_delayed_fields_serde() .serialized_size(&value, &ty_layout) diff --git a/aptos-move/framework/move-stdlib/src/natives/unit_test.rs b/aptos-move/framework/move-stdlib/src/natives/unit_test.rs index f23a1fb56b6f6..9e928af622264 100644 --- a/aptos-move/framework/move-stdlib/src/natives/unit_test.rs +++ b/aptos-move/framework/move-stdlib/src/natives/unit_test.rs @@ -38,7 +38,7 @@ fn native_create_signers_for_testing( let num_signers = safely_pop_arg!(args, u64); let signers = Value::vector_for_testing_only( - (0..num_signers).map(|i| Value::signer(AccountAddress::new(to_le_bytes(i)))), + (0..num_signers).map(|i| Value::master_signer(AccountAddress::new(to_le_bytes(i)))), ); Ok(smallvec![signers]) diff --git a/aptos-move/framework/move-stdlib/tests/bcs_tests.move b/aptos-move/framework/move-stdlib/tests/bcs_tests.move index c22cf8126342d..855a5494691be 100644 --- a/aptos-move/framework/move-stdlib/tests/bcs_tests.move +++ b/aptos-move/framework/move-stdlib/tests/bcs_tests.move @@ -157,4 +157,12 @@ module std::bcs_tests { assert!(std::cmp::compare(&bytes_val, &bytes_other).is_lt()); } + + #[test(s1 = @0x123)] + fun test_signer_serialization(s1: signer) { + assert!( + bcs::to_bytes(&s1) == bcs::to_bytes(&@0x123), + 1 + ); + } } diff --git a/aptos-move/framework/src/built_package.rs b/aptos-move/framework/src/built_package.rs index b79095ed4cc2a..def5da75b83a1 100644 --- a/aptos-move/framework/src/built_package.rs +++ b/aptos-move/framework/src/built_package.rs @@ -272,7 +272,7 @@ impl BuiltPackage { if let Some(model_options) = model.get_extension::() { if model_options.experiment_on(Experiment::STOP_BEFORE_EXTENDED_CHECKS) { - std::process::exit(0) + std::process::exit(if model.has_warnings() { 1 } else { 0 }) } } @@ -287,7 +287,7 @@ impl BuiltPackage { if let Some(model_options) = model.get_extension::() { if model_options.experiment_on(Experiment::STOP_AFTER_EXTENDED_CHECKS) { - std::process::exit(0) + std::process::exit(if model.has_warnings() { 1 } else { 0 }) } } diff --git a/aptos-move/framework/src/natives/account_abstraction.rs b/aptos-move/framework/src/natives/account_abstraction.rs new file mode 100644 index 0000000000000..65bff16aad776 --- /dev/null +++ b/aptos-move/framework/src/natives/account_abstraction.rs @@ -0,0 +1,61 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use super::function_info::extract_function_info; +use aptos_gas_schedule::gas_params::natives::aptos_framework::DISPATCHABLE_AUTHENTICATE_DISPATCH_BASE; +use aptos_native_interface::{ + RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeError, SafeNativeResult, +}; +use move_vm_runtime::native_functions::NativeFunction; +use move_vm_types::{loaded_data::runtime_types::Type, values::Value}; +use smallvec::SmallVec; +use std::collections::VecDeque; + +/*************************************************************************************************** + * native fun dispatchable_authenticate + * + * Directs control flow based on the last argument. We use the same native function implementation + * for all dispatching native. + * gas cost: a flat fee because we charged the loading of those modules previously. + * + **************************************************************************************************/ +pub(crate) fn native_dispatch( + context: &mut SafeNativeContext, + ty_args: Vec, + mut arguments: VecDeque, +) -> SafeNativeResult> { + let (module_name, func_name) = extract_function_info(&mut arguments)?; + // Check if the module is already properly charged in this transaction. + if !module_name.address().is_special() + && !context + .traversal_context() + .visited + .contains_key(&(module_name.address(), module_name.name())) + { + return Err(SafeNativeError::Abort { abort_code: 4 }); + } + + // Use Error to instruct the VM to perform a function call dispatch. + Err(SafeNativeError::FunctionDispatch { + cost: context.eval_gas(DISPATCHABLE_AUTHENTICATE_DISPATCH_BASE), + module_name, + func_name, + ty_args, + args: arguments.into_iter().collect(), + }) +} + +/*************************************************************************************************** + * module + * + **************************************************************************************************/ +pub fn make_all( + builder: &SafeNativeBuilder, +) -> impl Iterator + '_ { + let natives = [( + "dispatchable_authenticate", + native_dispatch as RawSafeNative, + )]; + + builder.make_named_natives(natives) +} diff --git a/aptos-move/framework/src/natives/create_signer.rs b/aptos-move/framework/src/natives/create_signer.rs index c8605088113da..6ba6f79b578d9 100644 --- a/aptos-move/framework/src/natives/create_signer.rs +++ b/aptos-move/framework/src/natives/create_signer.rs @@ -28,7 +28,7 @@ pub(crate) fn native_create_signer( context.charge(ACCOUNT_CREATE_SIGNER_BASE)?; let address = safely_pop_arg!(arguments, AccountAddress); - Ok(smallvec![Value::signer(address)]) + Ok(smallvec![Value::master_signer(address)]) } /*************************************************************************************************** diff --git a/aptos-move/framework/src/natives/dispatchable_fungible_asset.rs b/aptos-move/framework/src/natives/dispatchable_fungible_asset.rs index 9554c5d163377..b9dc026345868 100644 --- a/aptos-move/framework/src/natives/dispatchable_fungible_asset.rs +++ b/aptos-move/framework/src/natives/dispatchable_fungible_asset.rs @@ -25,11 +25,19 @@ pub(crate) fn native_dispatch( ) -> SafeNativeResult> { let (module_name, func_name) = extract_function_info(&mut arguments)?; // Check if the module is already properly charged in this transaction. - if !context - .traversal_context() - .visited - .contains_key(&(module_name.address(), module_name.name())) - { + let is_err = if context.get_feature_flags().is_account_abstraction_enabled() { + !module_name.address().is_special() + && !context + .traversal_context() + .visited + .contains_key(&(module_name.address(), module_name.name())) + } else { + !context + .traversal_context() + .visited + .contains_key(&(module_name.address(), module_name.name())) + }; + if is_err { return Err(SafeNativeError::Abort { abort_code: 4 }); } diff --git a/aptos-move/framework/src/natives/function_info.rs b/aptos-move/framework/src/natives/function_info.rs index 2884ad8c82141..e30061b6fb806 100644 --- a/aptos-move/framework/src/natives/function_info.rs +++ b/aptos-move/framework/src/natives/function_info.rs @@ -83,11 +83,19 @@ fn native_check_dispatch_type_compatibility_impl( let (rhs, rhs_id) = { let (module, func) = extract_function_info(&mut arguments)?; - if !context - .traversal_context() - .visited - .contains_key(&(module.address(), module.name())) - { + let is_err = if context.get_feature_flags().is_account_abstraction_enabled() { + !module.address().is_special() + && !context + .traversal_context() + .visited + .contains_key(&(module.address(), module.name())) + } else { + !context + .traversal_context() + .visited + .contains_key(&(module.address(), module.name())) + }; + if is_err { return Err(SafeNativeError::Abort { abort_code: 2 }); } ( diff --git a/aptos-move/framework/src/natives/mod.rs b/aptos-move/framework/src/natives/mod.rs index dcfc80407f932..4fc3c8ec76e07 100644 --- a/aptos-move/framework/src/natives/mod.rs +++ b/aptos-move/framework/src/natives/mod.rs @@ -3,6 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 pub mod account; + +pub mod account_abstraction; pub mod aggregator_natives; pub mod code; pub mod consensus_config; @@ -15,6 +17,7 @@ pub mod function_info; pub mod hash; pub mod object; pub mod object_code_deployment; +pub mod permissioned_signer; pub mod randomness; pub mod state_storage; pub mod string_utils; @@ -91,6 +94,14 @@ pub fn all_natives( "dispatchable_fungible_asset", dispatchable_fungible_asset::make_all(builder) ); + add_natives_from_module!( + "permissioned_signer", + permissioned_signer::make_all(builder) + ); + add_natives_from_module!( + "account_abstraction", + account_abstraction::make_all(builder) + ); if inject_create_signer_for_gov_sim { add_natives_from_module!( diff --git a/aptos-move/framework/src/natives/permissioned_signer.rs b/aptos-move/framework/src/natives/permissioned_signer.rs new file mode 100644 index 0000000000000..e080a1e1f3f08 --- /dev/null +++ b/aptos-move/framework/src/natives/permissioned_signer.rs @@ -0,0 +1,142 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 +use aptos_gas_schedule::gas_params::natives::aptos_framework::{ + IS_PERMISSIONED_SIGNER_BASE, PERMISSION_ADDRESS_BASE, SIGNER_FROM_PERMISSIONED_HANDLE_BASE, +}; +use aptos_native_interface::{ + safely_pop_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeError, + SafeNativeResult, +}; +use move_core_types::account_address::AccountAddress; +use move_vm_runtime::native_functions::NativeFunction; +use move_vm_types::{ + loaded_data::runtime_types::Type, + values::{SignerRef, Value}, +}; +use smallvec::{smallvec, SmallVec}; +use std::collections::VecDeque; + +const EPERMISSION_SIGNER_DISABLED: u64 = 9; + +/*************************************************************************************************** + * native fun is_permissioned_signer_impl + * + * Returns true if the signer passed in is a permissioned signer + * gas cost: base_cost + * + **************************************************************************************************/ +fn native_is_permissioned_signer_impl( + context: &mut SafeNativeContext, + _ty_args: Vec, + mut arguments: VecDeque, +) -> SafeNativeResult> { + debug_assert!(arguments.len() == 1); + + if !context + .get_feature_flags() + .is_enabled(aptos_types::on_chain_config::FeatureFlag::PERMISSIONED_SIGNER) + { + return SafeNativeResult::Err(SafeNativeError::Abort { + abort_code: EPERMISSION_SIGNER_DISABLED, + }); + } + + let signer = safely_pop_arg!(arguments, SignerRef); + + context.charge(IS_PERMISSIONED_SIGNER_BASE)?; + let result = signer.is_permissioned()?; + + Ok(smallvec![Value::bool(result)]) +} + +/*************************************************************************************************** + * native fun permission_address + * + * Returns the permission storage address if the signer passed in is a permissioned signer + * gas cost: base_cost + * + **************************************************************************************************/ +fn native_permission_address( + context: &mut SafeNativeContext, + _ty_args: Vec, + mut args: VecDeque, +) -> SafeNativeResult> { + debug_assert!(args.len() == 1); + + if !context + .get_feature_flags() + .is_enabled(aptos_types::on_chain_config::FeatureFlag::PERMISSIONED_SIGNER) + { + return SafeNativeResult::Err(SafeNativeError::Abort { + abort_code: EPERMISSION_SIGNER_DISABLED, + }); + } + + let signer = safely_pop_arg!(args, SignerRef); + + context.charge(PERMISSION_ADDRESS_BASE)?; + if !signer.is_permissioned()? { + return Err(SafeNativeError::Abort { abort_code: 3 }); + } + + Ok(smallvec![signer.permission_address()?]) +} + +/*************************************************************************************************** + * native fun signer_from_permissioned_handle_impl + * + * Returns the permission signer from a master signer. + * gas cost: base_cost + * + **************************************************************************************************/ +fn native_signer_from_permissioned( + context: &mut SafeNativeContext, + _ty_args: Vec, + mut arguments: VecDeque, +) -> SafeNativeResult> { + debug_assert!(arguments.len() == 2); + + if !context + .get_feature_flags() + .is_enabled(aptos_types::on_chain_config::FeatureFlag::PERMISSIONED_SIGNER) + { + return SafeNativeResult::Err(SafeNativeError::Abort { + abort_code: EPERMISSION_SIGNER_DISABLED, + }); + } + + let permission_addr = safely_pop_arg!(arguments, AccountAddress); + let master_addr = safely_pop_arg!(arguments, AccountAddress); + context.charge(SIGNER_FROM_PERMISSIONED_HANDLE_BASE)?; + + Ok(smallvec![Value::permissioned_signer( + master_addr, + permission_addr + )]) +} + +/*************************************************************************************************** + * module + * + **************************************************************************************************/ +pub fn make_all( + builder: &SafeNativeBuilder, +) -> impl Iterator + '_ { + let natives = [ + ( + "is_permissioned_signer_impl", + native_is_permissioned_signer_impl as RawSafeNative, + ), + ( + "is_permissioned_signer", + native_is_permissioned_signer_impl as RawSafeNative, + ), + ("permission_address", native_permission_address), + ( + "signer_from_permissioned_handle_impl", + native_signer_from_permissioned, + ), + ]; + + builder.make_named_natives(natives) +} diff --git a/aptos-move/framework/src/natives/string_utils.rs b/aptos-move/framework/src/natives/string_utils.rs index 0a4c7c71583f8..28e9fd50b103f 100644 --- a/aptos-move/framework/src/natives/string_utils.rs +++ b/aptos-move/framework/src/natives/string_utils.rs @@ -13,7 +13,7 @@ use move_core_types::{ account_address::AccountAddress, language_storage::TypeTag, u256, - value::{MoveFieldLayout, MoveStructLayout, MoveTypeLayout}, + value::{MoveFieldLayout, MoveStructLayout, MoveTypeLayout, MASTER_ADDRESS_FIELD_OFFSET}, }; use move_vm_runtime::native_functions::NativeFunction; use move_vm_types::{ @@ -188,8 +188,11 @@ fn native_format_impl( let addr = if fix_enabled { val.value_as::()? .unpack()? - .next() - .unwrap() + // The second field of a signer is always the master address regardless of which variants. + .nth(MASTER_ADDRESS_FIELD_OFFSET) + .ok_or_else(|| SafeNativeError::Abort { + abort_code: EINVALID_FORMAT, + })? .value_as::()? } else { val.value_as::()? diff --git a/aptos-move/framework/src/natives/util.rs b/aptos-move/framework/src/natives/util.rs index f39239491fae1..4ce9d70880bf1 100644 --- a/aptos-move/framework/src/natives/util.rs +++ b/aptos-move/framework/src/natives/util.rs @@ -43,6 +43,7 @@ fn native_from_bytes( UTIL_FROM_BYTES_BASE + UTIL_FROM_BYTES_PER_BYTE * NumBytes::new(bytes.len() as u64), )?; let val = match ValueSerDeContext::new() + .with_legacy_signer() .with_func_args_deserialization(context.function_value_extension()) .deserialize(&bytes, &layout) { diff --git a/aptos-move/move-examples/account_abstraction/bls12381_single_key/Move.toml b/aptos-move/move-examples/account_abstraction/bls12381_single_key/Move.toml new file mode 100644 index 0000000000000..18c97ec8116e9 --- /dev/null +++ b/aptos-move/move-examples/account_abstraction/bls12381_single_key/Move.toml @@ -0,0 +1,10 @@ +[package] +name = "AA" +version = "0.0.0" + +[addresses] +aa = "_" + +[dependencies] +AptosFramework = { local = "../../../framework/aptos-framework" } +AptosStdlib = { local = "../../../framework/aptos-stdlib" } diff --git a/aptos-move/move-examples/account_abstraction/bls12381_single_key/sources/single_key.move b/aptos-move/move-examples/account_abstraction/bls12381_single_key/sources/single_key.move new file mode 100644 index 0000000000000..25e1e37c0ffa7 --- /dev/null +++ b/aptos-move/move-examples/account_abstraction/bls12381_single_key/sources/single_key.move @@ -0,0 +1,58 @@ +module aa::single_key { + use std::option; + use std::signer; + use aptos_std::bls12381::{Self, PublicKey}; + use aptos_framework::auth_data::{Self, AbstractionAuthData}; + + /// Only fungible asset metadata owner can make changes. + const EINVALID_PUBLIC_KEY: u64 = 1; + const EPUBLIC_KEY_NOT_FOUND: u64 = 2; + const EINVALID_SIGNATURE: u64 = 3; + + /// Store the BLS public key. + struct BLSPublicKey has key, drop { + key: PublicKey + } + + /// Update the public key. + public entry fun update_public_key(admin: &signer, key: vector) acquires BLSPublicKey { + let addr = signer::address_of(admin); + let pubkey_opt = bls12381::public_key_from_bytes(key); + assert!(option::is_some(&pubkey_opt), EINVALID_PUBLIC_KEY); + if (exists(addr)) { + let pubkey = &mut borrow_global_mut(addr).key; + *pubkey = option::destroy_some(pubkey_opt); + } else { + move_to(admin, BLSPublicKey { + key: option::destroy_some(pubkey_opt) + }) + }; + } + + /// Authorization function for account abstraction. + public fun authenticate( + account: signer, + signing_data: AbstractionAuthData, + ): signer acquires BLSPublicKey { + let addr = signer::address_of(&account); + assert!(exists(addr), EPUBLIC_KEY_NOT_FOUND); + let pubkey = &borrow_global(addr).key; + assert!( + bls12381::verify_normal_signature( + &bls12381::signature_from_bytes(*auth_data::authenticator(&signing_data)), + pubkey, + *auth_data::digest(&signing_data) + ), + EINVALID_SIGNATURE + ); + account + } + + /// cleanup storage footprint before transition to another authentication scheme. + public entry fun cleanup(admin: &signer) acquires BLSPublicKey { + let addr = signer::address_of(admin); + if (exists(addr)) { + move_from(addr); + }; + } +} diff --git a/aptos-move/move-examples/account_abstraction/bls12381_single_key/sources/test_functions.move b/aptos-move/move-examples/account_abstraction/bls12381_single_key/sources/test_functions.move new file mode 100644 index 0000000000000..b522b2fd6393e --- /dev/null +++ b/aptos-move/move-examples/account_abstraction/bls12381_single_key/sources/test_functions.move @@ -0,0 +1,10 @@ +module aa::test_functions { + use aptos_framework::aptos_account; + + /// test function for multi-agent aa. + public entry fun transfer_to_the_last(a: &signer, b: &signer, c: &signer, d: address) { + aptos_account::transfer(a, d, 1); + aptos_account::transfer(b, d, 1); + aptos_account::transfer(c, d, 1); + } +} diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index 239713079c616..ea57e7b377de2 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -27,8 +27,7 @@ use aptos_types::{ secure_test_rsa_jwk, }, keyless::{ - self, test_utils::get_sample_iss, Groth16VerificationKey, DEVNET_VERIFICATION_KEY, - KEYLESS_ACCOUNT_MODULE_NAME, + self, test_utils::get_sample_iss, Groth16VerificationKey, KEYLESS_ACCOUNT_MODULE_NAME, }, move_utils::as_move_value::AsMoveValue, on_chain_config::{ @@ -111,7 +110,7 @@ pub struct GenesisConfiguration { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub initial_jwks: Vec, - pub keyless_groth16_vk_override: Option, + pub keyless_groth16_vk: Option, } pub static GENESIS_KEYPAIR: Lazy<(Ed25519PrivateKey, Ed25519PublicKey)> = Lazy::new(|| { @@ -312,7 +311,7 @@ pub fn encode_genesis_change_set( &module_storage, chain_id, genesis_config.initial_jwks.clone(), - genesis_config.keyless_groth16_vk_override.clone(), + genesis_config.keyless_groth16_vk.clone(), ); set_genesis_end(&mut session, &module_storage); @@ -686,7 +685,7 @@ fn initialize_keyless_accounts( module_storage: &impl AptosModuleStorage, chain_id: ChainId, mut initial_jwks: Vec, - vk_override: Option, + vk: Option, ) { let config = keyless::Configuration::new_for_devnet(); exec_function( @@ -700,9 +699,8 @@ fn initialize_keyless_accounts( config.as_move_value(), ]), ); - if !chain_id.is_mainnet() { - let vk = - vk_override.unwrap_or_else(|| Groth16VerificationKey::from(&*DEVNET_VERIFICATION_KEY)); + + if vk.is_some() { exec_function( session, module_storage, @@ -711,10 +709,11 @@ fn initialize_keyless_accounts( vec![], serialize_values(&vec![ MoveValue::Signer(CORE_CODE_ADDRESS), - vk.as_move_value(), + vk.unwrap().as_move_value(), ]), ); - + } + if !chain_id.is_mainnet() { let additional_jwk_patch = IssuerJWK { issuer: get_sample_iss(), jwk: JWK::RSA(secure_test_rsa_jwk()), @@ -1255,7 +1254,7 @@ pub fn generate_test_genesis( randomness_config_override: None, jwk_consensus_config_override: None, initial_jwks: vec![], - keyless_groth16_vk_override: None, + keyless_groth16_vk: None, }, &OnChainConsensusConfig::default_for_genesis(), &OnChainExecutionConfig::default_for_genesis(), @@ -1307,7 +1306,7 @@ fn mainnet_genesis_config() -> GenesisConfiguration { randomness_config_override: None, jwk_consensus_config_override: None, initial_jwks: vec![], - keyless_groth16_vk_override: None, + keyless_groth16_vk: None, } } diff --git a/config/src/config/api_config.rs b/config/src/config/api_config.rs index 1758d8c227994..a70d17411def4 100644 --- a/config/src/config/api_config.rs +++ b/config/src/config/api_config.rs @@ -40,6 +40,9 @@ pub struct ApiConfig { /// Enables BCS output of APIs that support it #[serde(default = "default_enabled")] pub bcs_output_enabled: bool, + /// Enables compression middleware for API responses + #[serde(default = "default_enabled")] + pub compression_enabled: bool, /// Enables encode submission API #[serde(default = "default_enabled")] pub encode_submission_enabled: bool, @@ -121,6 +124,7 @@ impl Default for ApiConfig { failpoints_enabled: default_disabled(), bcs_output_enabled: default_enabled(), json_output_enabled: default_enabled(), + compression_enabled: default_enabled(), encode_submission_enabled: default_enabled(), transaction_submission_enabled: default_enabled(), transaction_simulation_enabled: default_enabled(), diff --git a/consensus/consensus-types/src/block.rs b/consensus/consensus-types/src/block.rs index e6ad6c6c15a66..e80fbb7c83347 100644 --- a/consensus/consensus-types/src/block.rs +++ b/consensus/consensus-types/src/block.rs @@ -360,6 +360,11 @@ impl Block { "Reconfiguration suffix should not carry payload" ); } + + if let Some(payload) = self.payload() { + payload.verify_epoch(self.epoch())?; + } + if let Some(failed_authors) = self.block_data().failed_authors() { // when validating for being well formed, // allow for missing failed authors, diff --git a/consensus/consensus-types/src/common.rs b/consensus/consensus-types/src/common.rs index 869a40c683cc4..f57c5c50cbf5d 100644 --- a/consensus/consensus-types/src/common.rs +++ b/consensus/consensus-types/src/common.rs @@ -6,6 +6,7 @@ use crate::{ payload::{OptQuorumStorePayload, PayloadExecutionLimit}, proof_of_store::{BatchInfo, ProofCache, ProofOfStore}, }; +use anyhow::ensure; use aptos_crypto::{ hash::{CryptoHash, CryptoHasher}, HashValue, @@ -487,6 +488,23 @@ impl Payload { Ok(()) } + pub fn verify_inline_batches<'a>( + inline_batches: impl Iterator)>, + ) -> anyhow::Result<()> { + for (batch, payload) in inline_batches { + // TODO: Can cloning be avoided here? + let computed_digest = BatchPayload::new(batch.author(), payload.clone()).hash(); + ensure!( + computed_digest == *batch.digest(), + "Hash of the received inline batch doesn't match the digest value for batch {}: {} != {}", + batch, + computed_digest, + batch.digest() + ); + } + Ok(()) + } + pub fn verify( &self, validator: &ValidatorVerifier, @@ -505,20 +523,20 @@ impl Payload { ), (true, Payload::QuorumStoreInlineHybrid(inline_batches, proof_with_data, _)) => { Self::verify_with_cache(&proof_with_data.proofs, validator, proof_cache)?; - for (batch, payload) in inline_batches.iter() { - // TODO: Can cloning be avoided here? - if BatchPayload::new(batch.author(), payload.clone()).hash() != *batch.digest() - { - return Err(anyhow::anyhow!( - "Hash of the received inline batch doesn't match the digest value", - )); - } - } + Self::verify_inline_batches( + inline_batches.iter().map(|(info, txns)| (info, txns)), + )?; Ok(()) }, (true, Payload::OptQuorumStore(opt_quorum_store)) => { let proof_with_data = opt_quorum_store.proof_with_data(); Self::verify_with_cache(&proof_with_data.batch_summary, validator, proof_cache)?; + Self::verify_inline_batches( + opt_quorum_store + .inline_batches() + .iter() + .map(|batch| (batch.info(), batch.transactions())), + )?; Ok(()) }, (_, _) => Err(anyhow::anyhow!( @@ -528,6 +546,42 @@ impl Payload { )), } } + + pub(crate) fn verify_epoch(&self, epoch: u64) -> anyhow::Result<()> { + match self { + Payload::DirectMempool(_) => return Ok(()), + Payload::InQuorumStore(proof_with_data) => { + ensure!( + proof_with_data.proofs.iter().all(|p| p.epoch() == epoch), + "Payload epoch doesn't match given epoch" + ); + }, + Payload::InQuorumStoreWithLimit(proof_with_data_with_txn_limit) => { + ensure!( + proof_with_data_with_txn_limit + .proof_with_data + .proofs + .iter() + .all(|p| p.epoch() == epoch), + "Payload epoch doesn't match given epoch" + ); + }, + Payload::QuorumStoreInlineHybrid(inline_batches, proof_with_data, _) => { + ensure!( + proof_with_data.proofs.iter().all(|p| p.epoch() == epoch), + "Payload proof epoch doesn't match given epoch" + ); + ensure!( + inline_batches.iter().all(|b| b.0.epoch() == epoch), + "Payload inline batch epoch doesn't match given epoch" + ) + }, + Payload::OptQuorumStore(opt_quorum_store_payload) => { + opt_quorum_store_payload.check_epoch(epoch)?; + }, + }; + Ok(()) + } } impl fmt::Display for Payload { diff --git a/consensus/consensus-types/src/payload.rs b/consensus/consensus-types/src/payload.rs index 9514c8d00907c..d4dd7b26db86a 100644 --- a/consensus/consensus-types/src/payload.rs +++ b/consensus/consensus-types/src/payload.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::proof_of_store::{BatchInfo, ProofOfStore}; +use anyhow::ensure; use aptos_executor_types::ExecutorResult; use aptos_infallible::Mutex; use aptos_types::{transaction::SignedTransaction, PeerId}; @@ -33,6 +34,7 @@ pub trait TDataInfo { pub struct DataFetchFut { pub iteration: u32, + pub responders: Vec>>>, pub fut: Shared>>>, } @@ -186,6 +188,10 @@ impl InlineBatch { pub fn info(&self) -> &BatchInfo { &self.batch_info } + + pub fn transactions(&self) -> &Vec { + &self.transactions + } } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] @@ -286,6 +292,26 @@ impl OptQuorumStorePayloadV1 { PayloadExecutionLimit::MaxTransactionsToExecute(max) => Some(max), } } + + pub fn check_epoch(&self, epoch: u64) -> anyhow::Result<()> { + ensure!( + self.inline_batches + .iter() + .all(|b| b.info().epoch() == epoch), + "OptQS InlineBatch epoch doesn't match given epoch" + ); + ensure!( + self.opt_batches.iter().all(|b| b.info().epoch() == epoch), + "OptQS OptBatch epoch doesn't match given epoch" + ); + + ensure!( + self.proofs.iter().all(|b| b.info().epoch() == epoch), + "OptQS Proof epoch doesn't match given epoch" + ); + + Ok(()) + } } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] diff --git a/consensus/consensus-types/src/pipelined_block.rs b/consensus/consensus-types/src/pipelined_block.rs index b0cc069aff768..e3a0856996576 100644 --- a/consensus/consensus-types/src/pipelined_block.rs +++ b/consensus/consensus-types/src/pipelined_block.rs @@ -105,6 +105,7 @@ impl PipelineFutures { } pub struct PipelineInputTx { + pub qc_tx: Option>>, pub rand_tx: Option>>, pub order_vote_tx: Option>, pub order_proof_tx: Option>, @@ -112,6 +113,7 @@ pub struct PipelineInputTx { } pub struct PipelineInputRx { + pub qc_rx: oneshot::Receiver>, pub rand_rx: oneshot::Receiver>, pub order_vote_rx: oneshot::Receiver<()>, pub order_proof_fut: TaskFuture<()>, @@ -145,6 +147,8 @@ pub struct PipelinedBlock { pipeline_tx: Arc>>, #[derivative(PartialEq = "ignore")] pipeline_abort_handle: Arc>>>, + #[derivative(PartialEq = "ignore")] + block_qc: Arc>>>, } impl Serialize for PipelinedBlock { @@ -286,6 +290,13 @@ impl PipelinedBlock { .take() .expect("pre_commit_result_rx missing.") } + + pub fn set_qc(&self, qc: Arc) { + *self.block_qc.lock() = Some(qc.clone()); + if let Some(tx) = self.pipeline_tx().lock().as_mut() { + tx.qc_tx.take().map(|tx| tx.send(qc)); + } + } } impl Debug for PipelinedBlock { @@ -317,6 +328,7 @@ impl PipelinedBlock { pipeline_futs: Arc::new(Mutex::new(None)), pipeline_tx: Arc::new(Mutex::new(None)), pipeline_abort_handle: Arc::new(Mutex::new(None)), + block_qc: Arc::new(Mutex::new(None)), } } @@ -422,6 +434,10 @@ impl PipelinedBlock { pub fn get_execution_summary(&self) -> Option { self.execution_summary.get().cloned() } + + pub fn qc(&self) -> Option> { + self.block_qc.lock().clone() + } } /// Pipeline related functions diff --git a/consensus/src/block_preparer.rs b/consensus/src/block_preparer.rs index aa3d82706f32d..5db76e27ef47e 100644 --- a/consensus/src/block_preparer.rs +++ b/consensus/src/block_preparer.rs @@ -8,11 +8,12 @@ use crate::{ transaction_filter::TransactionFilter, transaction_shuffler::TransactionShuffler, }; -use aptos_consensus_types::block::Block; +use aptos_consensus_types::{block::Block, quorum_cert::QuorumCert}; use aptos_executor_types::ExecutorResult; use aptos_types::transaction::SignedTransaction; use fail::fail_point; -use std::{sync::Arc, time::Instant}; +use futures::future::Shared; +use std::{future::Future, sync::Arc, time::Instant}; pub struct BlockPreparer { payload_manager: Arc, @@ -36,7 +37,11 @@ impl BlockPreparer { } } - pub async fn prepare_block(&self, block: &Block) -> ExecutorResult> { + pub async fn prepare_block( + &self, + block: &Block, + block_qc_fut: Shared>>>, + ) -> ExecutorResult> { fail_point!("consensus::prepare_block", |_| { use aptos_executor_types::ExecutorError; use std::{thread, time::Duration}; @@ -44,8 +49,17 @@ impl BlockPreparer { Err(ExecutorError::CouldNotGetData) }); let start_time = Instant::now(); - let (txns, max_txns_from_block_to_execute) = - self.payload_manager.get_transactions(block).await?; + + let (txns, max_txns_from_block_to_execute) = tokio::select! { + // Poll the block qc future until a QC is received. Ignore None outcomes. + Some(qc) = block_qc_fut => { + let block_voters = Some(qc.ledger_info().get_voters_bitvec().clone()); + self.payload_manager.get_transactions(block, block_voters).await + }, + result = self.payload_manager.get_transactions(block, None) => { + result + } + }?; let txn_filter = self.txn_filter.clone(); let txn_deduper = self.txn_deduper.clone(); let txn_shuffler = self.txn_shuffler.clone(); diff --git a/consensus/src/block_storage/block_store.rs b/consensus/src/block_storage/block_store.rs index b8c8146121e0a..9e223e252a63d 100644 --- a/consensus/src/block_storage/block_store.rs +++ b/consensus/src/block_storage/block_store.rs @@ -449,6 +449,7 @@ impl BlockStore { pipelined_block.block().timestamp_usecs(), BlockStage::QC_ADDED, ); + pipelined_block.set_qc(Arc::new(qc.clone())); }, None => bail!("Insert {} without having the block in store first", qc), }; @@ -524,7 +525,8 @@ impl BlockStore { pub async fn wait_for_payload(&self, block: &Block, deadline: Duration) -> anyhow::Result<()> { let duration = deadline.saturating_sub(self.time_service.get_current_timestamp()); - tokio::time::timeout(duration, self.payload_manager.get_transactions(block)).await??; + tokio::time::timeout(duration, self.payload_manager.get_transactions(block, None)) + .await??; Ok(()) } diff --git a/consensus/src/consensusdb/mod.rs b/consensus/src/consensusdb/mod.rs index 6f9e8eab8f786..d9b80a9c948a0 100644 --- a/consensus/src/consensusdb/mod.rs +++ b/consensus/src/consensusdb/mod.rs @@ -11,7 +11,7 @@ use anyhow::Result; use aptos_consensus_types::{block::Block, quorum_cert::QuorumCert}; use aptos_crypto::HashValue; use aptos_logger::prelude::*; -use aptos_schemadb::{schema::Schema, Options, SchemaBatch, DB, DEFAULT_COLUMN_FAMILY_NAME}; +use aptos_schemadb::{batch::SchemaBatch, schema::Schema, Options, DB, DEFAULT_COLUMN_FAMILY_NAME}; use aptos_storage_interface::AptosDbError; pub use schema::{ block::BlockSchema, @@ -107,14 +107,14 @@ impl ConsensusDB { } pub fn save_highest_2chain_timeout_certificate(&self, tc: Vec) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch.put::(&SingleEntryKey::Highest2ChainTimeoutCert, &tc)?; self.commit(batch)?; Ok(()) } pub fn save_vote(&self, last_vote: Vec) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch.put::(&SingleEntryKey::LastVote, &last_vote)?; self.commit(batch) } @@ -127,7 +127,7 @@ impl ConsensusDB { if block_data.is_empty() && qc_data.is_empty() { return Err(anyhow::anyhow!("Consensus block and qc data is empty!").into()); } - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); block_data .iter() .try_for_each(|block| batch.put::(&block.id(), block))?; @@ -144,7 +144,7 @@ impl ConsensusDB { if block_ids.is_empty() { return Err(anyhow::anyhow!("Consensus block ids is empty!").into()); } - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); block_ids.iter().try_for_each(|hash| { batch.delete::(hash)?; batch.delete::(hash) @@ -167,7 +167,7 @@ impl ConsensusDB { } pub fn delete_highest_2chain_timeout_certificate(&self) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch.delete::(&SingleEntryKey::Highest2ChainTimeoutCert)?; self.commit(batch) } @@ -180,21 +180,21 @@ impl ConsensusDB { } pub fn delete_last_vote_msg(&self) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch.delete::(&SingleEntryKey::LastVote)?; self.commit(batch)?; Ok(()) } pub fn put(&self, key: &S::Key, value: &S::Value) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch.put::(key, value)?; self.commit(batch)?; Ok(()) } pub fn delete(&self, keys: Vec) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); keys.iter().try_for_each(|key| batch.delete::(key))?; self.commit(batch) } diff --git a/consensus/src/dag/tests/helpers.rs b/consensus/src/dag/tests/helpers.rs index dab407099c303..281ace993dc0d 100644 --- a/consensus/src/dag/tests/helpers.rs +++ b/consensus/src/dag/tests/helpers.rs @@ -34,6 +34,7 @@ impl TPayloadManager for MockPayloadManager { async fn get_transactions( &self, _block: &Block, + _block_signers: Option, ) -> ExecutorResult<(Vec, Option)> { Ok((Vec::new(), None)) } diff --git a/consensus/src/epoch_manager.rs b/consensus/src/epoch_manager.rs index a1be0f289de64..14ed035334525 100644 --- a/consensus/src/epoch_manager.rs +++ b/consensus/src/epoch_manager.rs @@ -699,7 +699,6 @@ impl EpochManager

{ network_sender, epoch_state.verifier.clone(), self.proof_cache.clone(), - self.config.safety_rules.backend.clone(), self.quorum_store_storage.clone(), !consensus_config.is_dag_enabled(), consensus_key, diff --git a/consensus/src/execution_pipeline.rs b/consensus/src/execution_pipeline.rs index 6cb016fa02158..2836022fec75c 100644 --- a/consensus/src/execution_pipeline.rs +++ b/consensus/src/execution_pipeline.rs @@ -10,7 +10,9 @@ use crate::{ pipeline::pipeline_phase::CountedRequest, state_computer::StateComputeResultFut, }; -use aptos_consensus_types::{block::Block, pipeline_execution_result::PipelineExecutionResult}; +use aptos_consensus_types::{ + block::Block, pipeline_execution_result::PipelineExecutionResult, quorum_cert::QuorumCert, +}; use aptos_crypto::HashValue; use aptos_executor_types::{ state_compute_result::StateComputeResult, BlockExecutorTrait, ExecutorError, ExecutorResult, @@ -25,7 +27,7 @@ use aptos_types::{ }, }; use fail::fail_point; -use futures::future::BoxFuture; +use futures::{future::BoxFuture, FutureExt}; use once_cell::sync::Lazy; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; use std::{ @@ -92,6 +94,7 @@ impl ExecutionPipeline { block: Block, metadata: BlockMetadataExt, parent_block_id: HashValue, + block_qc: Option>, txn_generator: BlockPreparer, block_executor_onchain_config: BlockExecutorConfigFromOnchain, pre_commit_hook: PreCommitHook, @@ -110,6 +113,7 @@ impl ExecutionPipeline { command_creation_time: Instant::now(), pre_commit_hook, lifetime_guard, + block_qc, }) .expect("Failed to send block to execution pipeline."); @@ -139,10 +143,13 @@ impl ExecutionPipeline { result_tx, command_creation_time, lifetime_guard, + block_qc, } = command; counters::PREPARE_BLOCK_WAIT_TIME.observe_duration(command_creation_time.elapsed()); debug!("prepare_block received block {}.", block.id()); - let input_txns = block_preparer.prepare_block(&block).await; + let input_txns = block_preparer + .prepare_block(&block, async { block_qc }.shared()) + .await; if let Err(e) = input_txns { result_tx .send(Err(e)) @@ -226,7 +233,7 @@ impl ExecutionPipeline { }); let start = Instant::now(); executor - .execute_and_state_checkpoint( + .execute_and_update_state( block, parent_block_id, block_executor_onchain_config, @@ -375,6 +382,7 @@ struct PrepareBlockCommand { result_tx: oneshot::Sender>, command_creation_time: Instant, lifetime_guard: CountedRequest<()>, + block_qc: Option>, } struct ExecuteBlockCommand { diff --git a/consensus/src/payload_manager.rs b/consensus/src/payload_manager.rs index 16f3e305ea585..86a537edb940b 100644 --- a/consensus/src/payload_manager.rs +++ b/consensus/src/payload_manager.rs @@ -56,6 +56,7 @@ pub trait TPayloadManager: Send + Sync { async fn get_transactions( &self, block: &Block, + block_voters: Option, ) -> ExecutorResult<(Vec, Option)>; } @@ -81,6 +82,7 @@ impl TPayloadManager for DirectMempoolPayloadManager { async fn get_transactions( &self, block: &Block, + _block_signers: Option, ) -> ExecutorResult<(Vec, Option)> { let Some(payload) = block.payload() else { return Ok((Vec::new(), None)); @@ -126,7 +128,7 @@ impl QuorumStorePayloadManager { } fn request_transactions( - batches: Vec<(BatchInfo, Vec)>, + batches: Vec<(BatchInfo, Arc>>)>, block_timestamp: u64, batch_reader: Arc, ) -> Vec<( @@ -146,7 +148,7 @@ impl QuorumStorePayloadManager { batch_reader.get_batch( *batch_info.digest(), batch_info.expiration(), - responders, + responders.clone(), ), )); } else { @@ -226,7 +228,7 @@ impl TPayloadManager for QuorumStorePayloadManager { .map(|proof| { ( proof.info().clone(), - proof.shuffled_signers(&self.ordered_authors), + Arc::new(Mutex::new(proof.shuffled_signers(&self.ordered_authors))), ) }) .collect(), @@ -250,20 +252,25 @@ impl TPayloadManager for QuorumStorePayloadManager { return; } - let batches_and_responders = data_pointer + let (batches_and_responders, responders) = data_pointer .batch_summary .iter() .map(|proof| { let signers = proof.signers(ordered_authors); + let responders = Arc::new(Mutex::new(signers)); // TODO(ibalajiarun): Add block author to signers - (proof.info().clone(), signers) + ((proof.info().clone(), responders.clone()), responders) }) - .collect(); + .unzip(); let fut = request_txns_from_quorum_store(batches_and_responders, timestamp, batch_reader) .boxed() .shared(); - *data_fut = Some(DataFetchFut { fut, iteration: 0 }) + *data_fut = Some(DataFetchFut { + fut, + iteration: 0, + responders, + }) } match payload { @@ -381,6 +388,7 @@ impl TPayloadManager for QuorumStorePayloadManager { async fn get_transactions( &self, block: &Block, + block_signers: Option, ) -> ExecutorResult<(Vec, Option)> { let Some(payload) = block.payload() else { return Ok((Vec::new(), None)); @@ -388,7 +396,7 @@ impl TPayloadManager for QuorumStorePayloadManager { let transaction_payload = match payload { Payload::InQuorumStore(proof_with_data) => { - let transactions = process_payload( + let transactions = process_qs_payload( proof_with_data, self.batch_reader.clone(), block, @@ -401,7 +409,7 @@ impl TPayloadManager for QuorumStorePayloadManager { ) }, Payload::InQuorumStoreWithLimit(proof_with_data) => { - let transactions = process_payload( + let transactions = process_qs_payload( &proof_with_data.proof_with_data, self.batch_reader.clone(), block, @@ -420,7 +428,7 @@ impl TPayloadManager for QuorumStorePayloadManager { max_txns_to_execute, ) => { let all_transactions = { - let mut all_txns = process_payload( + let mut all_txns = process_qs_payload( proof_with_data, self.batch_reader.clone(), block, @@ -448,18 +456,20 @@ impl TPayloadManager for QuorumStorePayloadManager { ) }, Payload::OptQuorumStore(opt_qs_payload) => { - let opt_batch_txns = process_payload_helper( + let opt_batch_txns = process_optqs_payload( opt_qs_payload.opt_batches(), self.batch_reader.clone(), block, &self.ordered_authors, + block_signers.as_ref(), ) .await?; - let proof_batch_txns = process_payload_helper( + let proof_batch_txns = process_optqs_payload( opt_qs_payload.proof_with_data(), self.batch_reader.clone(), block, &self.ordered_authors, + None, ) .await?; let inline_batch_txns = opt_qs_payload.inline_batches().transactions(); @@ -549,7 +559,7 @@ async fn get_transactions_for_observer( } async fn request_txns_from_quorum_store( - batches_and_responders: Vec<(BatchInfo, Vec)>, + batches_and_responders: Vec<(BatchInfo, Arc>>)>, timestamp: u64, batch_reader: Arc, ) -> ExecutorResult> { @@ -581,44 +591,72 @@ async fn request_txns_from_quorum_store( Ok(ret) } -async fn process_payload_helper( +async fn process_optqs_payload( data_ptr: &BatchPointer, batch_reader: Arc, block: &Block, ordered_authors: &[PeerId], + additional_peers_to_request: Option<&BitVec>, ) -> ExecutorResult> { - let (iteration, fut) = { + let (iteration, fut, existing_responders) = { let data_fut_guard = data_ptr.data_fut.lock(); let data_fut = data_fut_guard.as_ref().expect("must be initialized"); - (data_fut.iteration, data_fut.fut.clone()) + ( + data_fut.iteration, + data_fut.fut.clone(), + data_fut.responders.clone(), + ) }; + let mut signers = Vec::new(); + if let Some(peers) = additional_peers_to_request { + for i in peers.iter_ones() { + if let Some(author) = ordered_authors.get(i) { + signers.push(*author); + } + } + } + + // Append the additional peers to existing responders list + // NB: this might append the same signers multiple times, but this + // should be very rare and has no negative effects. + for responders in existing_responders { + responders.lock().append(&mut signers.clone()); + } + let result = fut.await; + // If error, reschedule before returning the result if result.is_err() { let mut data_fut_guard = data_ptr.data_fut.lock(); let data_fut = data_fut_guard.as_mut().expect("must be initialized"); // Protection against race, check the iteration number before rescheduling. if data_fut.iteration == iteration { - let batches_and_responders = data_ptr + let (batches_and_responders, responders) = data_ptr .batch_summary .iter() - .map(|proof| { - let mut signers = proof.signers(ordered_authors); + .map(|summary| { + let mut signers = signers.clone(); + signers.append(&mut summary.signers(ordered_authors)); if let Some(author) = block.author() { signers.push(author); } - (proof.info().clone(), signers) + let responders = Arc::new(Mutex::new(signers)); + + ((summary.info().clone(), responders.clone()), responders) }) - .collect(); - data_fut.fut = request_txns_from_quorum_store( - batches_and_responders, - block.timestamp_usecs(), - batch_reader, - ) - .boxed() - .shared(); - data_fut.iteration = iteration + 1; + .unzip(); + *data_fut = DataFetchFut { + fut: request_txns_from_quorum_store( + batches_and_responders, + block.timestamp_usecs(), + batch_reader, + ) + .boxed() + .shared(), + iteration: iteration + 1, + responders, + }; } } result @@ -626,7 +664,7 @@ async fn process_payload_helper( /// This is deprecated. Use `process_payload_helper` instead after migrating to /// OptQuorumStore payload -async fn process_payload( +async fn process_qs_payload( proof_with_data: &ProofWithData, batch_reader: Arc, block: &Block, @@ -667,7 +705,9 @@ async fn process_payload( .map(|proof| { ( proof.info().clone(), - proof.shuffled_signers(ordered_authors), + Arc::new(Mutex::new( + proof.shuffled_signers(ordered_authors), + )), ) }) .collect(), @@ -692,7 +732,9 @@ async fn process_payload( .map(|proof| { ( proof.info().clone(), - proof.shuffled_signers(ordered_authors), + Arc::new(Mutex::new( + proof.shuffled_signers(ordered_authors), + )), ) }) .collect(), @@ -753,6 +795,7 @@ impl TPayloadManager for ConsensusObserverPayloadManager { async fn get_transactions( &self, block: &Block, + _block_signers: Option, ) -> ExecutorResult<(Vec, Option)> { return get_transactions_for_observer(block, &self.txns_pool, &self.consensus_publisher) .await; diff --git a/consensus/src/pipeline/buffer_manager.rs b/consensus/src/pipeline/buffer_manager.rs index 8325c64feaab9..633fb9780b6f3 100644 --- a/consensus/src/pipeline/buffer_manager.rs +++ b/consensus/src/pipeline/buffer_manager.rs @@ -38,8 +38,7 @@ use aptos_network::protocols::{rpc::error::RpcError, wire::handshake::v1::Protoc use aptos_reliable_broadcast::{DropGuard, ReliableBroadcast}; use aptos_time_service::TimeService; use aptos_types::{ - account_address::AccountAddress, epoch_change::EpochChangeProof, epoch_state::EpochState, - ledger_info::LedgerInfoWithSignatures, + account_address::AccountAddress, epoch_state::EpochState, ledger_info::LedgerInfoWithSignatures, }; use bytes::Bytes; use fail::fail_point; @@ -544,12 +543,6 @@ impl BufferManager { })) .await .expect("Failed to send persist request"); - // this needs to be done after creating the persisting request to avoid it being lost - if commit_proof.ledger_info().ends_epoch() { - self.commit_msg_tx - .send_epoch_change(EpochChangeProof::new(vec![commit_proof], false)) - .await; - } info!("Advance head to {:?}", self.buffer.head_cursor()); self.previous_commit_time = Instant::now(); return; diff --git a/consensus/src/pipeline/decoupled_execution_utils.rs b/consensus/src/pipeline/decoupled_execution_utils.rs index 53e03beca995e..0fedc3eb5a82d 100644 --- a/consensus/src/pipeline/decoupled_execution_utils.rs +++ b/consensus/src/pipeline/decoupled_execution_utils.rs @@ -98,8 +98,9 @@ pub fn prepare_phases_and_buffer_manager( let (persisting_phase_request_tx, persisting_phase_request_rx) = create_channel::>(); let (persisting_phase_response_tx, persisting_phase_response_rx) = create_channel(); + let commit_msg_tx = Arc::new(commit_msg_tx); - let persisting_phase_processor = PersistingPhase::new(persisting_proxy); + let persisting_phase_processor = PersistingPhase::new(persisting_proxy, commit_msg_tx.clone()); let persisting_phase = PipelinePhase::new( persisting_phase_request_rx, Some(persisting_phase_response_tx), @@ -120,7 +121,7 @@ pub fn prepare_phases_and_buffer_manager( execution_wait_phase_response_rx, signing_phase_request_tx, signing_phase_response_rx, - Arc::new(commit_msg_tx), + commit_msg_tx, commit_msg_rx, persisting_phase_request_tx, persisting_phase_response_rx, diff --git a/consensus/src/pipeline/execution_schedule_phase.rs b/consensus/src/pipeline/execution_schedule_phase.rs index 42a673a0ea4a5..3a8d170e3151d 100644 --- a/consensus/src/pipeline/execution_schedule_phase.rs +++ b/consensus/src/pipeline/execution_schedule_phase.rs @@ -102,6 +102,7 @@ impl StatelessPipeline for ExecutionSchedulePhase { b.block(), b.parent_id(), b.randomness().cloned(), + b.qc(), lifetime_guard.spawn(()), ) .await; diff --git a/consensus/src/pipeline/persisting_phase.rs b/consensus/src/pipeline/persisting_phase.rs index a038c05db1672..68c7ef4b9e356 100644 --- a/consensus/src/pipeline/persisting_phase.rs +++ b/consensus/src/pipeline/persisting_phase.rs @@ -3,12 +3,13 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ + network::NetworkSender, pipeline::pipeline_phase::StatelessPipeline, state_replication::{StateComputer, StateComputerCommitCallBackType}, }; use aptos_consensus_types::{common::Round, pipelined_block::PipelinedBlock}; use aptos_executor_types::ExecutorResult; -use aptos_types::ledger_info::LedgerInfoWithSignatures; +use aptos_types::{epoch_change::EpochChangeProof, ledger_info::LedgerInfoWithSignatures}; use async_trait::async_trait; use std::{ fmt::{Debug, Display, Formatter}, @@ -46,11 +47,18 @@ pub type PersistingResponse = ExecutorResult; pub struct PersistingPhase { persisting_handle: Arc, + commit_msg_tx: Arc, } impl PersistingPhase { - pub fn new(persisting_handle: Arc) -> Self { - Self { persisting_handle } + pub fn new( + persisting_handle: Arc, + commit_msg_tx: Arc, + ) -> Self { + Self { + persisting_handle, + commit_msg_tx, + } } } @@ -68,7 +76,7 @@ impl StatelessPipeline for PersistingPhase { callback, } = req; - if blocks + let response = if blocks .last() .expect("Blocks can't be empty") .pipeline_enabled() @@ -86,9 +94,15 @@ impl StatelessPipeline for PersistingPhase { } else { let round = commit_ledger_info.ledger_info().round(); self.persisting_handle - .commit(&blocks, commit_ledger_info, callback) + .commit(&blocks, commit_ledger_info.clone(), callback) .await .map(|_| round) + }; + if commit_ledger_info.ledger_info().ends_epoch() { + self.commit_msg_tx + .send_epoch_change(EpochChangeProof::new(vec![commit_ledger_info], false)) + .await; } + response } } diff --git a/consensus/src/pipeline/pipeline_builder.rs b/consensus/src/pipeline/pipeline_builder.rs index a71f9927fed3c..85ddac2f87e37 100644 --- a/consensus/src/pipeline/pipeline_builder.rs +++ b/consensus/src/pipeline/pipeline_builder.rs @@ -4,8 +4,7 @@ use crate::{ block_preparer::BlockPreparer, block_storage::tracing::{observe_block, BlockStage}, - counters, - counters::{update_counters_for_block, update_counters_for_compute_result}, + counters::{self, update_counters_for_block, update_counters_for_compute_result}, execution_pipeline::SIG_VERIFY_POOL, monitor, payload_manager::TPayloadManager, @@ -23,6 +22,7 @@ use aptos_consensus_types::{ PipelineInputRx, PipelineInputTx, PipelinedBlock, PostCommitResult, PostLedgerUpdateResult, PostPreCommitResult, PreCommitResult, PrepareResult, TaskError, TaskFuture, TaskResult, }, + quorum_cert::QuorumCert, }; use aptos_crypto::HashValue; use aptos_executor_types::{state_compute_result::StateComputeResult, BlockExecutorTrait}; @@ -194,6 +194,7 @@ impl PipelineBuilder { } fn channel(abort_handles: &mut Vec) -> (PipelineInputTx, PipelineInputRx) { + let (qc_tx, qc_rx) = oneshot::channel(); let (rand_tx, rand_rx) = oneshot::channel(); let (order_vote_tx, order_vote_rx) = oneshot::channel(); let (order_proof_tx, order_proof_fut) = oneshot::channel(); @@ -216,12 +217,14 @@ impl PipelineBuilder { ); ( PipelineInputTx { + qc_tx: Some(qc_tx), rand_tx: Some(rand_tx), order_vote_tx: Some(order_vote_tx), order_proof_tx: Some(order_proof_tx), commit_proof_tx: Some(commit_proof_tx), }, PipelineInputRx { + qc_rx, rand_rx, order_vote_rx, order_proof_fut, @@ -289,6 +292,7 @@ impl PipelineBuilder { let mut abort_handles = vec![]; let (tx, rx) = Self::channel(&mut abort_handles); let PipelineInputRx { + qc_rx, rand_rx, order_vote_rx, order_proof_fut, @@ -296,7 +300,7 @@ impl PipelineBuilder { } = rx; let prepare_fut = spawn_shared_fut( - Self::prepare(self.block_preparer.clone(), block.clone()), + Self::prepare(self.block_preparer.clone(), block.clone(), qc_rx), &mut abort_handles, ); let execute_fut = spawn_shared_fut( @@ -406,12 +410,27 @@ impl PipelineBuilder { /// Precondition: Block is inserted into block tree (all ancestors are available) /// What it does: Wait for all data becomes available and verify transaction signatures - async fn prepare(preparer: Arc, block: Arc) -> TaskResult { + async fn prepare( + preparer: Arc, + block: Arc, + qc_rx: oneshot::Receiver>, + ) -> TaskResult { let mut tracker = Tracker::start_waiting("prepare", &block); tracker.start_working(); + + let qc_rx = async { + match qc_rx.await { + Ok(qc) => Some(qc), + Err(_) => { + warn!("[BlockPreparer] qc tx cancelled for block {}", block.id()); + None + }, + } + } + .shared(); // the loop can only be abort by the caller let input_txns = loop { - match preparer.prepare_block(&block).await { + match preparer.prepare_block(&block, qc_rx.clone()).await { Ok(input_txns) => break input_txns, Err(e) => { warn!( @@ -480,7 +499,7 @@ impl PipelineBuilder { let start = Instant::now(); tokio::task::spawn_blocking(move || { executor - .execute_and_state_checkpoint( + .execute_and_update_state( (block.id(), txns).into(), block.parent_id(), onchain_execution_config, diff --git a/consensus/src/quorum_store/batch_requester.rs b/consensus/src/quorum_store/batch_requester.rs index c7dfe6aeff0c1..322054402e6e5 100644 --- a/consensus/src/quorum_store/batch_requester.rs +++ b/consensus/src/quorum_store/batch_requester.rs @@ -12,6 +12,7 @@ use crate::{ use aptos_consensus_types::proof_of_store::BatchInfo; use aptos_crypto::HashValue; use aptos_executor_types::*; +use aptos_infallible::Mutex; use aptos_logger::prelude::*; use aptos_types::{transaction::SignedTransaction, validator_verifier::ValidatorVerifier, PeerId}; use futures::{stream::FuturesUnordered, StreamExt}; @@ -20,7 +21,7 @@ use std::{sync::Arc, time::Duration}; use tokio::{sync::oneshot, time}; struct BatchRequesterState { - signers: Vec, + signers: Arc>>, next_index: usize, ret_tx: oneshot::Sender>>, num_retries: usize, @@ -29,7 +30,7 @@ struct BatchRequesterState { impl BatchRequesterState { fn new( - signers: Vec, + signers: Arc>>, ret_tx: oneshot::Sender>>, retry_limit: usize, ) -> Self { @@ -43,25 +44,25 @@ impl BatchRequesterState { } fn next_request_peers(&mut self, num_peers: usize) -> Option> { + let signers = self.signers.lock(); if self.num_retries == 0 { let mut rng = rand::thread_rng(); // make sure nodes request from the different set of nodes - self.next_index = rng.gen::() % self.signers.len(); + self.next_index = rng.gen::() % signers.len(); counters::SENT_BATCH_REQUEST_COUNT.inc_by(num_peers as u64); } else { counters::SENT_BATCH_REQUEST_RETRY_COUNT.inc_by(num_peers as u64); } if self.num_retries < self.retry_limit { self.num_retries += 1; - let ret = self - .signers + let ret = signers .iter() .cycle() .skip(self.next_index) .take(num_peers) .cloned() .collect(); - self.next_index = (self.next_index + num_peers) % self.signers.len(); + self.next_index = (self.next_index + num_peers) % signers.len(); Some(ret) } else { None @@ -132,7 +133,7 @@ impl BatchRequester { &self, digest: HashValue, expiration: u64, - responders: Vec, + responders: Arc>>, ret_tx: oneshot::Sender>>, mut subscriber_rx: oneshot::Receiver, ) -> Option<(BatchInfo, Vec)> { diff --git a/consensus/src/quorum_store/batch_store.rs b/consensus/src/quorum_store/batch_store.rs index 523744c76749f..9c594ee228cb5 100644 --- a/consensus/src/quorum_store/batch_store.rs +++ b/consensus/src/quorum_store/batch_store.rs @@ -15,6 +15,7 @@ use anyhow::bail; use aptos_consensus_types::proof_of_store::{BatchInfo, SignedBatchInfo}; use aptos_crypto::{CryptoMaterialError, HashValue}; use aptos_executor_types::{ExecutorError, ExecutorResult}; +use aptos_infallible::Mutex; use aptos_logger::prelude::*; use aptos_types::{transaction::SignedTransaction, validator_signer::ValidatorSigner, PeerId}; use dashmap::{ @@ -26,7 +27,7 @@ use once_cell::sync::OnceCell; use std::{ sync::{ atomic::{AtomicU64, Ordering}, - Arc, Mutex, + Arc, }, time::Duration, }; @@ -309,10 +310,7 @@ impl BatchStore { // Add expiration for the inserted entry, no need to be atomic w. insertion. #[allow(clippy::unwrap_used)] { - self.expirations - .lock() - .unwrap() - .add_item(digest, expiration_time); + self.expirations.lock().add_item(digest, expiration_time); } Ok(true) } @@ -346,7 +344,7 @@ impl BatchStore { // after the expiration time. This will help remote peers fetch batches that just expired but are within their // execution window. let expiration_time = certified_time.saturating_sub(self.expiration_buffer_usecs); - let expired_digests = self.expirations.lock().unwrap().expire(expiration_time); + let expired_digests = self.expirations.lock().expire(expiration_time); let mut ret = Vec::new(); for h in expired_digests { let removed_value = match self.db_cache.entry(h) { @@ -497,7 +495,7 @@ pub trait BatchReader: Send + Sync { &self, digest: HashValue, expiration: u64, - signers: Vec, + signers: Arc>>, ) -> oneshot::Receiver>>; fn update_certified_timestamp(&self, certified_time: u64); @@ -529,7 +527,7 @@ impl BatchReader for Batch &self, digest: HashValue, expiration: u64, - signers: Vec, + signers: Arc>>, ) -> oneshot::Receiver>> { let (tx, rx) = oneshot::channel(); let batch_store = self.batch_store.clone(); diff --git a/consensus/src/quorum_store/quorum_store_builder.rs b/consensus/src/quorum_store/quorum_store_builder.rs index 73a4d4f49880e..e7878e82ee336 100644 --- a/consensus/src/quorum_store/quorum_store_builder.rs +++ b/consensus/src/quorum_store/quorum_store_builder.rs @@ -25,7 +25,7 @@ use crate::{ round_manager::VerifiedEvent, }; use aptos_channels::{aptos_channel, message_queues::QueueStyle}; -use aptos_config::config::{QuorumStoreConfig, SecureBackend}; +use aptos_config::config::QuorumStoreConfig; use aptos_consensus_types::{ common::Author, proof_of_store::ProofCache, request_response::GetPayloadCommand, }; @@ -129,7 +129,6 @@ pub struct InnerBuilder { network_sender: NetworkSender, verifier: Arc, proof_cache: ProofCache, - _backend: SecureBackend, coordinator_tx: Sender, coordinator_rx: Option>, batch_generator_cmd_tx: tokio::sync::mpsc::Sender, @@ -165,7 +164,6 @@ impl InnerBuilder { network_sender: NetworkSender, verifier: Arc, proof_cache: ProofCache, - backend: SecureBackend, quorum_store_storage: Arc, broadcast_proofs: bool, consensus_key: Arc, @@ -205,7 +203,6 @@ impl InnerBuilder { network_sender, verifier, proof_cache, - _backend: backend, coordinator_tx, coordinator_rx: Some(coordinator_rx), batch_generator_cmd_tx, diff --git a/consensus/src/quorum_store/quorum_store_db.rs b/consensus/src/quorum_store/quorum_store_db.rs index fccb002fc0b32..bc78d6ed456bb 100644 --- a/consensus/src/quorum_store/quorum_store_db.rs +++ b/consensus/src/quorum_store/quorum_store_db.rs @@ -12,7 +12,7 @@ use anyhow::Result; use aptos_consensus_types::proof_of_store::BatchId; use aptos_crypto::HashValue; use aptos_logger::prelude::*; -use aptos_schemadb::{Options, SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, Options, DB}; use std::{collections::HashMap, path::Path, time::Instant}; pub trait QuorumStoreStorage: Sync + Send { @@ -63,7 +63,7 @@ impl QuorumStoreDB { impl QuorumStoreStorage for QuorumStoreDB { fn delete_batches(&self, digests: Vec) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); for digest in digests.iter() { trace!("QS: db delete digest {}", digest); batch.delete::(digest)?; @@ -93,7 +93,7 @@ impl QuorumStoreStorage for QuorumStoreDB { } fn delete_batch_id(&self, epoch: u64) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch.delete::(&epoch)?; self.db.write_schemas(batch)?; Ok(()) diff --git a/consensus/src/quorum_store/tests/batch_requester_test.rs b/consensus/src/quorum_store/tests/batch_requester_test.rs index 33b63849e1940..148fd2278f063 100644 --- a/consensus/src/quorum_store/tests/batch_requester_test.rs +++ b/consensus/src/quorum_store/tests/batch_requester_test.rs @@ -13,6 +13,7 @@ use aptos_consensus_types::{ proof_of_store::{BatchId, ProofOfStore, SignedBatchInfo}, }; use aptos_crypto::HashValue; +use aptos_infallible::Mutex; use aptos_types::{ aggregate_signature::PartialSignatures, block_info::BlockInfo, @@ -21,7 +22,10 @@ use aptos_types::{ validator_verifier::{ValidatorConsensusInfo, ValidatorVerifier}, }; use move_core_types::account_address::AccountAddress; -use std::time::{Duration, Instant}; +use std::{ + sync::Arc, + time::{Duration, Instant}, +}; use tokio::sync::oneshot; #[derive(Clone)] @@ -98,7 +102,7 @@ async fn test_batch_request_exists() { .request_batch( *batch.digest(), batch.expiration(), - vec![AccountAddress::random()], + Arc::new(Mutex::new(vec![AccountAddress::random()])), tx, subscriber_rx, ) @@ -194,7 +198,7 @@ async fn test_batch_request_not_exists_not_expired() { .request_batch( *batch.digest(), batch.expiration(), - vec![AccountAddress::random()], + Arc::new(Mutex::new(vec![AccountAddress::random()])), tx, subscriber_rx, ) @@ -242,7 +246,7 @@ async fn test_batch_request_not_exists_expired() { .request_batch( *batch.digest(), batch.expiration(), - vec![AccountAddress::random()], + Arc::new(Mutex::new(vec![AccountAddress::random()])), tx, subscriber_rx, ) diff --git a/consensus/src/quorum_store/tests/proof_coordinator_test.rs b/consensus/src/quorum_store/tests/proof_coordinator_test.rs index 2fd9d36ac57f5..8ce920aa8c84c 100644 --- a/consensus/src/quorum_store/tests/proof_coordinator_test.rs +++ b/consensus/src/quorum_store/tests/proof_coordinator_test.rs @@ -13,6 +13,7 @@ use crate::{ use aptos_consensus_types::proof_of_store::{BatchId, SignedBatchInfo, SignedBatchInfoMsg}; use aptos_crypto::HashValue; use aptos_executor_types::ExecutorResult; +use aptos_infallible::Mutex; use aptos_types::{ transaction::SignedTransaction, validator_verifier::random_validator_verifier, PeerId, }; @@ -33,7 +34,7 @@ impl BatchReader for MockBatchReader { &self, _digest: HashValue, _expiration: u64, - _signers: Vec, + _signers: Arc>>, ) -> tokio::sync::oneshot::Receiver>> { unimplemented!() } diff --git a/consensus/src/rand/rand_gen/storage/db.rs b/consensus/src/rand/rand_gen/storage/db.rs index 9ef658212aa4d..02344d6e439d9 100644 --- a/consensus/src/rand/rand_gen/storage/db.rs +++ b/consensus/src/rand/rand_gen/storage/db.rs @@ -16,7 +16,7 @@ use crate::{ }; use anyhow::Result; use aptos_logger::info; -use aptos_schemadb::{schema::Schema, Options, SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, schema::Schema, Options, DB}; use std::{path::Path, sync::Arc, time::Instant}; pub struct RandDb { @@ -58,14 +58,14 @@ impl RandDb { } fn put(&self, key: &S::Key, value: &S::Value) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch.put::(key, value)?; self.commit(batch)?; Ok(()) } fn delete(&self, mut keys: impl Iterator) -> Result<(), DbError> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); keys.try_for_each(|key| batch.delete::(&key))?; self.commit(batch) } diff --git a/consensus/src/round_manager.rs b/consensus/src/round_manager.rs index 072a3a0f3c897..892c1ee7a4d27 100644 --- a/consensus/src/round_manager.rs +++ b/consensus/src/round_manager.rs @@ -1135,6 +1135,20 @@ impl RoundManager { pub async fn process_verified_proposal(&mut self, proposal: Block) -> anyhow::Result<()> { let proposal_round = proposal.round(); + let sync_info = self.block_store.sync_info(); + + if proposal_round <= sync_info.highest_round() { + sample!( + SampleRate::Duration(Duration::from_secs(1)), + warn!( + sync_info = sync_info, + proposal = proposal, + "Ignoring proposal. SyncInfo round is higher than proposal round." + ) + ); + return Ok(()); + } + let vote = self.create_vote(proposal).await?; self.round_state.record_vote(vote.clone()); let vote_msg = VoteMsg::new(vote.clone(), self.block_store.sync_info()); diff --git a/consensus/src/round_manager_test.rs b/consensus/src/round_manager_test.rs index 1123f33352919..292ddfe269ea8 100644 --- a/consensus/src/round_manager_test.rs +++ b/consensus/src/round_manager_test.rs @@ -482,6 +482,7 @@ impl NodeSetup { self.vote_queue.pop_front().unwrap() } + #[allow(unused)] pub async fn next_order_vote(&mut self) -> OrderVoteMsg { while self.order_vote_queue.is_empty() { self.next_network_message().await; diff --git a/consensus/src/state_computer.rs b/consensus/src/state_computer.rs index 498be4e87ea9a..a2a0ae732e198 100644 --- a/consensus/src/state_computer.rs +++ b/consensus/src/state_computer.rs @@ -21,7 +21,7 @@ use anyhow::Result; use aptos_consensus_notifications::ConsensusNotificationSender; use aptos_consensus_types::{ block::Block, common::Round, pipeline_execution_result::PipelineExecutionResult, - pipelined_block::PipelinedBlock, + pipelined_block::PipelinedBlock, quorum_cert::QuorumCert, }; use aptos_crypto::HashValue; use aptos_executor_types::{ @@ -228,6 +228,7 @@ impl StateComputer for ExecutionProxy { // The parent block id. parent_block_id: HashValue, randomness: Option, + block_qc: Option>, lifetime_guard: CountedRequest<()>, ) -> StateComputeResultFut { let block_id = block.id(); @@ -274,6 +275,7 @@ impl StateComputer for ExecutionProxy { block.clone(), metadata.clone(), parent_block_id, + block_qc, transaction_generator, block_executor_onchain_config, self.pre_commit_hook(), @@ -545,7 +547,7 @@ async fn test_commit_sync_race() { Ok(StateComputeResult::new_dummy()) } - fn execute_and_state_checkpoint( + fn execute_and_update_state( &self, _block: ExecutableBlock, _parent_block_id: HashValue, diff --git a/consensus/src/state_computer_tests.rs b/consensus/src/state_computer_tests.rs index 96af0cf89a6f6..aee28239087ef 100644 --- a/consensus/src/state_computer_tests.rs +++ b/consensus/src/state_computer_tests.rs @@ -112,7 +112,7 @@ impl BlockExecutorTrait for DummyBlockExecutor { Ok(()) } - fn execute_and_state_checkpoint( + fn execute_and_update_state( &self, block: ExecutableBlock, _parent_block_id: HashValue, @@ -198,7 +198,7 @@ async fn should_see_and_notify_validator_txns() { // Ensure the dummy executor has received the txns. let _ = execution_policy - .schedule_compute(&block, HashValue::zero(), None, dummy_guard()) + .schedule_compute(&block, HashValue::zero(), None, None, dummy_guard()) .await .await .unwrap(); diff --git a/consensus/src/state_replication.rs b/consensus/src/state_replication.rs index bbe171fc4e3e7..297a2178ee963 100644 --- a/consensus/src/state_replication.rs +++ b/consensus/src/state_replication.rs @@ -8,7 +8,9 @@ use crate::{ transaction_deduper::TransactionDeduper, transaction_shuffler::TransactionShuffler, }; use anyhow::Result; -use aptos_consensus_types::{block::Block, pipelined_block::PipelinedBlock}; +use aptos_consensus_types::{ + block::Block, pipelined_block::PipelinedBlock, quorum_cert::QuorumCert, +}; use aptos_crypto::HashValue; use aptos_executor_types::ExecutorResult; use aptos_types::{ @@ -32,6 +34,7 @@ pub trait StateComputer: Send + Sync { // The parent block root hash. _parent_block_id: HashValue, _randomness: Option, + _block_qc: Option>, _lifetime_guard: CountedRequest<()>, ) -> StateComputeResultFut { unimplemented!(); diff --git a/consensus/src/test_utils/mock_execution_client.rs b/consensus/src/test_utils/mock_execution_client.rs index 24594f2460124..d957449ed883f 100644 --- a/consensus/src/test_utils/mock_execution_client.rs +++ b/consensus/src/test_utils/mock_execution_client.rs @@ -75,8 +75,10 @@ impl MockExecutionClient { .lock() .remove(&block.id()) .ok_or_else(|| format_err!("Cannot find block"))?; - let (mut payload_txns, _max_txns_from_block_to_execute) = - self.payload_manager.get_transactions(block.block()).await?; + let (mut payload_txns, _max_txns_from_block_to_execute) = self + .payload_manager + .get_transactions(block.block(), None) + .await?; txns.append(&mut payload_txns); } // they may fail during shutdown diff --git a/consensus/src/test_utils/mock_state_computer.rs b/consensus/src/test_utils/mock_state_computer.rs index ff620acb8a0bb..5b9c65af200a4 100644 --- a/consensus/src/test_utils/mock_state_computer.rs +++ b/consensus/src/test_utils/mock_state_computer.rs @@ -14,7 +14,7 @@ use crate::{ use anyhow::{anyhow, Result}; use aptos_consensus_types::{ block::Block, pipeline_execution_result::PipelineExecutionResult, - pipelined_block::PipelinedBlock, + pipelined_block::PipelinedBlock, quorum_cert::QuorumCert, }; use aptos_crypto::HashValue; use aptos_executor_types::{ @@ -125,6 +125,7 @@ impl StateComputer for RandomComputeResultStateComputer { _block: &Block, parent_block_id: HashValue, _randomness: Option, + _block_qc: Option>, _lifetime_guard: CountedRequest<()>, ) -> StateComputeResultFut { // trapdoor for Execution Error diff --git a/crates/aptos-crypto/src/hash.rs b/crates/aptos-crypto/src/hash.rs index 8fe9ec701b6f6..5517f2ca4abd9 100644 --- a/crates/aptos-crypto/src/hash.rs +++ b/crates/aptos-crypto/src/hash.rs @@ -679,6 +679,11 @@ pub static ACCUMULATOR_PLACEHOLDER_HASH: Lazy = pub static SPARSE_MERKLE_PLACEHOLDER_HASH: Lazy = Lazy::new(|| create_literal_hash("SPARSE_MERKLE_PLACEHOLDER_HASH")); +/// Useful at places where we have to set a hash value for placeholder before +/// knowing the actual hash. +pub static CORRUPTION_SENTINEL: Lazy = + Lazy::new(|| create_literal_hash("CORRUPTION_SENTINEL")); + /// Placeholder hash of hot state tier Merkle Tree. pub static HOT_STATE_PLACE_HOLDER_HASH: Lazy = Lazy::new(|| create_literal_hash("HOT_STATE_PLACEHOLDER_HASH")); diff --git a/crates/aptos-drop-helper/src/lib.rs b/crates/aptos-drop-helper/src/lib.rs index c923742322bdb..c86a305507ba7 100644 --- a/crates/aptos-drop-helper/src/lib.rs +++ b/crates/aptos-drop-helper/src/lib.rs @@ -25,11 +25,19 @@ pub trait ArcAsyncDrop: Send + Sync + 'static {} impl ArcAsyncDrop for T {} -#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DropHelper { inner: Option, } +impl Default for DropHelper { + fn default() -> Self { + Self { + inner: Some(T::default()), + } + } +} + impl DropHelper { pub fn new(inner: T) -> Self { Self { inner: Some(inner) } diff --git a/crates/aptos-genesis/src/builder.rs b/crates/aptos-genesis/src/builder.rs index 01921473e7c9b..c3440d5cee217 100644 --- a/crates/aptos-genesis/src/builder.rs +++ b/crates/aptos-genesis/src/builder.rs @@ -444,7 +444,7 @@ pub struct GenesisConfiguration { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub initial_jwks: Vec, - pub keyless_groth16_vk_override: Option, + pub keyless_groth16_vk: Option, } pub type InitConfigFn = Arc; @@ -667,7 +667,7 @@ impl Builder { randomness_config_override: None, jwk_consensus_config_override: None, initial_jwks: vec![], - keyless_groth16_vk_override: None, + keyless_groth16_vk: None, }; if let Some(init_genesis_config) = &self.init_genesis_config { (init_genesis_config)(&mut genesis_config); diff --git a/crates/aptos-genesis/src/lib.rs b/crates/aptos-genesis/src/lib.rs index 8fed37e85cfa6..bcce6731f1e16 100644 --- a/crates/aptos-genesis/src/lib.rs +++ b/crates/aptos-genesis/src/lib.rs @@ -79,7 +79,7 @@ pub struct GenesisInfo { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub initial_jwks: Vec, - pub keyless_groth16_vk_override: Option, + pub keyless_groth16_vk: Option, } impl GenesisInfo { @@ -120,7 +120,7 @@ impl GenesisInfo { randomness_config_override: genesis_config.randomness_config_override.clone(), jwk_consensus_config_override: genesis_config.jwk_consensus_config_override.clone(), initial_jwks: genesis_config.initial_jwks.clone(), - keyless_groth16_vk_override: genesis_config.keyless_groth16_vk_override.clone(), + keyless_groth16_vk: genesis_config.keyless_groth16_vk.clone(), }) } @@ -157,7 +157,7 @@ impl GenesisInfo { randomness_config_override: self.randomness_config_override.clone(), jwk_consensus_config_override: self.jwk_consensus_config_override.clone(), initial_jwks: self.initial_jwks.clone(), - keyless_groth16_vk_override: self.keyless_groth16_vk_override.clone(), + keyless_groth16_vk: self.keyless_groth16_vk.clone(), }, &self.consensus_config, &self.execution_config, diff --git a/crates/aptos-genesis/src/mainnet.rs b/crates/aptos-genesis/src/mainnet.rs index 37ece1845d719..e78e619694ee2 100644 --- a/crates/aptos-genesis/src/mainnet.rs +++ b/crates/aptos-genesis/src/mainnet.rs @@ -144,7 +144,7 @@ impl MainnetGenesisInfo { randomness_config_override: self.randomness_config_override.clone(), jwk_consensus_config_override: self.jwk_consensus_config_override.clone(), initial_jwks: vec![], - keyless_groth16_vk_override: None, + keyless_groth16_vk: None, }, ) } diff --git a/crates/aptos-localnet/Cargo.toml b/crates/aptos-localnet/Cargo.toml index 370ddebccdf73..2ba3067a361c0 100644 --- a/crates/aptos-localnet/Cargo.toml +++ b/crates/aptos-localnet/Cargo.toml @@ -26,7 +26,7 @@ diesel = { workspace = true, features = [ "postgres_backend", ] } diesel-async = { workspace = true } -processor = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "51a34901b40d7f75767ac907b4d2478104d6a515", default-features = false } +processor = { workspace = true } reqwest = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/crates/aptos-localnet/src/hasura_metadata.json b/crates/aptos-localnet/src/hasura_metadata.json index d5f1a87a594c9..c07f8dc421c13 100644 --- a/crates/aptos-localnet/src/hasura_metadata.json +++ b/crates/aptos-localnet/src/hasura_metadata.json @@ -2327,6 +2327,9 @@ "columns": [ "block_height", "entry_function_id_str", + "entry_function_contract_address", + "entry_function_module_name", + "entry_function_function_name", "epoch", "expiration_timestamp_secs", "gas_unit_price", diff --git a/crates/aptos-localnet/src/processors.rs b/crates/aptos-localnet/src/processors.rs index 350de43e2d667..276e2b85be293 100644 --- a/crates/aptos-localnet/src/processors.rs +++ b/crates/aptos-localnet/src/processors.rs @@ -33,6 +33,9 @@ pub fn get_processor_config(processor_name: &ProcessorName) -> Result { bail!("ParquetDefaultProcessor is not supported in the localnet") }, + ProcessorName::ParquetFungibleAssetActivitiesProcessor => { + bail!("ParquetFungibleAssetActivitiesProcessor is not supported in the localnet") + }, ProcessorName::ParquetFungibleAssetProcessor => { bail!("ParquetFungibleAssetProcessor is not supported in the localnet") }, @@ -48,6 +51,9 @@ pub fn get_processor_config(processor_name: &ProcessorName) -> Result { bail!("ParquetTokenV2Processor is not supported in the localnet") }, + ProcessorName::ParquetUserTransactionsProcessor => { + bail!("ParquetUserTransactionsProcessor is not supported in the localnet") + }, ProcessorName::StakeProcessor => ProcessorConfig::StakeProcessor(StakeProcessorConfig { query_retries: Default::default(), query_retry_delay_ms: Default::default(), diff --git a/crates/aptos-metrics-core/src/const_metric.rs b/crates/aptos-metrics-core/src/const_metric.rs index 744ff1b7c989c..c354b0eed4921 100644 --- a/crates/aptos-metrics-core/src/const_metric.rs +++ b/crates/aptos-metrics-core/src/const_metric.rs @@ -37,7 +37,7 @@ impl ConstMetric { let mut metric = Metric::default(); metric.set_counter(counter); - metric.set_label(labels.into()); + metric.set_label(labels); Ok(ConstMetric { desc, @@ -63,7 +63,7 @@ impl ConstMetric { let mut metric = Metric::default(); metric.set_gauge(guage); - metric.set_label(labels.into()); + metric.set_label(labels); Ok(ConstMetric { desc, @@ -84,7 +84,7 @@ impl Collector for ConstMetric { met.set_name(self.desc.fq_name.clone()); met.set_help(self.desc.help.clone()); met.set_field_type(self.metric_type); - met.set_metric(vec![self.metric.clone()].into()); + met.set_metric(vec![self.metric.clone()]); vec![met] } diff --git a/crates/aptos-push-metrics/Cargo.toml b/crates/aptos-push-metrics/Cargo.toml index 279be31dc0e5c..e77bae668547d 100644 --- a/crates/aptos-push-metrics/Cargo.toml +++ b/crates/aptos-push-metrics/Cargo.toml @@ -15,5 +15,6 @@ rust-version = { workspace = true } [dependencies] aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } +rand = { workspace = true } ureq = { workspace = true } url = { workspace = true } diff --git a/crates/aptos-push-metrics/src/lib.rs b/crates/aptos-push-metrics/src/lib.rs index 92896d7ef5f59..c9984a66e6d53 100644 --- a/crates/aptos-push-metrics/src/lib.rs +++ b/crates/aptos-push-metrics/src/lib.rs @@ -164,6 +164,7 @@ impl MetricsPusher { "metrics_source=unknown".into(), "kubernetes_pod_name=unknown".into(), "role=unknown".into(), + format!("run_uuid={:x}", rand::random::()), format!("namespace={}", namespace), ] } diff --git a/crates/aptos/CHANGELOG.md b/crates/aptos/CHANGELOG.md index ab9da71f870a0..adb5a136dda17 100644 --- a/crates/aptos/CHANGELOG.md +++ b/crates/aptos/CHANGELOG.md @@ -3,18 +3,26 @@ All notable changes to the Aptos CLI will be captured in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and the format set out by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). # Unreleased + +## [6.0.1] - 2025/01/17 +- Update Hasura metadata to include `entry_function_contract_address`, `entry_function_module_name`, and `entry_function_function_name` in `user_transactions` table. + +## [6.0.0] - 2025/01/14 +- Set Compiler v2 as the default compiler and Move 2 as the default language version. +- Add new `--move-1` flag to use Compiler v1 and Move 1. - Add flag `--benchmark` to `aptos move prove`, which allows to benchmark verification times of individual functions in a package. - Add flag `--only ` to `aptos move prove`, which allows to scope verification to a function. - Fix `aptos init` to show the explorer link for accounts when account is already created on chain instead of prompting to fund the account. - Set Compiler v2 as the default compiler and Move 2 as the default language version. - Add new `--move-1` flag to use Compiler v1 and Move 1. +- Upgrade indexer processors for localnet from 51a34901b40d7f75767ac907b4d2478104d6a515 to 3064a075e1abc06c60363f3f2551cc41f5c091de. Upgrade Hasura metadata accordingly. ## [5.1.0] - 2024/12/13 - More optimizations are now default for compiler v2. - Downgrade bytecode version to v6 before calling the Revela decompiler, if possible, i.e. no enum types are used. This allows to continue to use Revela until the new decompiler is ready. ## [5.0.0] - 2024/12/11 -- [**Breaking Change**] `aptos init` and `aptos account fund-with-faucet` no longer work directly with testnet, you must now use the minting page at the [Aptos dev docs](https://aptos.dev/network/faucet). +- [**Breaking Change**] `aptos init` and `aptos account fund-with-faucet` no longer work directly with testnet, you must now use the minting page at the [Aptos dev docs](https://aptos.dev/network/faucet). ## [4.7.0] - 2024/12/10 - [`Fix`] CLI config should not always require a private key field to be present. @@ -70,7 +78,7 @@ All notable changes to the Aptos CLI will be captured in this file. This project ## [4.1.0] - 2024/08/30 - Marks Move 2 and compiler v2 as stable. -- Adds new `--move-2` flag to work with Move 2 without need for multiple other flags. +- Adds new `--move-2` flag to work with Move 2 without need for multiple other flags. - Adds `aptos move lint` to produce lint warnings for the current package. Only a few lint rules are implemented for now, but more are coming. - Adds `aptos move fmt`, which runs the Move formatter, `movefmt`, on the current package. Also adds diff --git a/crates/aptos/Cargo.toml b/crates/aptos/Cargo.toml index feb0630e7fb79..0ccacca9b92f6 100644 --- a/crates/aptos/Cargo.toml +++ b/crates/aptos/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "aptos" description = "Aptos tool for management of nodes and interacting with the blockchain" -version = "5.1.0" +version = "6.0.1" # Workspace inherited keys authors = { workspace = true } @@ -90,9 +90,7 @@ move-vm-runtime = { workspace = true, features = ["testing"] } open = { workspace = true } pathsearch = { workspace = true } poem = { workspace = true } -# We set default-features to false so we don't onboard the libpq dep. See more here: -# https://github.com/aptos-labs/aptos-core/pull/12568 -processor = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "51a34901b40d7f75767ac907b4d2478104d6a515", default-features = false } +processor = { workspace = true } rand = { workspace = true } regex = { workspace = true } reqwest = { workspace = true } @@ -100,7 +98,7 @@ self_update = { git = "https://github.com/banool/self_update.git", rev = "830615 serde = { workspace = true } serde_json = { workspace = true } serde_yaml = { workspace = true } -server-framework = { git = "https://github.com/aptos-labs/aptos-indexer-processors.git", rev = "51a34901b40d7f75767ac907b4d2478104d6a515" } +server-framework = { workspace = true } set_env = { workspace = true } tempfile = { workspace = true } thiserror = { workspace = true } diff --git a/crates/aptos/src/common/types.rs b/crates/aptos/src/common/types.rs index 9667831e814f5..5443a9a936be9 100644 --- a/crates/aptos/src/common/types.rs +++ b/crates/aptos/src/common/types.rs @@ -1608,7 +1608,7 @@ impl FaucetOptions { } /// Gas price options for manipulating how to prioritize transactions -#[derive(Debug, Eq, Parser, PartialEq)] +#[derive(Debug, Clone, Eq, Parser, PartialEq)] pub struct GasOptions { /// Gas multiplier per unit of gas /// diff --git a/crates/aptos/src/genesis/mod.rs b/crates/aptos/src/genesis/mod.rs index 001f9ae1a93ca..5e5fcca4d8ea6 100644 --- a/crates/aptos/src/genesis/mod.rs +++ b/crates/aptos/src/genesis/mod.rs @@ -261,7 +261,7 @@ pub fn fetch_mainnet_genesis_info(git_options: GitOptions) -> CliTypedResult CliTypedResult { + vec![Self::parse_abstraction_signature( + sig, + sender, + transaction_version, + transaction_block_height, + is_sender_primary, + multi_agent_index, + override_address, + )] + }, } } @@ -390,4 +402,29 @@ impl Signature { multi_sig_index: 0, } } + + fn parse_abstraction_signature( + _s: &APIAbstractionSignature, + sender: &String, + transaction_version: i64, + transaction_block_height: i64, + is_sender_primary: bool, + multi_agent_index: i64, + override_address: Option<&String>, + ) -> Self { + let signer = standardize_address(override_address.unwrap_or(sender)); + Self { + transaction_version, + transaction_block_height, + signer, + is_sender_primary, + type_: String::from("abstraction_signature"), + public_key: "Not implemented".into(), + threshold: 1, + public_key_indices: serde_json::Value::Array(vec![]), + signature: "Not implemented".into(), + multi_agent_index, + multi_sig_index: 0, + } + } } diff --git a/crates/transaction-emitter-lib/src/emitter/submission_worker.rs b/crates/transaction-emitter-lib/src/emitter/submission_worker.rs index 9563e78648b59..57832b81162ec 100644 --- a/crates/transaction-emitter-lib/src/emitter/submission_worker.rs +++ b/crates/transaction-emitter-lib/src/emitter/submission_worker.rs @@ -491,7 +491,27 @@ pub async fn submit_transactions( .counts(); if let Some(failure) = failures.first() { sample!(SampleRate::Duration(Duration::from_secs(60)), { - let sender = txns[failure.transaction_index].sender(); + let first_failed_txn = &txns[failure.transaction_index]; + let sender = first_failed_txn.sender(); + use aptos_types::transaction::TransactionPayload::*; + let payload = match first_failed_txn.payload() { + Script(_) => "script".to_string(), + ModuleBundle(_) => "module_bundle".to_string(), + EntryFunction(entry_function) => format!( + "entry {}::{}", + entry_function.module(), + entry_function.function() + ), + Multisig(_) => "multisig".to_string(), + }; + + let first_failed_txn_info = format!( + "due to {:?}, for account {}, max gas {}, payload {}", + failure, + first_failed_txn.sender(), + first_failed_txn.max_gas_amount(), + payload, + ); let last_transactions = if let Ok(account) = client.get_account_bcs(sender).await { @@ -513,11 +533,10 @@ pub async fn submit_transactions( .map_or(-1, |v| v.into_inner() as i64); warn!( - "[{:?}] Failed to submit {} txns in a batch, first failure due to {:?}, for account {}, chain id: {:?}, first asked: {}, failed seq nums: {:?}, failed error codes: {:?}, balance of {} and last transaction for account: {:?}", + "[{:?}] Failed to submit {} txns in a batch, first failure: {}, chain id: {:?}, first asked: {}, failed seq nums: {:?}, failed error codes: {:?}, balance of {} and last transaction for account: {:?}", client.path_prefix_string(), failures.len(), - failure, - sender, + first_failed_txn_info, txns[0].chain_id(), txns[0].sequence_number(), failures.iter().map(|f| txns[f.transaction_index].sequence_number()).collect::>(), diff --git a/crates/transaction-emitter-lib/src/emitter/transaction_executor.rs b/crates/transaction-emitter-lib/src/emitter/transaction_executor.rs index 27d87d6d1cd68..667aa1422982b 100644 --- a/crates/transaction-emitter-lib/src/emitter/transaction_executor.rs +++ b/crates/transaction-emitter-lib/src/emitter/transaction_executor.rs @@ -165,6 +165,17 @@ async fn warn_detailed_error( err: Result<&aptos_types::transaction::TransactionInfo, &RestError>, ) { let sender = txn.sender(); + use aptos_types::transaction::TransactionPayload::*; + let payload = match txn.payload() { + Script(_) => "script".to_string(), + ModuleBundle(_) => "module_bundle".to_string(), + EntryFunction(entry_function) => format!( + "entry {}::{}", + entry_function.module(), + entry_function.function() + ), + Multisig(_) => "multisig".to_string(), + }; let (last_transactions, seq_num) = if let Ok(account) = rest_client.get_account_bcs(sender).await { let inner = account.into_inner(); @@ -194,11 +205,12 @@ async fn warn_detailed_error( .map_or(-1, |v| v.into_inner() as i128); warn!( - "[{:?}] Failed {} transaction: {:?}, seq num: {}, gas: unit {} and max {}, for account {}, last seq_num {:?}, balance of {} and last transaction for account: {:?}", + "[{:?}] Failed {} transaction: {:?}, seq num: {}, payload: {}, gas: unit {} and max {}, for account {}, last seq_num {:?}, balance of {} and last transaction for account: {:?}", rest_client.path_prefix_string(), call_name, err, txn.sequence_number(), + payload, txn.gas_unit_price(), txn.max_gas_amount(), sender, diff --git a/crates/transaction-workloads-lib/src/args.rs b/crates/transaction-workloads-lib/src/args.rs index 402c4aeb3b54c..947982f0cbb72 100644 --- a/crates/transaction-workloads-lib/src/args.rs +++ b/crates/transaction-workloads-lib/src/args.rs @@ -78,6 +78,8 @@ pub enum TransactionTypeArg { SmartTablePicture1MWith1KChangeExceedsLimit, DeserializeU256, SimpleScript, + APTTransferWithPermissionedSigner, + APTTransferWithMasterSigner, } impl TransactionTypeArg { @@ -351,6 +353,12 @@ impl TransactionTypeArg { }, TransactionTypeArg::DeserializeU256 => call_custom_module(EntryPoints::DeserializeU256), TransactionTypeArg::SimpleScript => call_custom_module(EntryPoints::SimpleScript), + TransactionTypeArg::APTTransferWithPermissionedSigner => { + call_custom_module(EntryPoints::APTTransferWithPermissionedSigner) + }, + TransactionTypeArg::APTTransferWithMasterSigner => { + call_custom_module(EntryPoints::APTTransferWithMasterSigner) + }, } } diff --git a/crates/transaction-workloads-lib/src/move_workloads.rs b/crates/transaction-workloads-lib/src/move_workloads.rs index 8b5a191c55510..ba7628271652a 100644 --- a/crates/transaction-workloads-lib/src/move_workloads.rs +++ b/crates/transaction-workloads-lib/src/move_workloads.rs @@ -232,6 +232,10 @@ pub enum EntryPoints { /// there to slow down deserialization & verification, effectively making it more expensive to /// load it into code cache. SimpleScript, + /// Set up an APT transfer permission and transfering APT by using that permissioned signer. + APTTransferWithPermissionedSigner, + /// Transfer APT using vanilla master signer to compare the performance. + APTTransferWithMasterSigner, } impl EntryPointTrait for EntryPoints { @@ -284,7 +288,9 @@ impl EntryPointTrait for EntryPoints { | EntryPoints::ResourceGroupsSenderWriteTag { .. } | EntryPoints::ResourceGroupsSenderMultiChange { .. } | EntryPoints::CoinInitAndMint - | EntryPoints::FungibleAssetMint => "framework_usecases", + | EntryPoints::FungibleAssetMint + | EntryPoints::APTTransferWithPermissionedSigner + | EntryPoints::APTTransferWithMasterSigner => "framework_usecases", EntryPoints::TokenV2AmbassadorMint { .. } | EntryPoints::TokenV2AmbassadorBurn => { "ambassador_token" }, @@ -363,6 +369,8 @@ impl EntryPointTrait for EntryPoints { EntryPoints::IncGlobalMilestoneAggV2 { .. } | EntryPoints::CreateGlobalMilestoneAggV2 { .. } => "counter_with_milestone", EntryPoints::DeserializeU256 => "bcs_stream", + EntryPoints::APTTransferWithPermissionedSigner + | EntryPoints::APTTransferWithMasterSigner => "permissioned_transfer", } } @@ -781,6 +789,20 @@ impl EntryPointTrait for EntryPoints { ], ) }, + EntryPoints::APTTransferWithPermissionedSigner => get_payload( + module_id, + ident_str!("transfer_permissioned").to_owned(), + vec![ + bcs::to_bytes(&other.expect("Must provide other")).unwrap(), + bcs::to_bytes(&1u64).unwrap(), + ], + ), + EntryPoints::APTTransferWithMasterSigner => { + get_payload(module_id, ident_str!("transfer").to_owned(), vec![ + bcs::to_bytes(&other.expect("Must provide other")).unwrap(), + bcs::to_bytes(&1u64).unwrap(), + ]) + }, } } @@ -899,6 +921,8 @@ impl EntryPointTrait for EntryPoints { EntryPoints::DeserializeU256 => AutomaticArgs::None, EntryPoints::IncGlobalMilestoneAggV2 { .. } => AutomaticArgs::None, EntryPoints::CreateGlobalMilestoneAggV2 { .. } => AutomaticArgs::Signer, + EntryPoints::APTTransferWithPermissionedSigner + | EntryPoints::APTTransferWithMasterSigner => AutomaticArgs::Signer, } } } diff --git a/crates/transaction-workloads-lib/src/raw_module_data.rs b/crates/transaction-workloads-lib/src/raw_module_data.rs index a8d7050aac7ac..a3fe4f232be26 100644 --- a/crates/transaction-workloads-lib/src/raw_module_data.rs +++ b/crates/transaction-workloads-lib/src/raw_module_data.rs @@ -276,11 +276,11 @@ pub static MODULES_SIMPLE: Lazy>> = Lazy::new(|| { vec![ pub static PACKAGE_FRAMEWORK_USECASES_METADATA: Lazy> = Lazy::new(|| { vec![ 17, 70, 114, 97, 109, 101, 119, 111, 114, 107, 85, 115, 101, 99, 97, 115, 101, 115, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, 51, 68, 54, 69, 51, 48, 54, 53, - 54, 52, 67, 68, 68, 69, 68, 69, 57, 50, 53, 68, 69, 52, 55, 52, 52, 57, - 69, 67, 51, 66, 66, 53, 48, 67, 67, 67, 49, 56, 69, 70, 70, 66, 55, 56, - 53, 66, 49, 69, 57, 70, 52, 68, 49, 55, 56, 66, 50, 68, 68, 66, 65, 57, - 56, 51, 215, 1, 31, 139, 8, 0, 0, 0, 0, 0, 2, 255, 165, 144, 187, 142, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, 70, 49, 55, 49, 54, 53, 49, 70, + 66, 54, 55, 70, 70, 66, 51, 48, 70, 49, 65, 57, 53, 56, 67, 55, 52, 51, + 52, 51, 55, 55, 51, 55, 49, 48, 51, 68, 52, 68, 54, 50, 56, 55, 70, 67, + 55, 66, 56, 67, 52, 53, 65, 69, 51, 67, 56, 65, 56, 67, 51, 66, 65, 49, + 69, 66, 215, 1, 31, 139, 8, 0, 0, 0, 0, 0, 2, 255, 165, 144, 187, 142, 194, 64, 12, 69, 251, 249, 10, 107, 182, 38, 236, 15, 108, 193, 238, 138, 150, 6, 170, 8, 33, 51, 49, 33, 100, 176, 163, 241, 240, 144, 16, 255, 78, 44, 30, 130, 22, 100, 23, 215, 246, 189, 167, 112, 217, 97, 104, 177, 166, 185, 99, 220, 18, 252, @@ -292,28 +292,29 @@ pub static PACKAGE_FRAMEWORK_USECASES_METADATA: Lazy> = Lazy::new(|| { 134, 107, 160, 99, 88, 35, 215, 38, 101, 5, 65, 88, 51, 114, 6, 172, 170, 68, 170, 96, 20, 5, 236, 5, 197, 88, 184, 242, 182, 183, 231, 117, 187, 101, 108, 116, 77, 105, 113, 55, 219, 163, 143, 163, 223, 191, 127, 239, 46, 112, 10, 188, 112, 161, - 1, 0, 0, 8, 18, 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, 95, 101, 120, + 1, 0, 0, 9, 18, 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 12, 99, 111, 105, 110, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 22, 102, 117, 110, 103, 105, 98, 108, 101, 95, 97, 115, 115, 101, 116, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 12, 109, 97, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 7, 111, 98, 106, 101, 99, - 116, 115, 0, 0, 0, 23, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, 114, 111, - 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 8, 116, 111, 107, - 101, 110, 95, 118, 49, 0, 0, 0, 14, 118, 101, 99, 116, 111, 114, 95, 101, 120, - 97, 109, 112, 108, 101, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 116, 115, 0, 0, 0, 21, 112, 101, 114, 109, 105, 115, 115, 105, 111, 110, 101, 100, + 95, 116, 114, 97, 110, 115, 102, 101, 114, 0, 0, 0, 23, 114, 101, 115, 111, 117, + 114, 99, 101, 95, 103, 114, 111, 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, + 0, 0, 0, 8, 116, 111, 107, 101, 110, 95, 118, 49, 0, 0, 0, 14, 118, 101, + 99, 116, 111, 114, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 5, 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, 14, 65, 112, 116, 111, 115, + 70, 114, 97, 109, 101, 119, 111, 114, 107, 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, 14, 65, 112, 116, 111, 115, 70, 114, 97, 109, 101, 119, 111, - 114, 107, 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, 11, 65, - 112, 116, 111, 115, 83, 116, 100, 108, 105, 98, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 11, 65, 112, 116, 111, 115, 83, 116, 100, 108, 105, 98, 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, 10, 77, 111, 118, 101, 83, 116, 100, 108, 105, 98, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 77, 111, 118, 101, + 83, 116, 100, 108, 105, 98, 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, 3, 10, 65, 112, 116, 111, - 115, 84, 111, 107, 101, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 10, 65, 112, 116, 111, 115, 84, 111, 107, 101, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 17, 65, 112, 116, 111, 115, 84, 111, 107, 101, 110, 79, 98, 106, 101, 99, - 116, 115, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, 65, 112, 116, 111, 115, 84, 111, 107, + 101, 110, 79, 98, 106, 101, 99, 116, 115, 0, ] }); @@ -667,6 +668,24 @@ pub static MODULE_FRAMEWORK_USECASES_OBJECTS: Lazy> = Lazy::new(|| { ] }); +#[rustfmt::skip] +pub static MODULE_FRAMEWORK_USECASES_PERMISSIONED_TRANSFER: Lazy> = Lazy::new(|| { + vec![ + 161, 28, 235, 11, 7, 0, 0, 10, 7, 1, 0, 4, 3, 4, 12, 5, 16, 6, + 7, 22, 45, 8, 67, 64, 16, 131, 1, 31, 12, 162, 1, 15, 0, 0, 1, 2, + 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 3, 6, 12, 5, 3, 0, + 21, 112, 101, 114, 109, 105, 115, 115, 105, 111, 110, 101, 100, 95, 116, 114, 97, 110, + 115, 102, 101, 114, 8, 116, 114, 97, 110, 115, 102, 101, 114, 13, 97, 112, 116, 111, + 115, 95, 97, 99, 99, 111, 117, 110, 116, 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, 171, 205, 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, 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, 109, 101, 116, 97, + 100, 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, 0, 1, 4, 0, + 1, 5, 11, 0, 11, 1, 11, 2, 17, 1, 2, 0, + ] +}); + #[rustfmt::skip] pub static MODULE_FRAMEWORK_USECASES_RESOURCE_GROUPS_EXAMPLE: Lazy> = Lazy::new(|| { vec![ @@ -1036,6 +1055,7 @@ pub static MODULES_FRAMEWORK_USECASES: Lazy>> = Lazy::new(|| { vec![ MODULE_FRAMEWORK_USECASES_FUNGIBLE_ASSET_EXAMPLE.to_vec(), MODULE_FRAMEWORK_USECASES_MAPS_EXAMPLE.to_vec(), MODULE_FRAMEWORK_USECASES_OBJECTS.to_vec(), + MODULE_FRAMEWORK_USECASES_PERMISSIONED_TRANSFER.to_vec(), MODULE_FRAMEWORK_USECASES_RESOURCE_GROUPS_EXAMPLE.to_vec(), MODULE_FRAMEWORK_USECASES_TOKEN_V1.to_vec(), MODULE_FRAMEWORK_USECASES_VECTOR_EXAMPLE.to_vec(), diff --git a/ecosystem/indexer-grpc/indexer-grpc-data-service/src/config.rs b/ecosystem/indexer-grpc/indexer-grpc-data-service/src/config.rs index d2bb21e3ade49..f437f5e968ca2 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-data-service/src/config.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-data-service/src/config.rs @@ -147,7 +147,7 @@ impl RunnableConfig for IndexerGrpcDataServiceConfig { .register_encoded_file_descriptor_set(INDEXER_V1_FILE_DESCRIPTOR_SET) .register_encoded_file_descriptor_set(TRANSACTION_V1_TESTING_FILE_DESCRIPTOR_SET) .register_encoded_file_descriptor_set(UTIL_TIMESTAMP_FILE_DESCRIPTOR_SET) - .build_v1() + .build_v1alpha() .map_err(|e| anyhow::anyhow!("Failed to build reflection service: {}", e))? .send_compressed(CompressionEncoding::Zstd) .accept_compressed(CompressionEncoding::Zstd) diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs index 434b6947f3e20..b4058fbed142c 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs @@ -675,6 +675,15 @@ pub fn convert_account_signature( "[Indexer Fullnode] Indexer should never see transactions with NoAccountSignature" ) }, + AccountSignature::AbstractionSignature(s) => ( + transaction::account_signature::Type::Abstraction, + transaction::account_signature::Signature::Abstraction( + transaction::AbstractionSignature { + function_info: s.function_info.to_owned(), + signature: s.auth_data.inner().to_owned(), + }, + ), + ), }; transaction::AccountSignature { diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-manager/Cargo.toml index a902d64701d28..29cdcff29faf7 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/Cargo.toml @@ -15,10 +15,17 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } aptos-indexer-grpc-server-framework = { workspace = true } +aptos-protos = { workspace = true } async-trait = { workspace = true } clap = { workspace = true } serde = { workspace = true } tokio = { workspace = true } +tokio-scoped = { workspace = true } +tonic = { workspace = true } +tracing = { workspace = true } + +[dev-dependencies] +aptos-config = { workspace = true } [target.'cfg(unix)'.dependencies] jemallocator = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/config.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/config.rs index d457db0f2b1b2..591388a8c06df 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/src/config.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/config.rs @@ -1,18 +1,34 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +use crate::grpc_manager::GrpcManager; use anyhow::Result; use aptos_indexer_grpc_server_framework::RunnableConfig; use serde::{Deserialize, Serialize}; +use std::net::SocketAddr; +use tokio::sync::OnceCell; + +static GRPC_MANAGER: OnceCell = OnceCell::const_new(); + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub(crate) struct ServiceConfig { + pub(crate) listen_address: SocketAddr, +} #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] -pub struct IndexerGrpcManagerConfig {} +pub struct IndexerGrpcManagerConfig { + pub(crate) chain_id: u64, + pub(crate) service_config: ServiceConfig, +} #[async_trait::async_trait] impl RunnableConfig for IndexerGrpcManagerConfig { async fn run(&self) -> Result<()> { - Ok(()) + GRPC_MANAGER + .get_or_init(|| async { GrpcManager::new(self).await }) + .await + .start(&self.service_config) } fn get_server_name(&self) -> String { diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/grpc_manager.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/grpc_manager.rs new file mode 100644 index 0000000000000..9d04ab15abf04 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/grpc_manager.rs @@ -0,0 +1,46 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + config::{IndexerGrpcManagerConfig, ServiceConfig}, + service::GrpcManagerService, +}; +use anyhow::Result; +use aptos_protos::indexer::v1::grpc_manager_server::GrpcManagerServer; +use std::time::Duration; +use tonic::{codec::CompressionEncoding, transport::Server}; +use tracing::info; + +const HTTP2_PING_INTERVAL_DURATION: Duration = Duration::from_secs(60); +const HTTP2_PING_TIMEOUT_DURATION: Duration = Duration::from_secs(10); + +pub(crate) struct GrpcManager { + chain_id: u64, +} + +impl GrpcManager { + pub(crate) async fn new(config: &IndexerGrpcManagerConfig) -> Self { + let chain_id = config.chain_id; + + Self { chain_id } + } + + pub(crate) fn start(&self, service_config: &ServiceConfig) -> Result<()> { + let service = GrpcManagerServer::new(GrpcManagerService::new(self.chain_id)) + .send_compressed(CompressionEncoding::Zstd) + .accept_compressed(CompressionEncoding::Zstd); + let server = Server::builder() + .http2_keepalive_interval(Some(HTTP2_PING_INTERVAL_DURATION)) + .http2_keepalive_timeout(Some(HTTP2_PING_TIMEOUT_DURATION)) + .add_service(service); + + tokio_scoped::scope(|s| { + s.spawn(async move { + info!("Starting GrpcManager at {}.", service_config.listen_address); + server.serve(service_config.listen_address).await.unwrap(); + }); + }); + + Ok(()) + } +} diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/lib.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/lib.rs index 36d88a8c1b06b..789d6b0bc6d93 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-manager/src/lib.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/lib.rs @@ -2,3 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 pub mod config; +mod grpc_manager; +mod service; +#[cfg(test)] +mod test; diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/service.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/service.rs new file mode 100644 index 0000000000000..d50eca972d6df --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/service.rs @@ -0,0 +1,109 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_protos::indexer::v1::{ + grpc_manager_server::GrpcManager, service_info::Info, GetDataServiceForRequestRequest, + GetDataServiceForRequestResponse, GetTransactionsRequest, HeartbeatRequest, HeartbeatResponse, + TransactionsResponse, +}; +use tonic::{Request, Response, Status}; + +pub struct GrpcManagerService { + chain_id: u64, +} + +impl GrpcManagerService { + pub(crate) fn new(chain_id: u64) -> Self { + Self { chain_id } + } + + async fn handle_heartbeat( + &self, + _address: String, + _info: Info, + ) -> anyhow::Result> { + // TODO(grao): Implement. + todo!() + } + + fn pick_live_data_service(&self, _starting_version: u64) -> Option { + // TODO(grao): Implement. + todo!() + } + + async fn pick_historical_data_service(&self, _starting_version: u64) -> Option { + // TODO(grao): Implement. + todo!() + } +} + +#[tonic::async_trait] +impl GrpcManager for GrpcManagerService { + async fn heartbeat( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + if let Some(service_info) = request.service_info { + if let Some(address) = service_info.address { + if let Some(info) = service_info.info { + return self + .handle_heartbeat(address, info) + .await + .map_err(|e| Status::internal(format!("Error handling heartbeat: {e}"))); + } + } + } + + Err(Status::invalid_argument("Bad request.")) + } + + async fn get_transactions( + &self, + request: Request, + ) -> Result, Status> { + let _request = request.into_inner(); + let transactions = vec![]; + // TODO(grao): Implement. + + Ok(Response::new(TransactionsResponse { + transactions, + chain_id: Some(self.chain_id), + })) + } + + async fn get_data_service_for_request( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + + if request.user_request.is_none() { + return Err(Status::invalid_argument("Bad request.")); + } + + let user_request = request.user_request.unwrap(); + if user_request.starting_version.is_none() { + return Err(Status::invalid_argument("Bad request.")); + } + + let starting_version = user_request.starting_version(); + + let data_service_address = + // TODO(grao): Use a simple strategy for now. Consider to make it smarter in the + // future. + if let Some(address) = self.pick_live_data_service(starting_version) { + address + } else if let Some(address) = self.pick_historical_data_service(starting_version).await { + address + } else { + return Err(Status::internal( + "Cannot find a data service instance to serve the provided request.", + )); + }; + + Ok(Response::new(GetDataServiceForRequestResponse { + data_service_address, + })) + } +} diff --git a/ecosystem/indexer-grpc/indexer-grpc-manager/src/test.rs b/ecosystem/indexer-grpc/indexer-grpc-manager/src/test.rs new file mode 100644 index 0000000000000..461dbe10a2546 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-grpc-manager/src/test.rs @@ -0,0 +1,25 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::{IndexerGrpcManagerConfig, ServiceConfig}; +use aptos_config::utils::get_available_port; +use aptos_indexer_grpc_server_framework::RunnableConfig; +use std::time::Duration; + +#[tokio::test(flavor = "multi_thread", worker_threads = 16)] +async fn test_run() { + let port = get_available_port(); + let listen_address = format!("127.0.0.1:{port}").parse().unwrap(); + let config = IndexerGrpcManagerConfig { + chain_id: 0, + service_config: ServiceConfig { listen_address }, + }; + + let task = tokio::spawn(async move { + config.run().await.unwrap(); + }); + + tokio::time::sleep(Duration::from_secs(10)).await; + + assert!(!task.is_finished()); +} diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/126043288_stake_delegration_withdraw.json b/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/126043288_stake_delegration_withdraw.json deleted file mode 100644 index 8a67405bded9b..0000000000000 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/126043288_stake_delegration_withdraw.json +++ /dev/null @@ -1,388 +0,0 @@ -{ - "timestamp": { - "seconds": "1682009435", - "nanos": 451514000 - }, - "version": "126043288", - "info": { - "hash": "XM+vYQm12DV7oLtjMvi1WM3PyRYFV5Po1MC7wcPmUgU=", - "stateChangeHash": "+oFCCpv8nO4E+hZLPSXcihBsjGJGT2iDrC5HjqYkXX8=", - "eventRootHash": "lmxryCIVmihGwQxeeGwDx2WTH8/JwytEyUZlnh0nf+c=", - "gasUsed": "61", - "success": true, - "vmStatus": "Executed successfully", - "accumulatorRootHash": "Sk6e664oRIUtGG0s6n2QWZW4kPfx2TtTBI+IiWgqF7I=", - "changes": [ - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4", - "stateKeyHash": "R2cGrgtkE2jia4psc1J7+96vBmFv8CVjw8mwGWqfDfo=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"2653232742\"},\"deposit_events\":{\"counter\":\"10\",\"guid\":{\"id\":{\"addr\":\"0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"23\",\"guid\":{\"id\":{\"addr\":\"0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4", - "stateKeyHash": "jNepY+2ntMWnwldqrcLptPY0fI8LL5edPZD3Zv94tCI=", - "type": { - "address": "0x1", - "module": "account", - "name": "Account" - }, - "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4\",\"coin_register_events\":{\"counter\":\"14\",\"guid\":{\"id\":{\"addr\":\"0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"44\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"62\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e", - "stateKeyHash": "m1zMzEiA39MGlIddKEkREn3Sb0UJH7Xfgom+eafwuZs=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"0\"},\"deposit_events\":{\"counter\":\"31\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"31\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e", - "stateKeyHash": "pJ+IFgI8eausfa+EIuI55Y2CXCjo3qlIlLNnIA7ntc0=", - "type": { - "address": "0x1", - "module": "stake", - "name": "StakePool" - }, - "typeStr": "0x1::stake::StakePool", - "data": "{\"active\":{\"value\":\"0\"},\"add_stake_events\":{\"counter\":\"13\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"6\"}}},\"delegated_voter\":\"0xcec29699a9bf0f26a7e525a626a5d876b185f60c670a89849939da1587185d08\",\"distribute_rewards_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"12\"}}},\"inactive\":{\"value\":\"0\"},\"increase_lockup_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"10\"}}},\"initialize_validator_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"4\"}}},\"join_validator_set_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"11\"}}},\"leave_validator_set_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"15\"}}},\"locked_until_secs\":\"0\",\"operator_address\":\"0xcec29699a9bf0f26a7e525a626a5d876b185f60c670a89849939da1587185d08\",\"pending_active\":{\"value\":\"0\"},\"pending_inactive\":{\"value\":\"0\"},\"reactivate_stake_events\":{\"counter\":\"28\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"7\"}}},\"rotate_consensus_key_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"8\"}}},\"set_operator_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"5\"}}},\"unlock_stake_events\":{\"counter\":\"33\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"13\"}}},\"update_network_and_fullnode_addresses_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"9\"}}},\"withdraw_stake_events\":{\"counter\":\"18\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"14\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e", - "stateKeyHash": "lSgRVdnN3gVJ1UPeq5eZ8v2GgApTFhnFwIg3ViBP+7A=", - "type": { - "address": "0x1", - "module": "delegation_pool", - "name": "DelegationPool" - }, - "typeStr": "0x1::delegation_pool::DelegationPool", - "data": "{\"active_shares\":{\"scaling_factor\":\"10000000000000000\",\"shares\":{\"inner\":{\"handle\":\"0x20a562f3cce72009287a03c003fadcfc61093d3bde0054a165b3cc568b0e0b7e\"},\"length\":\"0\"},\"total_coins\":\"0\",\"total_shares\":\"0\"},\"add_stake_events\":{\"counter\":\"13\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"16\"}}},\"distribute_commission_events\":{\"counter\":\"71\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"20\"}}},\"inactive_shares\":{\"handle\":\"0xcc401582c138de63fab2b47a5820c85b9eacee8c543e0daef120d94a4c7d7813\"},\"observed_lockup_cycle\":{\"index\":\"0\"},\"operator_commission_percentage\":\"1200\",\"pending_withdrawals\":{\"handle\":\"0x103338a7bf343ce3a027cc93f5a039659f92ca1dfb07488f863ec874946f7de3\"},\"reactivate_stake_events\":{\"counter\":\"10\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"17\"}}},\"stake_pool_signer_cap\":{\"account\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"},\"total_coins_inactive\":\"0\",\"unlock_stake_events\":{\"counter\":\"29\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"18\"}}},\"withdraw_stake_events\":{\"counter\":\"18\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"19\"}}}}" - } - }, - { - "type": "TYPE_DELETE_TABLE_ITEM", - "deleteTableItem": { - "stateKeyHash": "YWQ2/K0U38PPFMU55UpwNhGoOW4AK4xj6ah1AWQx7zg=", - "handle": "0x103338a7bf343ce3a027cc93f5a039659f92ca1dfb07488f863ec874946f7de3", - "key": "0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4", - "data": { - "key": "\"0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4\"", - "keyType": "address" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", - "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", - "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", - "data": { - "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", - "keyType": "address", - "value": "\"103037632846529620\"", - "valueType": "u128" - } - } - }, - { - "type": "TYPE_DELETE_TABLE_ITEM", - "deleteTableItem": { - "stateKeyHash": "wmp8CXcPQA784LoU0La3c7p6JdQntrXOgeHxWethwQA=", - "handle": "0xb744e4bc7e64146adaae0ff1f86b2e1229265d39683d142fc80b23006ae49ac3", - "key": "0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4", - "data": { - "key": "\"0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4\"", - "keyType": "address" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "kN5I82wub68cybmXHub7uMdgvbV98DHpHpwTog9deUg=", - "handle": "0xcc401582c138de63fab2b47a5820c85b9eacee8c543e0daef120d94a4c7d7813", - "key": "0x0000000000000000", - "data": { - "key": "{\"index\":\"0\"}", - "keyType": "0x1::delegation_pool::ObservedLockupCycle", - "value": "{\"scaling_factor\":\"10000000000000000\",\"shares\":{\"inner\":{\"handle\":\"0xb744e4bc7e64146adaae0ff1f86b2e1229265d39683d142fc80b23006ae49ac3\"},\"length\":\"0\"},\"total_coins\":\"0\",\"total_shares\":\"0\"}", - "valueType": "0x1::pool_u64_unbound::Pool" - } - } - } - ] - }, - "epoch": "2283", - "blockHeight": "48956686", - "type": "TRANSACTION_TYPE_USER", - "sizeInfo": { - "transactionBytes": 267, - "eventSizeInfo": [ - { - "typeTagBytes": 76, - "totalBytes": 204 - }, - { - "typeTagBytes": 61, - "totalBytes": 149 - }, - { - "typeTagBytes": 59, - "totalBytes": 147 - }, - { - "typeTagBytes": 52, - "totalBytes": 108 - }, - { - "typeTagBytes": 53, - "totalBytes": 109 - }, - { - "typeTagBytes": 52, - "totalBytes": 108 - }, - { - "typeTagBytes": 69, - "totalBytes": 189 - } - ], - "writeOpSizeInfo": [ - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 147 - }, - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 680 - }, - { - "keyBytes": 99, - "valueBytes": 432 - }, - { - "keyBytes": 66 - }, - { - "keyBytes": 66, - "valueBytes": 16 - }, - { - "keyBytes": 66 - }, - { - "keyBytes": 42, - "valueBytes": 72 - } - ] - }, - "user": { - "request": { - "sender": "0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4", - "sequenceNumber": "61", - "maxGasAmount": "74", - "gasUnitPrice": "103", - "expirationTimestampSecs": { - "seconds": "1682009554" - }, - "payload": { - "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", - "entryFunctionPayload": { - "function": { - "module": { - "address": "0x1", - "name": "delegation_pool" - }, - "name": "withdraw" - }, - "arguments": [ - "\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"", - "\"2651414640\"" - ], - "entryFunctionIdStr": "0x1::delegation_pool::withdraw" - } - }, - "signature": { - "type": "TYPE_ED25519", - "ed25519": { - "publicKey": "tdV+/HcoA8c1pDOG3h7XKrhE5/K/WR9LW5hpAdL5tA8=", - "signature": "ld+VOd8F7qT1IWXzcvkWBFTdhV3WdxdT1PhLvXN+B9608HL4g/GH5LbShazv9ThdcJ7semfLjDk8o0wjmHyXCg==" - } - } - }, - "events": [ - { - "key": { - "creationNumber": "20", - "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" - }, - "sequenceNumber": "70", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "delegation_pool", - "name": "DistributeCommissionEvent" - } - }, - "typeStr": "0x1::delegation_pool::DistributeCommissionEvent", - "data": "{\"commission_active\":\"0\",\"commission_pending_inactive\":\"0\",\"operator\":\"0xcec29699a9bf0f26a7e525a626a5d876b185f60c670a89849939da1587185d08\",\"pool_address\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"}" - }, - { - "key": { - "creationNumber": "7", - "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" - }, - "sequenceNumber": "27", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "stake", - "name": "ReactivateStakeEvent" - } - }, - "typeStr": "0x1::stake::ReactivateStakeEvent", - "data": "{\"amount\":\"0\",\"pool_address\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"}" - }, - { - "key": { - "creationNumber": "14", - "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" - }, - "sequenceNumber": "17", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "stake", - "name": "WithdrawStakeEvent" - } - }, - "typeStr": "0x1::stake::WithdrawStakeEvent", - "data": "{\"amount_withdrawn\":\"2651414640\",\"pool_address\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"}" - }, - { - "key": { - "creationNumber": "2", - "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" - }, - "sequenceNumber": "30", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "coin", - "name": "DepositEvent" - } - }, - "typeStr": "0x1::coin::DepositEvent", - "data": "{\"amount\":\"2651414640\"}" - }, - { - "key": { - "creationNumber": "3", - "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" - }, - "sequenceNumber": "30", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "coin", - "name": "WithdrawEvent" - } - }, - "typeStr": "0x1::coin::WithdrawEvent", - "data": "{\"amount\":\"2651414640\"}" - }, - { - "key": { - "creationNumber": "2", - "accountAddress": "0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4" - }, - "sequenceNumber": "9", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "coin", - "name": "DepositEvent" - } - }, - "typeStr": "0x1::coin::DepositEvent", - "data": "{\"amount\":\"2651414640\"}" - }, - { - "key": { - "creationNumber": "19", - "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" - }, - "sequenceNumber": "17", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "delegation_pool", - "name": "WithdrawStakeEvent" - } - }, - "typeStr": "0x1::delegation_pool::WithdrawStakeEvent", - "data": "{\"amount_withdrawn\":\"2651414640\",\"delegator_address\":\"0x2fd9dcfafccb7c4af95f62a2e1c720736394171810196fe5cf60b1cd335a40b4\",\"pool_address\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"}" - } - ] - } -} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/139442597_stake_unlock.json b/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/139442597_stake_unlock.json deleted file mode 100644 index 6308c83967225..0000000000000 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/139442597_stake_unlock.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "timestamp": { - "seconds": "1683759290", - "nanos": 511507000 - }, - "version": "139442597", - "info": { - "hash": "RpDVKeOm06q9Yx+c07Aazi54yoFvB8au5AeOfP15HPk=", - "stateChangeHash": "Aj+s/xZvqewTxvqu2ameJ+dZn+ai86KqDFVJ0OjZ12M=", - "eventRootHash": "K7fzjSze3fdNBJwqkOGJMapw/bGi8EfywiJZhuEnLes=", - "gasUsed": "5", - "success": true, - "vmStatus": "Executed successfully", - "accumulatorRootHash": "wcvJwG2GNT+8xgrzH1PYq9jhS5cP9QmzD+02TvPsPAQ=", - "changes": [ - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15", - "stateKeyHash": "EvBcNMI6wxdCfpA5tm3dwDBJxOE/IBSrsHcp2dqhyBs=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"8198324410\"},\"deposit_events\":{\"counter\":\"8\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"7\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15", - "stateKeyHash": "saefBfsqqVyLFGZ0wCs7Q1j6XJdzORBYaa4zOh0WE0o=", - "type": { - "address": "0x1", - "module": "stake", - "name": "StakePool" - }, - "typeStr": "0x1::stake::StakePool", - "data": "{\"active\":{\"value\":\"0\"},\"add_stake_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"15\"}}},\"delegated_voter\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"distribute_rewards_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"21\"}}},\"inactive\":{\"value\":\"0\"},\"increase_lockup_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"19\"}}},\"initialize_validator_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"13\"}}},\"join_validator_set_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"20\"}}},\"leave_validator_set_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"24\"}}},\"locked_until_secs\":\"0\",\"operator_address\":\"0x6673cf23cd019c663faebf23497883e1e5b6d8c76b39385ec82809c59095214c\",\"pending_active\":{\"value\":\"0\"},\"pending_inactive\":{\"value\":\"100000000\"},\"reactivate_stake_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"16\"}}},\"rotate_consensus_key_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"17\"}}},\"set_operator_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"14\"}}},\"unlock_stake_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"22\"}}},\"update_network_and_fullnode_addresses_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"18\"}}},\"withdraw_stake_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"23\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15", - "stateKeyHash": "pZ39U+ySIAJWZGND9I1cI9JYxCmIEDexzfzPm2MXsdM=", - "type": { - "address": "0x1", - "module": "account", - "name": "Account" - }, - "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0x095cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"25\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"23\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", - "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", - "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", - "data": { - "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", - "keyType": "address", - "value": "\"103371128441233190\"", - "valueType": "u128" - } - } - } - ] - }, - "epoch": "2526", - "blockHeight": "54325601", - "type": "TRANSACTION_TYPE_USER", - "sizeInfo": { - "transactionBytes": 222, - "eventSizeInfo": [ - { - "typeTagBytes": 57, - "totalBytes": 145 - } - ], - "writeOpSizeInfo": [ - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 680 - }, - { - "keyBytes": 84, - "valueBytes": 147 - }, - { - "keyBytes": 66, - "valueBytes": 16 - } - ] - }, - "user": { - "request": { - "sender": "0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15", - "sequenceNumber": "22", - "maxGasAmount": "7", - "gasUnitPrice": "100", - "expirationTimestampSecs": { - "seconds": "1683759320" - }, - "payload": { - "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", - "entryFunctionPayload": { - "function": { - "module": { - "address": "0x1", - "name": "stake" - }, - "name": "unlock" - }, - "arguments": [ - "\"1442700000000000\"" - ], - "entryFunctionIdStr": "0x1::stake::unlock" - } - }, - "signature": { - "type": "TYPE_ED25519", - "ed25519": { - "publicKey": "705WA3UXlhs8ocgApuWYonF1Z9MBaWpF46ODFsTNkHg=", - "signature": "MRY1yB4j9Td/4leTOm5FdmTdGT00kpyJQQ8vMqcH0zMKWQL8jiPyeuSEFB5UVb7JjcoGVYFpypIW5rifREwdBA==" - } - } - }, - "events": [ - { - "key": { - "creationNumber": "22", - "accountAddress": "0x095cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15" - }, - "sequenceNumber": "2", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "stake", - "name": "UnlockStakeEvent" - } - }, - "typeStr": "0x1::stake::UnlockStakeEvent", - "data": "{\"amount_unlocked\":\"0\",\"pool_address\":\"0x95cdd904dc1d91736019a3fe149488072f87690a210b3b35f87ea0f6898ac15\"}" - } - ] - } -} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1837008146_stake_add.json b/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1837008146_stake_add.json deleted file mode 100644 index 40040adf8a3f7..0000000000000 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1837008146_stake_add.json +++ /dev/null @@ -1,537 +0,0 @@ -{ - "timestamp": { - "seconds": "1729803976", - "nanos": 378230000 - }, - "version": "1837008146", - "info": { - "hash": "yv/+K2c9weDA8nrIsefQR8md966onIaNQna/+ieAy28=", - "stateChangeHash": "xgSqP4SucwMW3qJeUTyIRsgp/Ix9K5aAO7Tr9WbC8Wo=", - "eventRootHash": "wyYfSgcPWYpBA/DUYaR0gs+HPeuXBcYe+H2LY6S9oi0=", - "gasUsed": "1344", - "success": true, - "vmStatus": "Executed successfully", - "accumulatorRootHash": "0DEo7QY0RVCwE9VK83unfQGMbTpyFBdc8p4zWrbmx0k=", - "changes": [ - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x1", - "stateKeyHash": "/Oyrha7CwSRSnRt+eAL3NETP1PqiBLXYcvFVFj0aRbk=", - "type": { - "address": "0x1", - "module": "stake", - "name": "ValidatorSet" - }, - "typeStr": "0x1::stake::ValidatorSet", - "data": "{\"active_validators\":[{\"addr\":\"0xed84f8724f703c17075fb528b5713424e794f79ac82273d8f747b3f26fdd9ecd\",\"config\":{\"consensus_pubkey\":\"0x9148bc1a4e0538fa4e3c88a147c09435a26ec2e87776f343b9e3c7faa049e9802ce2bd1d170ebf922d9299edf128f6ff\",\"fullnode_addresses\":\"0x016704023d66756c6c6e6f64652e31383737383430662d386139342d343630362d383463622d3932353264386161356634372e6170746f732e6269736f6e2e72756e05261807202d0a88fafc3ec8081cc23ea8a5557fa4ed2402490403c6b7ab0cc3c25cabd0720800\",\"network_addresses\":\"0x016804023e76616c696461746f722e31383737383430662d386139342d343630362d383463622d3932353264386161356634372e6170746f732e6269736f6e2e72756e05241807206fa4c6191cec1e3f6bf3d0bb90d90033e27d8c6991f5e959eee63fcef40c32410800\",\"validator_index\":\"0\"},\"voting_power\":\"176952811965520\"},{\"addr\":\"0xeb5d1dfba88204036132b2bf4f4600f20822738e01985401ba45e75c464d1965\",\"config\":{\"consensus_pubkey\":\"0xb4399f716b06a1dfb187bd29255dc89fa89f4bbe259b930e16bb373f1152c0f91c31928437b2050ab3ac36cb6e6913ca\",\"fullnode_addresses\":\"0x016704023d66756c6c6e6f64652e62626237366432642d303262352d346533652d626663332d3966313061326536393834392e6170746f732e6269736f6e2e72756e05261807202494f31865a994a7ef8c2723a5f3fcfa05a8dad872e7420de8c542dac59fb1070800\",\"network_addresses\":\"0x016804023e76616c696461746f722e62626237366432642d303262352d346533652d626663332d3966313061326536393834392e6170746f732e6269736f6e2e72756e05241807203601215a079b0114a32104bd02149cf2258a206c8f8c79790e0684f4adfeae400800\",\"validator_index\":\"1\"},\"voting_power\":\"113018095743971\"},{\"addr\":\"0x32ad233a939bfbafb8d9056c0ae2eba58828d8baf5582277578ced38477f0f14\",\"config\":{\"consensus_pubkey\":\"0x90ef1d56c15ecc4574420d8897dd93b11c8958b9145860af5e6cb3f867b8edaa42aa9292c8ad492f7741b4de920b7189\",\"fullnode_addresses\":\"0x016604023c66756c6c6e6f64652e62356537653233642d303637322d343962352d393133392d3536356561306431613136652e6170746f732e686572642e72756e0526180720430c1f838c93e4bc80a4a65fad1fd5448328a0d6d0cfb342e680fb196a68da390800\",\"network_addresses\":\"0x016704023d76616c696461746f722e62356537653233642d303637322d343962352d393133392d3536356561306431613136652e6170746f732e686572642e72756e0524180720ea0f65faab5667196dfe0142048c0108232432e6073bc84cb706d5ae2be619390800\",\"validator_index\":\"2\"},\"voting_power\":\"413120477509988\"},{\"addr\":\"0xd4e43fa15a4cf475b35f7278f02ae5a694e14fbd7ef2494e39e7978781b3eefe\",\"config\":{\"consensus_pubkey\":\"0xb48115a3403e81412564b5819cb0ee88f1152393f99a794d6352b790e32c0946d606e5535295232ea6884ebe7c03b99a\",\"fullnode_addresses\":\"0x014c04022276666e302e61706e65312d302e6d61696e6e65742e6170746f736c6162732e636f6d0526180720a84c79bd0d5ee54b62db188e748fc66b62cbd15d5efe36b1d5c7cfa5ab445d390800\",\"network_addresses\":\"0x014c04022276616c302e61706e65312d302e6d61696e6e65742e6170746f736c6162732e636f6d05241807204b226faa0463d6d29e448bfb0423b08bb0d309b46ffd1251c765bc6f2dbdcd560800\",\"validator_index\":\"3\"},\"voting_power\":\"115251408829656\"},{\"addr\":\"0xda557f6d45952778e0c4c7296dc8f8303d846d5453800efd7b03cfbd5f8def04\",\"config\":{\"consensus_pubkey\":\"0x9069fb9c0df832b088613914bc94883df7e9d34354939942f910cc11b73e4b73c11da846a127407fe6438f9f6c238057\",\"fullnode_addresses\":\"0x014c04022276666e302e75736365312d302e6d61696e6e65742e6170746f736c6162732e636f6d0526180720f9e0b20bca5cf57f26ca1b046db48f50e2741c6c93ac04aab6b2fe7b3364b9430800\",\"network_addresses\":\"0x014c04022276616c302e75736365312d302e6d61696e6e65742e6170746f736c6162732e636f6d05241807207f782f994cd4ee26b655e2a594c72d81e950c7d97bc051814453c83eedf4ac510800\",\"validator_index\":\"4\"},\"voting_power\":\"115246614568474\"},{\"addr\":\"0x947c6451ad9a8659cba4e60a6da41086eb66e73fc07936bd3b7044873b5e094d\",\"config\":{\"consensus_pubkey\":\"0xb60961bd67a9b9740e86a36a5906454146d161cbe54e6de10fe246eed7ee48d5032acdd6d8b8cb89ab1d856fdc949d36\",\"fullnode_addresses\":\"0x014704021d76666e2e6d61696e6e65742e6170746f732e64657370726561642e696f0526180720d4eabfa79a26a59f5701397277556c4f1343e4892bfecf13ef9401c1650f317a0800\",\"network_addresses\":\"0x014604021c766e2e6d61696e6e65742e6170746f732e64657370726561642e696f0524180720e57f19f9f594969d37734976393b5c5db783b61799a89983c8a59f817d9940020800\",\"validator_index\":\"5\"},\"voting_power\":\"262033982446852\"},{\"addr\":\"0xc32f662cd9718f02d8a8e5628f8f642fa27cd9b5f457b406ed734901a4939e34\",\"config\":{\"consensus_pubkey\":\"0xb9875cecb4588e06d3db277beda15e7ab8a2931372ff2049a8bcc5ca0c607bfc2e2aa250b8dbef916d374f74d34f6c3e\",\"fullnode_addresses\":\"0x013e0402146170746f732d76666e2e7374616b656c792e696f05261807205a86c97203a41684739f42733727d79a1390579f1ac460b453b752a8ccdc8c460800\",\"network_addresses\":\"0x014404021a6170746f732d76616c696461746f722e7374616b656c792e696f0524180720796e34b3ffbd8396ad4ade8e397420bad3b5c49dee20a1dbcf8e6256105a1a2a0800\",\"validator_index\":\"6\"},\"voting_power\":\"1306968796420602\"},{\"addr\":\"0x324df1e27c4129a58d73851ae0e9366064dc666a73e747051e203694a4cb257\",\"config\":{\"consensus_pubkey\":\"0x866517eea1372da09adc99e810ab5e94bed852bb81c30600ccf1a1a8d9b9b034a039e594ef410b0b600efb2b246f54e3\",\"fullnode_addresses\":\"0x014204021876666e2e6170746f732e7268696e6f7374616b652e636f6d0526180720023c6d9ba8399b0b324d8aab7ddbeb8f076230e7b5500c014e71288e5c0b01070800\",\"network_addresses\":\"0x01430402196e6f64652e6170746f732e7268696e6f7374616b652e636f6d052418072072ca8564ccdc59ac0d7a836eae525caa666a0093e00d24d92b82c1ed659505660800\",\"validator_index\":\"7\"},\"voting_power\":\"1305289547264841\"},{\"addr\":\"0x3d654d35d558d6381fe6a0484d81c4fed128cd8adc1ca7a1482c297da80ee039\",\"config\":{\"consensus_pubkey\":\"0x91ef17afa2d8e1cf27dc068c19df4122b6653d51b0bb818aeb898838e981cd14add149600f2a4ea6aacfd818d7f5cc65\",\"fullnode_addresses\":\"0x014404021a76666e2e6d61696e6e65742e706f6e74656d2e6e6574776f726b0526180720f2f9fb5716fac75141eb5640d4a01fc395c187f1030d746b8d8c3c55dc990e580800\",\"network_addresses\":\"0x0143040219766e2e6d61696e6e65742e706f6e74656d2e6e6574776f726b0524180720090c9f0577db3336fdd71fe7a605f0b3e4610a03fb6efb1664715807cc92362a0800\",\"validator_index\":\"8\"},\"voting_power\":\"814100528253942\"},{\"addr\":\"0xea733e480c379c61dae9cfb3f14a388f6a683d7a797c135f86b924fb7a2e8cdb\",\"config\":{\"consensus_pubkey\":\"0x854cdb1633ed413a07e103577adb6e708b54581b8d3711b085fdbc31db1177148b8e153c3124c5984cda1dc9c707ac1c\",\"fullnode_addresses\":\"0x012d0400d05b6be50526180720b0c58e2ef9958ccd3ac1e6fcafa8752594c76b5808b3642d3bc09c6ea4bd90590800\",\"network_addresses\":\"0x012d0400d05b6bf60524180720caaebd25ad702242e94fbbdf391aa81aa041a937815851015eba8ade96c6fc710800\",\"validator_index\":\"9\"},\"voting_power\":\"112714275034006\"},{\"addr\":\"0xc067ce10f1faa4812fe608e2d4b3e1fe0bb629e91cfff532cccc23803a624414\",\"config\":{\"consensus_pubkey\":\"0x92e9b6a4b1a2943632a66f46076dd0f4180a78626bb7b3bd514519f43ac46bdd60f2ac7f94e8f2ab1ca7a46d1f2a031d\",\"fullnode_addresses\":\"0x013e0402146d61696e6e65742e6170746f732e65752e6f726705261807201b91523ee77cef70192b0d20197049d53d208a61fc89391eb6c067a9d4b49a5d0800\",\"network_addresses\":\"0x0141040217766e2e6d61696e6e65742e6170746f732e65752e6f72670524180720c30bc1e1aad627d791ef6884016ea29c93fd07562b5f337799f6bc1368323b6a0800\",\"validator_index\":\"10\"},\"voting_power\":\"113053588442952\"},{\"addr\":\"0xc1f31446852220ffdf2fe294fd42fa5d7ced48c7d0f1378d6813ae8d972f1adf\",\"config\":{\"consensus_pubkey\":\"0x9788b1e2c95a0c053d0dc76bbfaadb1c6198ce7c89e12f2221db7e6680ab5793b1ea79984b96e963401047f0dd8c614a\",\"fullnode_addresses\":\"0x01410402176170746f732e76666e2e6e6f64656d6f7665722e636f6d0526180720942efab5d95d7db0f2326102bf20c600d7ac06831fc41c507172b0c46f2e47510800\",\"network_addresses\":\"0x014704021d6170746f732e76616c696461746f722e6e6f64656d6f7665722e636f6d05241807207087e90c49704f26e3a2ec47b1ad364b7024680b9559a12deca94c96d5963b0d0800\",\"validator_index\":\"11\"},\"voting_power\":\"112706492720926\"},{\"addr\":\"0x52b48fb6e6883d4cdf244cde8d7e972ea2d8ece9b5e484ed5085aacef0e306a1\",\"config\":{\"consensus_pubkey\":\"0xb82b82a8f56a9d165aec20966dd2b842c33a16b756d59d6d88bef1b12e0e64aa52798d49fb41e76abef8e9ac468ea667\",\"fullnode_addresses\":\"0x012d0400344376df05261807208c9255c8b64a0c01d726045dfc3ca0b512e51e41e74fc96a1152b98b1a5bfe410800\",\"network_addresses\":\"0x012d04003443479c0524180720db1679d36960c0f05ff9c5f49b7fd6529f902a11fe456fe6d95747f945f9477d0800\",\"validator_index\":\"12\"},\"voting_power\":\"112689898824270\"},{\"addr\":\"0x9dfeca70acb3e01328d9dbbda4a6c23913fcd81ef25f74fab52cb2e96b0a1486\",\"config\":{\"consensus_pubkey\":\"0x8936c804437ad315c6606b9bc89371aed0aa8692fbc719280ef2188bf51a4370501b64d243b430edd29f0994120a39e2\",\"fullnode_addresses\":\"0x014d04022366756c6c6e6f64652e6d61696e6e65742e6170746f732e6e6f6465732e63656e7465720526180720630fb419660d6e57b92822f487bb5db6b0293f96f1f8631777ccfbeb366a43390800\",\"network_addresses\":\"0x014e04022476616c696461746f722e6d61696e6e65742e6170746f732e6e6f6465732e63656e74657205241807207da1a825a6375123a1b264497ec665ad993a77fc30ffae3f06f7a7b2634498280800\",\"validator_index\":\"13\"},\"voting_power\":\"112741827830295\"},{\"addr\":\"0x85bec1dcb618004064ab52a594321e8f047bac53be8244c5d10ac136128e30f7\",\"config\":{\"consensus_pubkey\":\"0x97739ff8fe762e704f81d1bf7f5406ed845d39a8fdcb380f68ac89d6563396cbbc1626b7c70e521bf8432c4f671f7881\",\"fullnode_addresses\":\"0x01430402196170746f732d66756c6c6e6f6465302e74617261732e756e6f05261807205fa606e4701e26282bee851ca473bd4e7b23672bf557b816879c1c2ca8c33f7a0800\",\"network_addresses\":\"0x014404021a6170746f732d76616c696461746f72302e74617261732e756e6f05241807200d2cab67c6e6ee8dc0fb513d2ca1964d52a503049f0782ef21919a495027ab0e0800\",\"validator_index\":\"14\"},\"voting_power\":\"112716040140215\"},{\"addr\":\"0x4cfeaf68aacfd0cd459c292837854ce058b9ba6c1cc35e8684b1a5030b1dc922\",\"config\":{\"consensus_pubkey\":\"0xb1b46f8ffe0b7d26c2e542664a0eaa3d7a851bc61120afb778dadbac6baee5dc31ecb048fa7cd7e22c61b835e0e9574d\",\"fullnode_addresses\":\"0x012d04004115294c05261807203b3aa2faaf3f8c3a5ef4da88587376965ee5dadfd9ff9aac78bdb9b1f73701620800\",\"network_addresses\":\"0x012d0400411550e80524180720a63e63ed35e7d3a41d1e1c81790bccb1b2ce622378e3b3086d382d57892fbc4b0800\",\"validator_index\":\"15\"},\"voting_power\":\"112745749715156\"},{\"addr\":\"0x447fc1fc130cf9245d9ca291785d0f8a00c3ebdc26b2e4c6165801b0af01c917\",\"config\":{\"consensus_pubkey\":\"0xb2480e136fe7c2a6716ac607019c802420c427f66f832837a0f8d386ecbe0d6d4485ed283fc0b9e89e3f3080be8c0eb5\",\"fullnode_addresses\":\"0x012d0400411550e00526180720338c4da1614934a16d553264cadfd4909fd13161b83717ef93861fc7a8c916220800\",\"network_addresses\":\"0x012d04004115515c0524180720cea3bc52d574788ae39e581947c19b8d20bd1740ccc215af7df6e1ff52b379610800\",\"validator_index\":\"16\"},\"voting_power\":\"112703865487561\"},{\"addr\":\"0xd60280852b50c341b22bba06562a817293d7b834eac251e7600b25d8bdd9efa3\",\"config\":{\"consensus_pubkey\":\"0xb07957c1c374415358c778068353b5ad8f18227eb1b19a9fc8da1667fe3d3100f359dc34cc29e2ff215e7dadde8f225e\",\"fullnode_addresses\":\"0x014d04022366756c6c6e6f64652e6d61696e6e65742e6170746f732e6d6f76656d6f76652e6f7267052618072030d434dca09c79413cbf885dae074a2390f3803371cd170f4e3c51a773522c4a0800\",\"network_addresses\":\"0x014e04022476616c696461746f722e6d61696e6e65742e6170746f732e6d6f76656d6f76652e6f726705241807209e571606d7287014a887ffd1d590049e600c2af0e1f01173dfcd7f2960c7c7220800\",\"validator_index\":\"17\"},\"voting_power\":\"112803755441924\"},{\"addr\":\"0xdca6aaf410e984463b37e192652b3c09b0ae3968b3e0171bb076ae0e21112ef9\",\"config\":{\"consensus_pubkey\":\"0x9743c1abc184978eb654562f5f28bdded5ae1f1a319ad2e6581dc7874c3387180080336634967fc468cde3232a6e81d9\",\"fullnode_addresses\":\"0x012d04000fccf131052618072006b93e83ff852d12012d87c4c6357c3218388c722fd9c867937fac641b82bd1a0800\",\"network_addresses\":\"0x012d04000fccf134052418072008b62a1f9b882eb7955ab3ed49942554c3a6c2163565a7f59fef453d737d15550800\",\"validator_index\":\"18\"},\"voting_power\":\"112743577394575\"},{\"addr\":\"0xd2dc57e95669c9bf102cb5693fe8b2a8b10d330213d7ddd9fb417f86f183dc1d\",\"config\":{\"consensus_pubkey\":\"0x94f3e6f611e741d69e0965bbd3bfdc6370ea4c04e6b375b48ccd9b08bfeca9cad3f26f58c57e772104b37ba551c1d195\",\"fullnode_addresses\":\"0x012d04004543968a0526180720ea03450ef44fc52dd39e30b1786eb999d6bf6d22f6d3e5341730707c5f164c1c0800\",\"network_addresses\":\"0x012d0400454396890524180720f2e7f1e0d23ee6f06c687e1cddf05070239a755208a2f2df252c246785afa3180800\",\"validator_index\":\"19\"},\"voting_power\":\"112868509704994\"},{\"addr\":\"0x35b922386bd35db0f33c732a70d7b6a2e91e463812c8d710f925f6da0e0ace07\",\"config\":{\"consensus_pubkey\":\"0xaa70d27f7b44955e59daae4002de10e00dd0ad3c9d3a54a9d5bb49f0af6d78b29b3d2f33d868fee48058b037216d08ea\",\"fullnode_addresses\":\"0x012d040023c75e67052618072098b923097936cc53df5138a8a1a67c18bd2b33421777b55b808652fff513e1660800\",\"network_addresses\":\"0x012d040023c61ede05241807205c37eb57684ced6a80eefc4e434f635acba094a66f7550bbada806b89d8fb35c0800\",\"validator_index\":\"20\"},\"voting_power\":\"115158070212627\"},{\"addr\":\"0x4b2c524fc36698caf9d049b6088faa002cea3bbcbf5ed764f59768b4fe96efcf\",\"config\":{\"consensus_pubkey\":\"0x857b3708c3652663fe19119317197fe10a70c92be553fc55b22b3b91e8920d485281fd4236e7f0ededc649150b85c4de\",\"fullnode_addresses\":\"0x012d04005bdaf7c405261807206ab230dac7d30c3f3f33f41dc37a2c958015f11b10d77a79d3f5c94e614eb7780800\",\"network_addresses\":\"0x012d04001fc06a8405241807204ef267beac90191dcb61a607333f48ca0b762a27370ca037d198a56fa0d383270800\",\"validator_index\":\"21\"},\"voting_power\":\"113044597790299\"},{\"addr\":\"0x18a3ef480b7883d05b917873a8b6d5f5a5f763372b650242ede89836a67cdce8\",\"config\":{\"consensus_pubkey\":\"0xb5c86b9ad3f19858cd1026f4660db300bdaeb4493866e1e19d8c6daad6b04e73ec1f5eb50d8066509b309dd49187dc6d\",\"fullnode_addresses\":\"0x014004021666756c6c6e6f64652e6170746f736c6162732e6c746405261807209801bf1bb28f45cebe83cdd33550eff87c4727d3e85edbd001f047fdb1038f7c0800\",\"network_addresses\":\"0x014104021776616c696461746f722e6170746f736c6162732e6c746405241807208db73be4c908e5bab823e27ac222cd85aea6f4d0d61e5e157bbac43403dfd4550800\",\"validator_index\":\"22\"},\"voting_power\":\"112746106303243\"},{\"addr\":\"0xc807d24a6ac70599cc9b72c649eb6b00c34a0e9c704447c44d75fade07213a26\",\"config\":{\"consensus_pubkey\":\"0xab31ec8d42d2154645cf4c1ac36b9bb162ca8b841f0e374fcebf585050fb064326947ca02bc5ef66b63d7288fa0ae942\",\"fullnode_addresses\":\"0x015604022c76666e2e6170746f732e6d61696e6e65742e72657075626c696363727970746f2d736f757263652e696e666f0526180720c4587e699ffbdfc8a3fb3869513e8ef2fe903300bb26e4d39cf436163ba0d8620800\",\"network_addresses\":\"0x015404022a762e6170746f732e6d61696e6e65742e72657075626c696363727970746f2d736f757263652e696e666f0524180720deead78f3a93b7e5ea08d2ff1faeec5551a313284b002a79e019568717bae0650800\",\"validator_index\":\"23\"},\"voting_power\":\"918891702610705\"},{\"addr\":\"0x4cf01e6c54a8ec918bf1b5666ffa26dcea3dc8044bdf011a58df1aeae9756fa5\",\"config\":{\"consensus_pubkey\":\"0xa0cd1026185a52bacfb9533ba6dbf08f8f513371f11d310493ac7fdce51aae684279c0570de5d0ecb4433bb3ff8d4a20\",\"fullnode_addresses\":\"0x012d0400cf7813bc05e675072036422795e84ef32b64807897b7634f8f643737c5ed5a6011ce28d16ed362ef440800\",\"network_addresses\":\"0x012d0400cf7813bc05e4750720d7a052274eb58be4936cc5164a9f35259cf3610638a2c5ee08863e175b9b7b5a0800\",\"validator_index\":\"24\"},\"voting_power\":\"603888905098900\"},{\"addr\":\"0xe9f7d36334768683b85ec1df892dfd8fc389c8f6dbe0b890195d579a6e390c78\",\"config\":{\"consensus_pubkey\":\"0xa9500d87fbf98c3e5f0a5b99a6b43b5a6686b652d294a84741da82f6b8e1a3d223ca310b279cbb0d50b0b3b9bf25efca\",\"fullnode_addresses\":\"0x012d0400a877192e05261807207cc49b1b576b04b667b1e69926182ffd902255953ec6d3d6d7d580a03074a5380800\",\"network_addresses\":\"0x012d0400a877192c0524180720b310eb2306b2651dbb1c202c2a67dde8d20a7d73bf2a2542dad0e882e9ff9e080800\",\"validator_index\":\"25\"},\"voting_power\":\"112720464915082\"},{\"addr\":\"0xe1abb4ea11673aad3137052dce831eb20a1907815cb4a03ccac38ba7a9e988d3\",\"config\":{\"consensus_pubkey\":\"0xafaebb523090461229b8b26eab6345afc3d06059487e48703ed4ae744807c34959dbde85ed30e822dcbe1f1ef0103d27\",\"fullnode_addresses\":\"0x014404021a6170746f732d66756c6c6e6f64652e6e656c72616e6e2e6f72670526180720f5b2d9a0d334df6501d1e7c6bb92f15f9ecfaa43d2e1c545a9e9be030d9902060800\",\"network_addresses\":\"0x014504021b6170746f732d76616c696461746f722e6e656c72616e6e2e6f72670524180720cc8de9fb7b570bed6b8f0a41aafb22fd77bc6ba0ccce46bda426acf8f81a71560800\",\"validator_index\":\"26\"},\"voting_power\":\"112755573495439\"},{\"addr\":\"0x925ec5ab56572964dc3cc69bb86c224367dbfc186f6831c26639f9428326c2b4\",\"config\":{\"consensus_pubkey\":\"0xb8305348e1572fbaba85198ce3185b139d6fc9e23282bfd1fc6dfdcd673c5ec7d95001f2529c11463f7e1c8c0dbac488\",\"fullnode_addresses\":\"0x014b04022166756c6c6e6f64652e6d61696e6e65742e6170746f732e666f72676f6f2e636f6d05261807208f49c6d7d4c49ac7297b31cc34ed185d30934b22e6d30ef7e44a1be8435c76560800\",\"network_addresses\":\"0x014c04022276616c696461746f722e6d61696e6e65742e6170746f732e666f72676f6f2e636f6d052418072028ea9abf5fe2d80c809ba3fed52022d1f846bbf8c388a097b9050a837d0585050800\",\"validator_index\":\"27\"},\"voting_power\":\"112710491111345\"},{\"addr\":\"0x6c8a3474cb49202515d121fea0f3217d303e41f6bdc43e615f1cd90855118089\",\"config\":{\"consensus_pubkey\":\"0x97f001bb26d1e80e1da9a02b573562abb8e02c5ff2447616a1c27ab4f4756c54795a51684c9e0cb2290f8e204d2035d4\",\"fullnode_addresses\":\"0x014a04022066756c6c6e6f64652e6170746f732e6d61696e2e6d657461686173682e62697a0526180720ec699df05d5c6dd59b320cee3559a91ed4c7ce3b34ec4368de81eec867c4b17e0800\",\"network_addresses\":\"0x014b04022176616c696461746f722e6170746f732e6d61696e2e6d657461686173682e62697a05241807207146cf496c4b54631d4d75e7491d0356f663affc8f8f5c44206c88992a6058110800\",\"validator_index\":\"28\"},\"voting_power\":\"772290861897111\"},{\"addr\":\"0xb840f1cfae5aaa4b50a11a6a23e2e859717e2f355fcd614592b219fc4d4e44a3\",\"config\":{\"consensus_pubkey\":\"0xacf25b3caf7bd8a2738ed518d285df7d603ef343bebaee915b7eb1e86dec02df591604747b35e9ea110ed8d811181297\",\"fullnode_addresses\":\"0x013904020f76666e2e646f7474332e636c69636b05261807200c9ffb2abeee02eb2b6a7430b48831ba163971603ebb2e3bcb063e92b1657d600800\",\"network_addresses\":\"0x013f04021576616c696461746f722e646f7474332e636c69636b0524180720c381325a62643e3d717ffb80a520b397a3d6e4a25941ebb9dd570d85b8afd72c0800\",\"validator_index\":\"29\"},\"voting_power\":\"112692971670539\"},{\"addr\":\"0x8d5c9e82d612c390b5dea347918b6421146bb638724854300eed065cc4211a6e\",\"config\":{\"consensus_pubkey\":\"0xa7b46e42a523b296b51e8563005acf932430782245cf0b4056e4840587132e8a32535c118da770a3f59a6071dde7d6a8\",\"fullnode_addresses\":\"0x013804020e662e6170746f736c6162732e63630526180720b8d25776ffffc2dcd328df80debaa651068cf3dd7e909e962289b935298e026b0800\",\"network_addresses\":\"0x013804020e762e6170746f736c6162732e6363052418072050fb8258d65e8e55f4e683e7c1828e8bf8df41b437a03751cfa71ee09b822d7c0800\",\"validator_index\":\"30\"},\"voting_power\":\"112894213559893\"},{\"addr\":\"0xcf2a5df3737cd33344dc332416c35278431aed26ff684491b1bf7f9d19e3ee93\",\"config\":{\"consensus_pubkey\":\"0xb2522b8e28084d0d80309613c97c605758a4a340f2f8dd869e2e9ae2ea9d59d16c7d3146be98c6aebe10f1d783c1f307\",\"fullnode_addresses\":\"0x012d04002d4c9bd305261807207f70ad5146bbe4bcc0f875a6cc5341bb29f8356286526aa82a42d1e4a2e117370800\",\"network_addresses\":\"0x012d04002d4df72905241807209c010497eb6dedbf596967252ec746c864bdd7f6d5580ab8b82d917bd740ab7b0800\",\"validator_index\":\"31\"},\"voting_power\":\"113039071952557\"},{\"addr\":\"0xb3254509d1cd652d6e1ca06fd37f3d20aaa42f7faeaf297577b85cf92d2f7462\",\"config\":{\"consensus_pubkey\":\"0xb8e46bd67eb6582ad38ad3df929bb3c671412d1935b74af02a5cacb6bbe684d9a300731530dbd2bf7881c9803c32d205\",\"fullnode_addresses\":\"0x015e0402346170746f732d6d6e65742d76662d302e63612d63656e7472616c2d312e737072642e76616c69646174696f6e636c6f75642e696f0526180720a814aaa8ad4901bbfc08e75af3f0068435bd8ca134505b6d8f2c145c0e8677430800\",\"network_addresses\":\"0x015d0402336170746f732d6d6e65742d762d302e63612d63656e7472616c2d312e737072642e76616c69646174696f6e636c6f75642e696f0524180720e98c60a49f2041191ed453a3b178f5d860064c4958a48070002f41e094671e4a0800\",\"validator_index\":\"32\"},\"voting_power\":\"988864846656647\"},{\"addr\":\"0xa6eb54c274da96778a6702740a763f6aa7b02eef3d1efc2623d28289d185118\",\"config\":{\"consensus_pubkey\":\"0x955806cdced75707e8a0b4a46a90df89b4dd977fe56041ae8e9d3106f1fcf24b99d40a4175f9fb10b0293c675b541b0c\",\"fullnode_addresses\":\"0x012d04002f5b133d05261807207d9348a4e93a17dbb73b511807710415ebe2a6c2c36ab404e2d63174407e625b0800\",\"network_addresses\":\"0x012d04002f4a2bc20524180720afa4342b513585903e76217289be010a3aa877e4e7613684ec38c0f39721d4080800\",\"validator_index\":\"33\"},\"voting_power\":\"989120931426867\"},{\"addr\":\"0x1c6a051d9a5ec4cf4200bab21a794d3afe8259d625f6b78aa4d01ab4652327d5\",\"config\":{\"consensus_pubkey\":\"0x806a4ce93322c4b0e93f75ccbb3021b19e4b21d032cd6a32aef10ca99afb741892b2b8c317b772c36a43cb0c0edff29c\",\"fullnode_addresses\":\"0x014704021d6170746f732d6d61696e2d66756c6c2e657665727374616b652e6f6e650526180720780561ebf2a24c7a6c522cf90b722fadf851cb94049866998cf64e03991221030800\",\"network_addresses\":\"0x01420402186170746f732d6d61696e2e657665727374616b652e6f6e650524180720d300000c1e098811aa300a52916231960277f37e8c064f337c522c2fa391e73f0800\",\"validator_index\":\"34\"},\"voting_power\":\"771638622267253\"},{\"addr\":\"0x649127a4d1b26b4cf936f7b795917dbcb571c59c2926ae473fe4d9df3575790e\",\"config\":{\"consensus_pubkey\":\"0x940c6d4c2ef681b2623a203c70df676c9284887859757a0735ad7ba21e910757243e8a131c5a209deff02efe73596d0d\",\"fullnode_addresses\":\"0x014a0402206170746f732d6d61696e6e65742d666e2e646f7261666163746f72792e6f726705261807204f41d241aeea3d0652651dcb2bfad447910b50de7f5426fc773d5a7d628035530800\",\"network_addresses\":\"0x014704021d6170746f732d6d61696e6e65742e646f7261666163746f72792e6f7267052418072000880e9f6a43d9af18b9fcb7e03560505bc01c48aaf058ee0fbb56f5c47abe450800\",\"validator_index\":\"35\"},\"voting_power\":\"836400900893015\"},{\"addr\":\"0xb87476d8877cfc324a520cef4d0cd6e42e26ec3ce613a8127220e2e444561e16\",\"config\":{\"consensus_pubkey\":\"0x810184f96a60655c340d254354f3f1b7c2b4a59530e5e8b9ed8765aefe4525a2d80393030e3be609fcc54742ff6a5186\",\"fullnode_addresses\":\"0x015904022f7473772d616d73312d6170746f732d6d61696e6e65742d76666e312e6e6f6465732e6173796d6d65747269632e72650526180720e51632cf8004506fff126942cda2a3e0fe6b8ca1edaac4e1fa5a5383a2b3f0370800\",\"network_addresses\":\"0x015904022f7473772d616d73312d6170746f732d6d61696e6e65742d76616c312e6e6f6465732e6173796d6d65747269632e72650524180720fd0d681d4aa63696df5847ed36d72415e580fd097889b9f2be3b65e31868d87d0800\",\"validator_index\":\"36\"},\"voting_power\":\"382419147485417\"},{\"addr\":\"0xbe4e66094c14a8c69361173fbd6694279db5fd8401bcb1d9c5df066755820a30\",\"config\":{\"consensus_pubkey\":\"0xa04613f8d8e7ae7a856cb3dca534c31ba9c5f7f1334e2da38933dfa7a8ba6198ac7ad4262510e0dfc0e29a1b0f6cde1d\",\"fullnode_addresses\":\"0x012d04000d7c2ae30526180720c5dfee7bf16baae3dc40ce95828f4b45717c952fd2fe1b10c31c4886a1ed2f650800\",\"network_addresses\":\"0x012d04002bc8cb0d052418072060e8e4dbc6de25194c0cb012866f4b6e154b2cc72a5ce893aa85fe5eb1dfca3a0800\",\"validator_index\":\"37\"},\"voting_power\":\"111689568709419\"},{\"addr\":\"0xf08bb83cf89d299e4cddee7ef987b850a35a399900ba22860cc1553da3682a84\",\"config\":{\"consensus_pubkey\":\"0x95197a9748f3f53163e060248c9793b1ebbcb1211e365b555da08b59682353701c457129c9a31ad93ea901ebf0ac06ce\",\"fullnode_addresses\":\"0x012d0400a7ebdedc05261807200d7904e0f3b6aa2b1c8475b06db994e65e1268fee2a23c221fcc00dc19bd80710800\",\"network_addresses\":\"0x012d0400175850d205241807204da04f388b8428746842a969cc8a1515eb3eea08705bee0da41c60370709f72e0800\",\"validator_index\":\"38\"},\"voting_power\":\"112695662661625\"},{\"addr\":\"0x6a1d3313a58719cf5abc1aaee6b4b74bc7e2c69036a8a02f02eb4f3ab4a3d678\",\"config\":{\"consensus_pubkey\":\"0xa10785eb745bbdea89b74a49f0df50f1d5ca5d1f07dec655bb745db1ae442076e2a10dde1f44639b2599e8b4b7f2ab69\",\"fullnode_addresses\":\"0x013f04021576666e2e6170746f732e626c6f636b6875622e6a700526180720e3430bc567682235924291181123d27944faafbb7b8ee2d61178558974f48d570800\",\"network_addresses\":\"0x014504021b76616c696461746f722e6170746f732e626c6f636b6875622e6a700524180720c5f1d24f85c892781f4218e100d5ad92ba05650369ff23833bfec4ccc6f1347d0800\",\"validator_index\":\"39\"},\"voting_power\":\"113078516469473\"},{\"addr\":\"0xb225277ba076b6620447f7b10abb30911966eb66d25fb526b7f09c2227425a11\",\"config\":{\"consensus_pubkey\":\"0x92e95c028f4218ec912eff1120b42c277c7e37fb48a205d3a99f72ffe278e2939edb14e8ea924f44f428bd1dff00a4d5\",\"fullnode_addresses\":\"0x00\",\"network_addresses\":\"0x013904020f6170746f73312e61706570692e696f0524180720c6b140f4b8652f1d22f74a07fda3b07afb23bb861f80201c12f49a9a05d9bc0e0800\",\"validator_index\":\"40\"},\"voting_power\":\"190963317898448\"},{\"addr\":\"0xc29a231581f243ddcbf97de8b93c8aabb466dd6912ce5ba12579ff2f13cb8da5\",\"config\":{\"consensus_pubkey\":\"0x819fe1bb05c18e016e00e15819d5f64ab3fabec524c7f7801efe82e6ffd90a14ba54fd9d4d4c0237e083e17e842c956e\",\"fullnode_addresses\":\"0x00\",\"network_addresses\":\"0x013904020f6170746f73332e61706570692e696f0524180720f1f82933d38579be0406ce803b3fc7ed69c231059ba9013030a68a2fd9f254380800\",\"validator_index\":\"41\"},\"voting_power\":\"190987789882018\"},{\"addr\":\"0xfc307ecd61ac025f5ec1828d2114d11b474b4d8a1b0c228c38614dc96b940048\",\"config\":{\"consensus_pubkey\":\"0x91784bbe2571fafaa761be86b0359becccbeaea3814f8def2217a535e5ad7a7bf379a2daad2043134bf4cc6a42f679a6\",\"fullnode_addresses\":\"0x00\",\"network_addresses\":\"0x013904020f6170746f73322e61706570692e696f052418072050df4bd4e18a074f9c7f1092ca36b23b0fd4b592b7065381b00fa392c7135b050800\",\"validator_index\":\"42\"},\"voting_power\":\"190965484862942\"},{\"addr\":\"0x371dfdee9fbecaa358683936c5946aa28393067fa60e1e185c4250da461e15cf\",\"config\":{\"consensus_pubkey\":\"0xa5a7d87c6037d4e98c4003459e63c88de7ca99b55cffaa36b1f8162866eb5bbf1978ecb13b09c66571f8ccd0dd3e2d94\",\"fullnode_addresses\":\"0x014004021676666e2e6170746f732e647372766c6162732e6e65740526180720df0eb85221ed6f116dd5caa1e7461d2ec2e3c6be4b252ac90246b3384e46d96d0800\",\"network_addresses\":\"0x014604021c76616c696461746f722e6170746f732e647372766c6162732e6e657405241807203a4def33aecebb139d4bf57f697e305f9241885cb30acae23f7ac9e354e4b95d0800\",\"validator_index\":\"43\"},\"voting_power\":\"156811969457332\"},{\"addr\":\"0x9da88926fd4d773fd499fc41830a82fe9c9ff3508435e7a16b2d8f529e77cdda\",\"config\":{\"consensus_pubkey\":\"0x8301cedf6fe6b91141e8d6dfe6291501c5cc2d849424a512e136472eb1ef3683054a47f206f36a65d0bfbccd2fe93214\",\"fullnode_addresses\":\"0x013b040211666e2e7374616b656170746f732e636f6d0526180720998fc9251996ab489b9a2ad89353a7b7ab3df5eddc39e090e10719185076c6740800\",\"network_addresses\":\"0x013c04021276666e2e7374616b656170746f732e636f6d05241807201ab75bf68e5123d816d70ba04ce4b1e7a7dc88fbcfd52afdc457ed3970e2917d0800\",\"validator_index\":\"44\"},\"voting_power\":\"1098906396773872\"},{\"addr\":\"0x8e943e68e8e4a1ebb7e5a250b081af507d40e616283f38d2d2a2a4b6523c02ac\",\"config\":{\"consensus_pubkey\":\"0x896994a59398f453d21f259f9b32c4494d8b971c33ec5b21647a065c4af43fd2fe3d7534d5d15ce4e80102501c4f400c\",\"fullnode_addresses\":\"0x014804021e66756c6c6e6f64652e6170746f732e6469676974616c666c6172652e636305261807202e3e0280c3a1f64945ace65ed6042ad25ff2a9520e85c8380290465ec2793d350800\",\"network_addresses\":\"0x014904021f76616c696461746f722e6170746f732e6469676974616c666c6172652e636305241807202661d2c95f73af09ad8e28159223639a5d0f69ef8a80880045f24224ee57ac1c0800\",\"validator_index\":\"45\"},\"voting_power\":\"112716488643224\"},{\"addr\":\"0x46b51b26710797faed701722bfc809386110c9720328f2b431e193cb5dc161f7\",\"config\":{\"consensus_pubkey\":\"0xb8336cb70d03881217aa408cba1cb40a415c9262775c3ac9a54a7d4cb1021bdb520cd3eda9b9811bbe24c233ca4b1699\",\"fullnode_addresses\":\"0x01530402296170746f732d6d61696e6e65742e6170746f732d66756c6c2e636861696e626173652e6f6e6c696e650526180720c321bc56afc962a7b12a381c5bbb6863b16d3b0132d90be8d86c76ba6121b1160800\",\"network_addresses\":\"0x014e0402246170746f732d6d61696e6e65742e6170746f732e636861696e626173652e6f6e6c696e650524180720eecf8fd6ba5f2fd886bad34913bc2045552b5757d8fe47f5fb4122b0cc1705780800\",\"validator_index\":\"46\"},\"voting_power\":\"574198779766370\"},{\"addr\":\"0xf2b6feeea4546648c257c7e33ff4f0aa8db3bb2949cca065c9db015478363458\",\"config\":{\"consensus_pubkey\":\"0xb7532f11ccb1d97ba4ff9ff2bac66638ff87f776a5077e3900282e8e03d8ea1205e031fad0dc0da35b6f99d72977cf81\",\"fullnode_addresses\":\"0x014704021d66756c6c6e6f64652e6170746f732e7175616e746e6f64652e7465636805261807205ef7eeb152008d69e49b43286c4380512f392ab2b3ff1267f5bcd283f148a4000800\",\"network_addresses\":\"0x014804021e76616c696461746f722e6170746f732e7175616e746e6f64652e7465636805241807203ffd66c98ce69e5ef6d5834ef47626408d820090d75dd99f937404cdf611c6570800\",\"validator_index\":\"47\"},\"voting_power\":\"112762387752539\"},{\"addr\":\"0x81d41a31fb5d3f827d188511e6fca1ddbed6cfa0ffbd46fa6d84a7adfe59f356\",\"config\":{\"consensus_pubkey\":\"0xa26f07052d6ebb154c1debe66fa5a0ac9224ac63d0e7ee38387139e76904f1958e845b25e0e0080874b0667283eff277\",\"fullnode_addresses\":\"0x00\",\"network_addresses\":\"0x012d040050be8132052418072085078010bf8ac6581a58d3da584825245faecdde2d998ce7a0dddda98729a6080800\",\"validator_index\":\"48\"},\"voting_power\":\"988775164891347\"},{\"addr\":\"0x71debfa733376c4f2dc8970de8962931fe107c7dc1daad3bf189101bfd4adc4b\",\"config\":{\"consensus_pubkey\":\"0x978340dbc74d21300f32c8b35f52179847196a7c3c27de7263d2304dec2ad78eefd7f45c04201af7c468bf1426ada284\",\"fullnode_addresses\":\"0x014d0402236170746f732e6d61696e6e65742e66756c6c6e6f64652e6a7573746c73746e2e6465760526180720ffd6994f31ec642f84cdc159fc2f313d3d95afd56737dc1de1aba39d467db65d0800\",\"network_addresses\":\"0x014e0402246170746f732e6d61696e6e65742e76616c696461746f722e6a7573746c73746e2e646576052418072058ca3e58bc16bd213ebed2714b0dd225d495b51f1df4518e8b00539e2e3b11230800\",\"validator_index\":\"49\"},\"voting_power\":\"112740766620794\"},{\"addr\":\"0x4cc22e5d2e84794c3c672b0b34145898ee971a4ff042eabae23627547f6dac80\",\"config\":{\"consensus_pubkey\":\"0x8af9cfdfd49dcc3a1a5d18d060d8ab11c82ff9dfe30a31a7cac15ef13961445b40a061eb54336c19893f7929f9106e4d\",\"fullnode_addresses\":\"0x015104022766756c6c6e6f64652d6170746f732d6d61696e6e65742e70726f76616c696461746f722e636f6d05261807207394f7d5b8e4103ae9dfc0bccd768ad65f7900104e336212db51e495a84e0d3b0800\",\"network_addresses\":\"0x015204022876616c696461746f722d6170746f732d6d61696e6e65742e70726f76616c696461746f722e636f6d05241807209546817e02baf372047aa81577b298c0edbd95c528ad9fdf0260bc646a8ca2190800\",\"validator_index\":\"50\"},\"voting_power\":\"673614282332190\"},{\"addr\":\"0xef191e643c2ed2d103de4109a506e020f5dde818cbc1ffe5e4ee36328cd22e9b\",\"config\":{\"consensus_pubkey\":\"0x963d5f5dd0179a9ded5e1af7e450786e93f41ff01b1d74baa0f776a8e5b72924839d5c4e4fd868b127315e19d595312a\",\"fullnode_addresses\":\"0x014504021b66756c6c312e6d61696e6e65742e6170746f732e7032702e6f726705261807208c7ad723dd13cf91afb6b976c31db785113f7e95d1fec8593c9ac8bbfaa5dc7e0800\",\"network_addresses\":\"0x014404021a76616c312e6d61696e6e65742e6170746f732e7032702e6f726705241807202e37a37baff5767e45c200c3b724e62f0d4870ec21fe055a65951efc1cd63a740800\",\"validator_index\":\"51\"},\"voting_power\":\"945416719858982\"},{\"addr\":\"0x209154f6e735562ff13b963b91588039a162fa95f409c068f917f27b762dfff8\",\"config\":{\"consensus_pubkey\":\"0x99e2fa7fe9fefee79ce9c7a106417f44107baf70fb9c8bb1f0492a3d21898a852474915711f6d2499c0e807f23dcdeba\",\"fullnode_addresses\":\"0x014c04022276666e302e75736365312d312e6d61696e6e65742e6170746f736c6162732e636f6d052618072022ad01f5c42a6da23c229475ce97dc5858204d0acd1dc2def457ee8f9c1a86500800\",\"network_addresses\":\"0x014c04022276616c302e75736365312d312e6d61696e6e65742e6170746f736c6162732e636f6d05241807206156354358cd26874f04792465861c025e0894d8e198c0bd027834d6597a0a2c0800\",\"validator_index\":\"52\"},\"voting_power\":\"880087562261597\"},{\"addr\":\"0x9a41af5c002f91dc29cb2843ab823e3d6cdaa6cc86e6331646a4f1328609a744\",\"config\":{\"consensus_pubkey\":\"0x91faace19486d9284c3137b4812e42738731f3d7b5775d473f820ecb4ce45470199ab2ea90554263df9b8028fdedf5eb\",\"fullnode_addresses\":\"0x014404021a6e6f64652e6d61696e6e65742e6170746f732e6b696c6e2e6669052618072038c7ae31dc43715db025f377220199b643a2efd915293a82796bd9f2b8e764170800\",\"network_addresses\":\"0x014904021f76616c696461746f722e6d61696e6e65742e6170746f732e6b696c6e2e666905241807209f494f6dca7cd6b9ab007be4b69e4f8c5b23a21c358aa1e78a3aeac35a38de6e0800\",\"validator_index\":\"53\"},\"voting_power\":\"815995007555816\"},{\"addr\":\"0x483cf8942c76d86ed28a9849940abdea14952a551be84c38c844208e13d976d4\",\"config\":{\"consensus_pubkey\":\"0x8e0330b1be6c245f769e2a6f150ba3273a86355c52b9263995dcc7e1dfd928fa75f36723176f775bd20910f65a9055c2\",\"fullnode_addresses\":\"0x012d04004115098c05251807202722e1aeaf68eb3368984eddf05199e0284e54aefc989399098c3848d34500480800\",\"network_addresses\":\"0x012d04004115098c0524180720df86b51ad92950ba4757bd0bcfca9f816dc4875ad6996c8c26423eaafda4a3700800\",\"validator_index\":\"54\"},\"voting_power\":\"112711242739970\"},{\"addr\":\"0x3eaf3ebc49555c705c34ec1ffe77404bdb7383b388476c36538b92b7b1b806c9\",\"config\":{\"consensus_pubkey\":\"0xa43ea6c2d3b5c6d87b51506aa1b7d477936aca06f7b3e7d68c4e839bf97a2360331e74c0eac41f0eb2d2971b28793554\",\"fullnode_addresses\":\"0x014c04022276666e302e65757765342d312e6d61696e6e65742e6170746f736c6162732e636f6d0526180720537c398001a4d903f86739307979c688cd49032ca980584fa1f62f1cb6e781480800\",\"network_addresses\":\"0x014c04022276616c302e65757765342d312e6d61696e6e65742e6170746f736c6162732e636f6d05241807209fcf681bf5b6f5d6a03e4ce4b0a28bbfea1a4bd390412432c09937b731596d550800\",\"validator_index\":\"55\"},\"voting_power\":\"991389778274230\"},{\"addr\":\"0xb4a4f1ef8b0702d85547dc444571a473f736e1205a86db36dad13815ad9bbbf6\",\"config\":{\"consensus_pubkey\":\"0xa5a4d90b3d84e3bdc23fa47f6f010f90d4a082bf2d903f299a10b3fe309a9ed1964892985abd864bc3a83e68c2cda66e\",\"fullnode_addresses\":\"0x014404021a6170746f732d73702d76666e2e62776172656c6162732e636f6d052618072028b9f4b32b0ffa3d5b1d53b6b93cf05e8d0aad443f5e08d592dd0710d05a0c210800\",\"network_addresses\":\"0x01420402186170746f732d73702d762e62776172656c6162732e636f6d05241807206bbdf23daeba081c3b4d019aa0bde9e2835fa6ddeceb4f2597529c89428c1e360800\",\"validator_index\":\"56\"},\"voting_power\":\"945217322156245\"},{\"addr\":\"0xa286a9187c86b4a3cef60478e5c61bb45757b795a8e6577ebbf0fa990db574cc\",\"config\":{\"consensus_pubkey\":\"0x83ddf24d5759259b40a61dc1a1ec2ebc9433504ecfd3033d7805c795506dbfeb03085df3b66c231036abf8e0cb24dd5b\",\"fullnode_addresses\":\"0x015f0402356170746f732d666f756e646174696f6e2e70726f642d656b732d61702d6e6f727468656173742d322e7374616b65642e636c6f75640526180720caf90fdcd8cf327a17b3e03b26e0f62a31a494a313c710b722f8c74ff877476d0800\",\"network_addresses\":\"0x015f0402356170746f732d666f756e646174696f6e2e70726f642d656b732d61702d6e6f727468656173742d322e7374616b65642e636c6f756405241807206a1c7b94f02a75a8d1934e9548abfdf666b04c7301c2aef516248c4d02af96240800\",\"validator_index\":\"57\"},\"voting_power\":\"785064243112281\"},{\"addr\":\"0xf05d2fe6618a3cb4258e94f2da24c1ee71ae4e7942b4f8b5836ad5267e59568f\",\"config\":{\"consensus_pubkey\":\"0xa17afb962545cc71548c859af67ec5039db81a0761978b0c948f35b75034470da6cb30a4b249b63c5ce567b4489f47e5\",\"fullnode_addresses\":\"0x014a040220636e65756e6132766a37316d64656632713632672e62646e6f6465732e6e65740526180720385bc8a1f3769d87b80dd83884e5a3fce1dd825f3476ef4a131c51d0ebe91c1e0800\",\"network_addresses\":\"0x014a040220636e65756e766d337632313273346c386c7634672e62646e6f6465732e6e65740524180720debe55fb55f1fafc768dd6967d08948f9974ca44901502c9f2076997e4b733520800\",\"validator_index\":\"58\"},\"voting_power\":\"846906595762874\"},{\"addr\":\"0x8be2ba62bfd783e5fbff57a07acf2a9a95f4d234b3729fbfda9c63f3f42fb78f\",\"config\":{\"consensus_pubkey\":\"0x9538315379ee817e621adf1c3ffb2890063628eb55276ec25288de5a1946ecd2d8be91e3846408947f6a8ef6b00600f4\",\"fullnode_addresses\":\"0x01630402396170746f732d6d61696e6e65742d6669676d656e742d76666e2d312e7374616b696e672e70726f64756374696f6e2e6669676d656e742e696f0526180720c6fde909bcc5a2728aade9b20037d0323151daa3420d4eb2dc0986438b51b8730800\",\"network_addresses\":\"0x016904023f6170746f732d6d61696e6e65742d6669676d656e742d76616c696461746f722d312e7374616b696e672e70726f64756374696f6e2e6669676d656e742e696f0524180720d72de74ccf8828a01521418b9b6a7495d043fcf22ae171cf115a6ff26e0d3b0d0800\",\"validator_index\":\"59\"},\"voting_power\":\"819627654195306\"},{\"addr\":\"0x401a881d9770f054a1b8cd6829f3d65a040bbe9b387ebcce50bddf0f853077d9\",\"config\":{\"consensus_pubkey\":\"0x9921070a2249eeca97723b3e40aef9f793a40903705496a2632230d5da1b2c53a8efcee97803ebed544df9477301b41e\",\"fullnode_addresses\":\"0x015904022f76616c696461746f722d66756c6c6e6f64652d322e6d61696e6e65742e6170746f732e6665726e6c6162732e78797a0526180720f19f3422d2b3bdb72a327762ed4e07d6788422f1e99b1705ea547602014f6d580800\",\"network_addresses\":\"0x015004022676616c696461746f722d322e6d61696e6e65742e6170746f732e6665726e6c6162732e78797a0524180720c63a3ec5043dec7bdc0c227d7ef416792e61654a315bead1bcc79ec95abfda130800\",\"validator_index\":\"60\"},\"voting_power\":\"143321615337144\"},{\"addr\":\"0x8dd8b23892be142c2ec4b7e1427584c97403e570cde4e6d9a81d2b220c884af5\",\"config\":{\"consensus_pubkey\":\"0xb37ebad23bc0c804392516319c3e65629bf61de77338d140de14c603002c9ea1f079e3e70e3dea53abcaa54916b618f8\",\"fullnode_addresses\":\"0x012d04003f2373910526180720f4e05d83bbf653e860eb208a46b47888ca5dad493ed125a54139f82df7aa6c6b0800\",\"network_addresses\":\"0x012d04003f22fa2e0524180720f1d7b741c64239502de71ace5da3d374ea411b18b3b576b680a090510c913c160800\",\"validator_index\":\"61\"},\"voting_power\":\"1002613806840793\"},{\"addr\":\"0xff3e9c10dd3781a1e0750a75ae9e5b04133cd7e8ca18b9936ffcf3b2a2538a49\",\"config\":{\"consensus_pubkey\":\"0x8b2c1cb46fa7bc2348852ef341dc1516b5a7934e158ef761e3ccd45f5d5aba0ddc5b77e9d69d3cca153b20635ade6056\",\"fullnode_addresses\":\"0x013c0402126170746f732d76666e2e6c676e732e78797a0526180720786514b4acf580901f4040ccb0c3aeff4709f2b2709a180d01c6b156e1a694500800\",\"network_addresses\":\"0x013b0402116170746f732d766e2e6c676e732e78797a05241807207956c2c66fd0d7d2146f85cad157c72e88c9ca28e5d32c3b28813157b1e5aa180800\",\"validator_index\":\"62\"},\"voting_power\":\"570170808974055\"},{\"addr\":\"0x6099edbe54f242bad50020dfd67646b1e46282999483e7064e70f02f7ea3c15\",\"config\":{\"consensus_pubkey\":\"0xb017b62a576df41b797d31277fb9e992b614cb2742ea1bf005479b62a537daa52f6455c6237d5f548c22b907a4cd0ab4\",\"fullnode_addresses\":\"0x014404021a6170746f732d64702d76666e2e62776172656c6162732e636f6d0526180720f25e9c09250f95df0af9437bb47440eda0ff7c12dde82238aa090ac733e67f480800\",\"network_addresses\":\"0x01420402186170746f732d64702d762e62776172656c6162732e636f6d052418072015c2b558164eb213b20b28316220bf72e811ac22c4fd4b465b78104364130d5a0800\",\"validator_index\":\"63\"},\"voting_power\":\"1140555479827383\"},{\"addr\":\"0xda418307cff595ced2af5eb471ec11b1ad6a4907ef57d6e2eeb253bdd5bd9d0d\",\"config\":{\"consensus_pubkey\":\"0x84f5d5d327e4656eff9a6e826f2db201fec8abe100705e026bc36c075421fd1c60085011bfa0024885fafdbf56afe81f\",\"fullnode_addresses\":\"0x00\",\"network_addresses\":\"0x012d04004f7fe0070524180720f7ad3c493cd06c31ea3e20092743d033e3ad2db394b0aa2197314778d60428450800\",\"validator_index\":\"64\"},\"voting_power\":\"804926787180278\"},{\"addr\":\"0x2ded75e99c6efbe143a9648a3e88ebf9d0cf249b2af44d510bdd0287e8adcc79\",\"config\":{\"consensus_pubkey\":\"0x8000b5beb0a9798110ccec1f012ed0a15a620c4ba642d309e3365e72e05b49a1ca9716777e812732a44e8f0c8b282437\",\"fullnode_addresses\":\"0x00\",\"network_addresses\":\"0x013f0402156170746f732e766573746967652e73797374656d7305241807201cb653e043d29fa8583483c6699783ec42b3ebd5ef23fba97a924e2545e2bc3b0800\",\"validator_index\":\"65\"},\"voting_power\":\"1055210882880243\"},{\"addr\":\"0x7ba7dd0aff5acdc056a2f1f7f1fb24bf1e7d3d6909c33d45f8c2333b13bd2f80\",\"config\":{\"consensus_pubkey\":\"0x90f6f73c297e4a1e7b8b9ff1024e6c39afde7f1ddd7fdf9b18271dab1fec949b8305df53f3053bac4b8ffae5b9826b8e\",\"fullnode_addresses\":\"0x012d0400225e5f400526180720ce9debb8ad83d7f615341b09c9832ba6d41fe7eef6c88f62f5e02957d0d1d2390800\",\"network_addresses\":\"0x012d0400225e5f40052418072052d2e01fdb974c18eefd86c3ed9e1d73cf8e1a9a0b9f577e107c212b5777933b0800\",\"validator_index\":\"66\"},\"voting_power\":\"335399891369000\"},{\"addr\":\"0x9bfd93ebaa1efd65515642942a607eeca53a0188c04c21ced646d2f0b9f551e8\",\"config\":{\"consensus_pubkey\":\"0x8001dc62bc59553db229a04c0a37fbfbbe1245568b70bca598a6610cb98c8deade1a9d272bf15042d1558ec6dafc0228\",\"fullnode_addresses\":\"0x015904022f7473772d647562312d6170746f732d6d61696e6e65742d76666e322e6e6f6465732e6173796d6d65747269632e72650526180720f4da6c0c2c920220b07418e9161071795f2dfd6ea80f799795e68880f79c93430800\",\"network_addresses\":\"0x015904022f7473772d647562312d6170746f732d6d61696e6e65742d76616c322e6e6f6465732e6173796d6d65747269632e726505241807204a94c9dfca6395ed0d4ff7dd6edf30b42054617e4675ee22ebe5fa77215ea05a0800\",\"validator_index\":\"67\"},\"voting_power\":\"1448049634847939\"},{\"addr\":\"0x2537e9d461d311dc6f1dee690f093b4e353f472abc2493c64275a3d5572532cc\",\"config\":{\"consensus_pubkey\":\"0x99b09a09cb154d0a4e4449b6b3db7afdddf2daa733af9d9bca09c159c2a82684809148e17cc558e6c1323df5929a9a3b\",\"fullnode_addresses\":\"0x016504023b6170746f732d6d61696e6e65742d61706f6c6c6f2d64702d76666e2d322e7374616b696e672e70726f64756374696f6e2e6669676d656e742e696f052618072004989f34811b2eae5837c58e6fc0501513b57e638289935c87e28d838a732c1f0800\",\"network_addresses\":\"0x01610402376170746f732d6d61696e6e65742d61706f6c6c6f2d64702d322e7374616b696e672e70726f64756374696f6e2e6669676d656e742e696f0524180720f692c242c6d6befe576cdcc00790dd83a2ac7e61b570ce44151ff3aa20caeb0e0800\",\"validator_index\":\"68\"},\"voting_power\":\"216749376853690\"},{\"addr\":\"0x6d00d52f94579e51308ae83841b5133e3a7e93b51fcd8cf338d766e3f0331026\",\"config\":{\"consensus_pubkey\":\"0x81b1e39deab26bc1761b9b1b23cdc0e84f4b165f14507723bf7be7e1f90a91a2d5026c4768fff10e21e04b0cb5af5cc4\",\"fullnode_addresses\":\"0x012d04007708bc030526180720072126b04b265a6b3e13a8aa53df74f570c8c29f5ff234dc63c89205197256240800\",\"network_addresses\":\"0x012d0400be5cc8b10524180720522f82ba8363457df95fdbbcc9f3a760014d82da40877902b56b904ab343747c0800\",\"validator_index\":\"69\"},\"voting_power\":\"1003337240216731\"},{\"addr\":\"0x39b844cb561d2a04c800164465e2eb2c2ea520499d718c35492244346da07b5f\",\"config\":{\"consensus_pubkey\":\"0xac575d5e206df18ace40438fd0b57feab67db4b84890bb142389c822827c185c9e12713d1f4e8ba3f0373b56feed4fef\",\"fullnode_addresses\":\"0x014804021e76666e2e6170746f732d6d61696e6e65742e7477696e7374616b652e696f0526180720afcaedc0521813dcd3ebf48a27201f09eb7fe62a0717fa968a97d5ef028a17020800\",\"network_addresses\":\"0x014704021d766e2e6170746f732d6d61696e6e65742e7477696e7374616b652e696f052418072073bb5fde4a22c979577faefecfd290703b82a3681b34bd2e037a700ea02388630800\",\"validator_index\":\"70\"},\"voting_power\":\"920799023599312\"},{\"addr\":\"0x7425cde20dc18a8e5e169614c47c0e4435fd1b6c475efdefbdbbb73785d331e3\",\"config\":{\"consensus_pubkey\":\"0xa9444b0f2845f4a159465877fbea1bc8aabd760d946d2a08b4894e0ab2727aed45d19934045285c5fc9915e31c771572\",\"fullnode_addresses\":\"0x014304021966756c6c6e6f64652e656e766f79732d6170746f732e636f6d0526180720fd3c256cd01390bfcf123983532dbd1402652204099ac67c1d3e91f0e3a7ad3c0800\",\"network_addresses\":\"0x014404021a76616c696461746f722e656e766f79732d6170746f732e636f6d052418072093578af40d8d96eaaf80c2065201806beb88b32e276a28c5b5d80a15d0dbc2430800\",\"validator_index\":\"71\"},\"voting_power\":\"890316478164710\"},{\"addr\":\"0xfaed6de6eacfb745f602d61a1ad559b0dda7fb2723d7d168c50b94687247a8b0\",\"config\":{\"consensus_pubkey\":\"0xacfcd3f31e306b625b737b24ed1bcf4b12b9a1a592a8ce1b686a20183a4dcac94dbd4c76135de3799e31db8b79fecd6b\",\"fullnode_addresses\":\"0x014204021876666e2e6170746f732d6d61696e6e65742e6134312e696f0526180720a5a4a7b8c40779bf761df71ea2da33961285bbb99dbfcb7c8dac5fd3172b974c0800\",\"network_addresses\":\"0x0141040217766e2e6170746f732d6d61696e6e65742e6134312e696f052418072052acbe0ebca7fb8af162117f61522f08d9e06ebdbb25f86a8ebed9d1d14bc6390800\",\"validator_index\":\"72\"},\"voting_power\":\"885602967443685\"},{\"addr\":\"0x15d241369552ece871a16d865a4e9b96f5e6e6f8c7db5478e89af17845969c02\",\"config\":{\"consensus_pubkey\":\"0xa6d2af57193cf144ec918882fef758576f206841d3149e4ef2cb806fd434ea807f81bc653f506c2ccd73a3fdd9f78c7f\",\"fullnode_addresses\":\"0x01420402186170746f736d61696e6e657476666e2e6d69726e792e696f052618072039df8ecd826c37753af70a9641085e978280fce963d1ad2fe0d30f616d5d477f0800\",\"network_addresses\":\"0x013f0402156170746f736d61696e6e65742e6d69726e792e696f0524180720921164018679c764e6889809dbcc9bbcea45717f9dbd2f747614a10c528cd82a0800\",\"validator_index\":\"73\"},\"voting_power\":\"992580133718454\"},{\"addr\":\"0x189093e65faaea1d0c1c367b7c78b4d2ea569fc3d1e7d20b226eec0361b1a116\",\"config\":{\"consensus_pubkey\":\"0xb9ab4a8dcb8af068d349cf7842007f4484598e0ab9d1d2e4a68ce99d9850a319f06492ce53f1fd772404a15be667a409\",\"fullnode_addresses\":\"0x01400402166170746f732d666e2e6861736863656c6c2e6c696e6b0526180720a4bdf4a294da5858cc6a15901af1a115c6715ff3b0c150d46ce4051dde1cbb4d0800\",\"network_addresses\":\"0x013f0402156170746f732d762e6861736863656c6c2e6c696e6b052418072025a5b33c0216a72b70ea7ffc01b6ac995f47a440a21a0012723ad5d7ee72d9650800\",\"validator_index\":\"74\"},\"voting_power\":\"992695103159083\"},{\"addr\":\"0x550fe3956e44112599b8410404e0977e74cc5bcb59a11b0706da734cd0f9beb2\",\"config\":{\"consensus_pubkey\":\"0xb6552006b0777da4012327b5330f1b615b0c26c5f0fde8aecf2da4fca9451f782b2517f444d953fd01c877b9ebbf8949\",\"fullnode_addresses\":\"0x012d0400d45f335b0526180720ccb91f858a6b2e552984be00dd07f87617ec783deb2ffcac3a37d9f028e00f2c0800\",\"network_addresses\":\"0x012d0400d45f335905241807206915ad216c9624593cc42d9f354fdaf0f3d29390dd283c0f728658b692f8a84a0800\",\"validator_index\":\"75\"},\"voting_power\":\"992042638631531\"},{\"addr\":\"0xa4a00989d8ecc6d116b2283503f58de94d7fc33fff9e28010868abeb70d7d051\",\"config\":{\"consensus_pubkey\":\"0xad727f7d91704e234ea8f9c694b85b750258052d5e33b758801d3b9a878bd8f5aea0bbe8dc611584b7a75e4ce534bcec\",\"fullnode_addresses\":\"0x014a0402206170746f732d6d61696e6e65742d6e6f64652d302e6e6f64657265616c2e696f0526180720b6efef1ce4bb0245a169b5fe15ae186eb84b176023d789f51d0deb5661c68b420800\",\"network_addresses\":\"0x014f0402256170746f732d6d61696e6e65742d76616c696461746f722d302e6e6f64657265616c2e696f0524180720f768970a0d733f3490ee37dc518e04cc1134b96e57b720a8625796cddc8711750800\",\"validator_index\":\"76\"},\"voting_power\":\"992856141783139\"},{\"addr\":\"0x4c7c21084620f9e55f50f292d1803e5fbcf55c6d850b24b5e64efef08d2aa428\",\"config\":{\"consensus_pubkey\":\"0x8e6f5f9640e5ccd80074f50c245d1b1abdb6ee73919599fd8d69e3b85bb7b21ca321b1e2a3a2b12351358704bb5d66f6\",\"fullnode_addresses\":\"0x00\",\"network_addresses\":\"0x013a0402106170746f732e6c69646c69642e78797a052418072099070b861faa33fd581dc17f590c4bab852f9e621248e948f2edca6e63cd597b0800\",\"validator_index\":\"77\"},\"voting_power\":\"1683291592053713\"},{\"addr\":\"0xddf23883328d39d8cbb4fad97f0e4bd45827ea999b66aa2a1cffa76615b9ef01\",\"config\":{\"consensus_pubkey\":\"0x95aec1e70766b03f8afa773ef6cdc297354ae4cf9667ec359298925caef4e686ccb42f0fe893b44df0deb289a2b1071f\",\"fullnode_addresses\":\"0x00\",\"network_addresses\":\"0x013d0402136170746f732e74616c6f732e6e6574776f726b0524180720d119f4bf42ca8e116f56e6c5a11acdd9781b7f7059ce62e65ed521f1b18e472b0800\",\"validator_index\":\"78\"},\"voting_power\":\"254355669132368\"},{\"addr\":\"0x881f164c09b7c8032fde6f8ea0de2ab839becf391556b5650eb75a36a6f52c35\",\"config\":{\"consensus_pubkey\":\"0xb63f49a762d4f808ee2b5e06c23e6f77db94717ad741bab1ab069ced7ce88a3042b34627b317f18951c4b535655e5b51\",\"fullnode_addresses\":\"0x016604023c66756c6c6e6f64652e61323964303731382d633038662d343866372d383036392d3264646337343063363039362e6170746f732e686572642e72756e0526180720a5c7300487669d6fcf4c3b551b96d22fc0e1ef8ce1eee1a49f6c99e6483da5650800\",\"network_addresses\":\"0x016704023d76616c696461746f722e61323964303731382d633038662d343866372d383036392d3264646337343063363039362e6170746f732e686572642e72756e052418072013fb4ce57683c4eba1aa64d17f9663db8ce1264d8cb0b503650eb23cf0b337440800\",\"validator_index\":\"79\"},\"voting_power\":\"440078314214867\"},{\"addr\":\"0xeb87b07f24f6111b5ab41ef30700ad9da780454bdf257722a100e897076a67f\",\"config\":{\"consensus_pubkey\":\"0x993c998f44be3a1345d8e71291032fa45de8deeb7fc9e8509f8968f951dd164bcb87853548113fbd9490500c4105755d\",\"fullnode_addresses\":\"0x016604023c66756c6c6e6f64652e64323931393135342d623262642d343266322d626537642d6536306166306435393435612e6170746f732e686572642e72756e0526180720a7c066ca15a7e0f7c1765a1e5c3b81592d4c579dc28cee7a15de8782b85f31410800\",\"network_addresses\":\"0x016704023d76616c696461746f722e64323931393135342d623262642d343266322d626537642d6536306166306435393435612e6170746f732e686572642e72756e0524180720ba07b1de5b6f533de8a7a3cbe73fcaf90bab558b9b885cc1c6475139d2a673050800\",\"validator_index\":\"80\"},\"voting_power\":\"247998434104277\"},{\"addr\":\"0x9c721c79ee082aafcdd99b1a71a833accdc48dba1a9a1bc5b5f8cc47ff7d49c0\",\"config\":{\"consensus_pubkey\":\"0x84dbf552edeffed075c7198fa159fbd084f7567c746bb039027d04e5ed18abe86b13996837b1479b6235b5236509be42\",\"fullnode_addresses\":\"0x016604023c66756c6c6e6f64652e64653635393535322d613966322d346364612d393964632d3161313138656234303732382e6170746f732e686572642e72756e0526180720dc9ab6f7d07c3ccd37034e965ce2c26faddf2377dfa194e948418f1b6d09264c0800\",\"network_addresses\":\"0x016704023d76616c696461746f722e64653635393535322d613966322d346364612d393964632d3161313138656234303732382e6170746f732e686572642e72756e0524180720806d594baf1fb2ff54f69a96ec13a266af58c6e657d971cce99bc31e32ed1a070800\",\"validator_index\":\"81\"},\"voting_power\":\"1284405634242813\"},{\"addr\":\"0xed84b96729eeaca42cdd0b84c3df69f76c4378a0406595a958cf515cdb024b20\",\"config\":{\"consensus_pubkey\":\"0xa0407c8f73e232487f0925c0798becd7fec1eb2e9880797cb6b8648a4aa6c031816a971c1793eecd7d81cc24c7e7d0c2\",\"fullnode_addresses\":\"0x016604023c66756c6c6e6f64652e33343037376538312d626433382d343233362d396665362d6532336634366265653361662e6170746f732e686572642e72756e052618072007523c1e2a102ac7eb3edd0d29ecb3ad6cf4fb0985608f69d53073a873bbec700800\",\"network_addresses\":\"0x016704023d76616c696461746f722e33343037376538312d626433382d343233362d396665362d6532336634366265653361662e6170746f732e686572642e72756e0524180720c0f8c6c9a822bd341a403f8ae85dc303b5fabe8d36dd7e4e9b593dd65dfbe8020800\",\"validator_index\":\"82\"},\"voting_power\":\"405445139710261\"},{\"addr\":\"0xc41e4eded759ab4a31e999bbef6d14361fd94bea59db8310703b1668af98a23d\",\"config\":{\"consensus_pubkey\":\"0xaa1127376d10d970d7bb15fb2b4cd7a4c6ca094b2f817bf52c03f100eddf4a6ef0bdf49a3281b9361385d7167dd98067\",\"fullnode_addresses\":\"0x01410402176170746f732d76666e2d656e2e6d6172626c65782e696f0526180720dac7e141cc34fe3f06f40f54e3b932eeacd5b81631e18c0775a84f03959d953c0800\",\"network_addresses\":\"0x01400402166170746f732d766e2d656e2e6d6172626c65782e696f05241807204ad53ee25ca28040146bee817e521281a13d0c53b21aefff991c4d9b116278700800\",\"validator_index\":\"83\"},\"voting_power\":\"298984788834968\"},{\"addr\":\"0x29f3f84adbd1eba85bbbec33814924fddcdc9f51921d9cade0dd3b3fdf9170cd\",\"config\":{\"consensus_pubkey\":\"0xa243fb9141d334bff8a4cc40f648a02f6c6c6ac35de375859c5ab33294b7d57f8995f1aea6871ae61746a483ccc1af7b\",\"fullnode_addresses\":\"0x014504021b6170746f732d66756c6c6e6f64652e706f6c6b616368752e636f6d05261807201059b842b505b72eaf6cf3e898536c7fab73855c26b64725eb0ddc3fdeea82270800\",\"network_addresses\":\"0x014604021c6170746f732d76616c696461746f722e706f6c6b616368752e636f6d052418072026100844272e2371b6beefa5e6001e9175656e378c7cfd2546aea8a64768a4210800\",\"validator_index\":\"84\"},\"voting_power\":\"887981021565804\"},{\"addr\":\"0x52b0fd0daaf4f24ddf389768bf24be0a291aabbbdae4ec7b46bc7ed7df41cbe9\",\"config\":{\"consensus_pubkey\":\"0x9220048416d0b1eed80f9ef9b2085a61935a98c3a39c2a199c624907c5aff44135e789de57732c6ddb779e1a8a81e514\",\"fullnode_addresses\":\"0x013e04021476666e2e6170746f732e6e6f6465732e6775727505261807200278a5b5fac22252c80fcdada55ab80dcfaf03ea9c91cb24ccc3ed54b5ef4f2b0800\",\"network_addresses\":\"0x014404021a76616c696461746f722e6170746f732e6e6f6465732e6775727505241807203deb2d94d3d75438e2e3afdd3aec98cf57505baa329045fe05415b96260d8f440800\",\"validator_index\":\"85\"},\"voting_power\":\"887377274395208\"},{\"addr\":\"0x30952a7b88b02028e7c6c7209722cc047acaef85d3d303f375d8ea89fc6ba0c6\",\"config\":{\"consensus_pubkey\":\"0x9761cfd8837023ac15652470109de6d5e2b137d3c213ff7080334dba28faa0df99991a7d6ec1e54ba74367e4dffc39a2\",\"fullnode_addresses\":\"0x014604021c6170746f732d666e2e61727469666163742d7374616b696e672e696f052618072099664f17c7bcb1fdec94ffd867c588e0b30f5b145e05dbe455354de0cec2b32f0800\",\"network_addresses\":\"0x01430402196170746f732e61727469666163742d7374616b696e672e696f0524180720d38b6dd4d0055c4a6190c386990f77df1ee6b64ba1d91a21684fe7a22ef206560800\",\"validator_index\":\"86\"},\"voting_power\":\"887459042837417\"},{\"addr\":\"0x2fd1e866773ea3670cbef6dc6e952ba6fa13130a69fabc98ad234bd834c3bcaf\",\"config\":{\"consensus_pubkey\":\"0x90296e0697f8a87468584317e1ec78d8362a418e32c5a5d205a376fa31daa8b02e0daf4c705296a6578b4080c44a839a\",\"fullnode_addresses\":\"0x016604023c66756c6c6e6f64652e39373338393166352d323762362d346532342d383765312d3138613962663065333361662e6170746f732e686572642e72756e0526180720f8219851a39f4946a5c115d4335127381b9b28083d6e81e3d4036da032f3a4330800\",\"network_addresses\":\"0x016704023d76616c696461746f722e39373338393166352d323762362d346532342d383765312d3138613962663065333361662e6170746f732e686572642e72756e0524180720039bf1100e23a85d06a7a325cdcbc6278070b73baf6a5d0dc149582196cd91190800\",\"validator_index\":\"87\"},\"voting_power\":\"503616162539441\"},{\"addr\":\"0x6be5d9afa759b48140a69c737e9b066270146c7065455d04c2c76842c3e23d4\",\"config\":{\"consensus_pubkey\":\"0x97697afb615084c36369dcc42c2e69e9b62bbf66b73aa7252d75374e93aaf49130b87fdde09db50f1e9aef9a25d18eb1\",\"fullnode_addresses\":\"0x014404021a76666e2e6170746f732e6c6176656e646572666976652e636f6d0526180720d44f650aff8bcabb5a34d038443f1c0ecf9d6e5d5a0a2f4fb1b3492fd6f347170800\",\"network_addresses\":\"0x01400402166170746f732e6c6176656e646572666976652e636f6d05241807209ae143a96188dbe3893016b5a13b0fc34ebb5927cea79062ed9730e8dd3b4e4c0800\",\"validator_index\":\"88\"},\"voting_power\":\"887106505169088\"},{\"addr\":\"0xa651c7c52d64a2014379902bbc92439d196499bcc36d94ff0395aa45837c66db\",\"config\":{\"consensus_pubkey\":\"0xa7a5b20fb6b827a13d2aeebc347f880592328f995193266f51d1d6c298e753e41fc83b038aaa89b75194d57eb0a77324\",\"fullnode_addresses\":\"0x012d0400228abf1f0526180720c781cf9e2cb86456c27c222e3ace4c153b2bf1b168a71896784582a06a5457430800\",\"network_addresses\":\"0x012d040068c4b67d0524180720452e5993709033d367b93ee3cfd64d0b1bf12c0deb6790c0d7d81a5926442e470800\",\"validator_index\":\"89\"},\"voting_power\":\"2751919625832648\"},{\"addr\":\"0xd89481a2f4ff5598f8a6e83e67f21dba6a0df56a1bc35b9c67a2de6dce166b30\",\"config\":{\"consensus_pubkey\":\"0x8719d00e59db5ce1083593ec819b832dc325ba72e2f349885e7690b82a2eed6f8fb5230c86f38910bc5d6f703ec7fbe0\",\"fullnode_addresses\":\"0x012d04002293d2eb0526180720963a52b99f2aa8931bfa949f6d006d674bb0fcff945f4cd22e2974ad1862230f0800\",\"network_addresses\":\"0x012d040023bd63990524180720c9ef94995aa04834c6454e10bf9b4001ae4815aec7a81ecf6c70792bad18e84c0800\",\"validator_index\":\"90\"},\"voting_power\":\"1001821446893340\"},{\"addr\":\"0xd7b10a9ddee853b3585dd1efd4902ab3ad4f482b94425a3780cc39e79e6d398\",\"config\":{\"consensus_pubkey\":\"0xb0237037c801c85e3b833e2e3c9e80a6143154876a81837fe3c34a393302be3ab27aa63ddcdacfe7bdc932da648e7535\",\"fullnode_addresses\":\"0x012d040008d9322a0526180720e7fadd82412a07342e97a8ed184fc6ed215951d83591761c32c37a81441491640800\",\"network_addresses\":\"0x012d040008d945d90524180720ea346bc8e2c658c7f2502125dfa83ab7328661b8747ee9a4103eb4580c9ffb7c0800\",\"validator_index\":\"91\"},\"voting_power\":\"1137239543022784\"},{\"addr\":\"0xa7375edf245124aa2531c74dcd0cbfb4c7aea02dbea32c7fbf72784533730874\",\"config\":{\"consensus_pubkey\":\"0xa913dba29f0ca85f6490c2f66558a60286bd183eb51b1a9ddfaee3a52fd25a94c8e76b6828277b5018af5cf5877419da\",\"fullnode_addresses\":\"0x0140040216666e2e6a616d626f746563686e6f6c6f67792e78797a0526180720c68c24ee2edbce84621b2b5d469b9bb0e359caa2ca32c85f92dc254860c154640800\",\"network_addresses\":\"0x0141040217626f742e6a616d626f746563686e6f6c6f67792e78797a0524180720648e281cc51f1ce1b340ded6c67559721038b52067fca8c2e8e9adbbb50184630800\",\"validator_index\":\"92\"},\"voting_power\":\"1056347666192981\"},{\"addr\":\"0xb43fe1ef756cae4fefea16dad049fb0760b7d8593ace12527e302520d934d0d7\",\"config\":{\"consensus_pubkey\":\"0x91fa9ff562024a56b5f96132e505808f5b8bc301def526d08437c6bc55ba07a499707d1fdba56f37bf67de873718eb7f\",\"fullnode_addresses\":\"0x012d04000d28ffac05261807209362d95a27b00577bd1ca99849bbd4b3f4f230a53a11a4c21f55bc4b9b892c570800\",\"network_addresses\":\"0x012d040012aaa2dd0524180720360573e1bea87706e7ae8ac151dce609fac21a468f332045caa045502bfe496c0800\",\"validator_index\":\"93\"},\"voting_power\":\"1501861678006378\"},{\"addr\":\"0x2784eb9f3b368be1db73256336014a01c02b1b06ab01df7387bb8945ca73045e\",\"config\":{\"consensus_pubkey\":\"0xaff4524870f337e9f91f2991d7d8cc0a9483cc309b884b98c9cf7005ad4c9c38067fdc1acf83a96a3741cc6f061e7402\",\"fullnode_addresses\":\"0x012d040036f117f50526180720c4d38da68500f1bd59dafdd94afb0c64db48c41fd99f154afe91cec60c669b780800\",\"network_addresses\":\"0x012d040036c12eb805241807205bd2ec71ab30063260b6781d9be1fad0e776db87ecc80123640c63297ef46a710800\",\"validator_index\":\"94\"},\"voting_power\":\"1501861717317598\"},{\"addr\":\"0xfc90c3e74dfb562827ef85dea5669beeca7717faee0c3ba520c3ab08f9b53135\",\"config\":{\"consensus_pubkey\":\"0xb6be13806b42f10cc20f6e4df4069e93e8186b736e4bde8f53f599ed7228f25ac24e8f8b5ace3975adcfc6380182246a\",\"fullnode_addresses\":\"0x014f04022576666e2d312e6d61696e6e65742e6170746f732e666c6970736964652e73657276696365730526180720c4bbeb105df7f5953413fe24845d8cbe7ea86b05b444130c13a25227df21af140800\",\"network_addresses\":\"0x014c040222766e2e6d61696e6e65742e6170746f732e666c6970736964652e7365727669636573052418072050f41f1dac12a677e1a23f5853ed6e574094c1480b5d8b1356d0edc5a67f2a4e0800\",\"validator_index\":\"95\"},\"voting_power\":\"396026414474284\"},{\"addr\":\"0x6fdb6516f550ceada7d1fb687b52e4d334c0805a856f17c85f1eb852cbe66ffb\",\"config\":{\"consensus_pubkey\":\"0x8bd1bc853f13ceb153d9be3004f7d510b331804721688651fb7ec5788042eb18771deab8944863065cfdac28319a6e12\",\"fullnode_addresses\":\"0x012d0400225e1d410526180720881dfe88146b45afa1162dcd0ba84f8717a7e28df5733f6e947257a0a42b566b0800\",\"network_addresses\":\"0x012d0400225e1d410524180720fb37ed6b0ee35d4745c306260bb93dbcbb634d13c9de2c2dad671ce50258fa1c0800\",\"validator_index\":\"96\"},\"voting_power\":\"248158714072637\"},{\"addr\":\"0x70ac104168697addf1569c26ffc00958435d6bd87e2a61e49e0c6eb16d07a10b\",\"config\":{\"consensus_pubkey\":\"0x87ad70b058561d1dbcb1420f8ff1b92342d939ab9d75fa6df261d56b04ed84186b337815a1ef0c3ad627cad41735ddc1\",\"fullnode_addresses\":\"0x01400402166170746f732d76666e2d312e616c636f76652e70726f0526180720f65b8d97c4b0fe13b1a2daf0ea7f956a03611567c56280501916803a20e099500800\",\"network_addresses\":\"0x014604021c6170746f732d76616c696461746f722d312e616c636f76652e70726f0524180720c06073d2a4ea5efe7cd60a20ee04126f775a60876f3ddeb1f71839fa57a3d9130800\",\"validator_index\":\"97\"},\"voting_power\":\"1059829419202744\"},{\"addr\":\"0xc92d451e6b5c1bca83d002c3dad857cb8fafb1e49ef5ddadf25c0f40f9d5728c\",\"config\":{\"consensus_pubkey\":\"0x94f04d1e4013a7e5156070e7b1d2f72041e3203d88c2012a814c12f72525299a63795191ee781becf1e870dbc1892913\",\"fullnode_addresses\":\"0x014404021a312d616c7068612e30783131353235313831353331312e636f6d0526180720c59db1ff57e4ff707c52716931b036715ce7ddc3caecbca2ba80d5cf57e1583e0800\",\"network_addresses\":\"0x0143040219312d626574612e30783131353235313831353331312e636f6d0524180720562ca2c60dd974ac6e8931dda6030f3e263f44acb66ca2f1b8c831f4bc038d070800\",\"validator_index\":\"98\"},\"voting_power\":\"1000217093981713\"},{\"addr\":\"0xefaec1debc26828f8142a71a906ba180cae526b0688f304a28e57fb66f2b9a5c\",\"config\":{\"consensus_pubkey\":\"0x8fa5b8e8c766c82f0715a2de4b6cfffa55fe6ee9d9ec86bcf019b2285e9506612d618320eb9a79a27b33d18f41f7723b\",\"fullnode_addresses\":\"0x014404021a302d616c7068612e30783131353235313831353331312e636f6d052618072073b4aecc4b65d254d8142efbb9b439d035e49ad552cdb23e44832fabd5fc02790800\",\"network_addresses\":\"0x0143040219302d626574612e30783131353235313831353331312e636f6d0524180720e075670db088b5173087a19fb3b2879b41ec1ede6a2111f5a8904be6b4e9667a0800\",\"validator_index\":\"99\"},\"voting_power\":\"1000217093981713\"},{\"addr\":\"0x6214524acdb638d3ace8a705c7e9bf6f73992d1e030003ac18155e46f0b81b91\",\"config\":{\"consensus_pubkey\":\"0xb3f715899f288754499e21935baea77f3c97ca08d54b0c6736faff9b253a84aa02c62feb0b8a4fba26cbc2a50187eec7\",\"fullnode_addresses\":\"0x015e04023476666e6368696e676172692e6170746f732e6d61696e6e65742e72657075626c696363727970746f2d736f757263652e696e666f052618072035bfa3d52f51d1f8515b5686b9192ad27bdb8008a3c98bac1d8299f47c585b3b0800\",\"network_addresses\":\"0x015c040232766368696e676172692e6170746f732e6d61696e6e65742e72657075626c696363727970746f2d736f757263652e696e666f0524180720c6f7494c510b2098d3f1481a3a40d9b72b70c4afee5f962a239e89276ed627750800\",\"validator_index\":\"100\"},\"voting_power\":\"608194294804494\"},{\"addr\":\"0xfd92966377f67c75c9165fd7c591b26294edc01d3ea2b71bd4b75375d08445ab\",\"config\":{\"consensus_pubkey\":\"0x81b36fa9397958d8dfe77e65d4babf93c90f189ffe06ccf5dfc25fa21190f7b0b22ff812d2297c3f3b0c9e93bc6173af\",\"fullnode_addresses\":\"0x015a0402306170746f732d7374616b65642d31312e70726f642d656b732d65752d6e6f7274682d312e7374616b65642e636c6f756405261807207727d0a72ebf7f55eb119985e8c33036502e4c08bd2ed7618ab5ffe972289f3b0800\",\"network_addresses\":\"0x015a0402306170746f732d7374616b65642d31312e70726f642d656b732d65752d6e6f7274682d312e7374616b65642e636c6f75640524180720373382f9f519130cab73bae85f956d71ebe29bd398d4c1913c84f63aa303c9420800\",\"validator_index\":\"101\"},\"voting_power\":\"680399735718707\"},{\"addr\":\"0x346361873c235e1a300fd67a2e8b7bd1ea3744001b2e0d1942317c4c8521f5dd\",\"config\":{\"consensus_pubkey\":\"0xac36951a1588965a3767fba32dc956ad5dfe0fb6014ff57e9da625024ecd5bf525d640e6c06149157971c266dae7a98e\",\"fullnode_addresses\":\"0x016604023c6170746f732d6d61696e6e65742d6669676d656e742d64702d76666e2d332e7374616b696e672e70726f64756374696f6e2e6669676d656e742e696f0526180720d8bfdfd70df4cb43d872814c293c66fb6e6df5abdfe25cbc588a3b264dd33b220800\",\"network_addresses\":\"0x01620402386170746f732d6d61696e6e65742d6669676d656e742d64702d332e7374616b696e672e70726f64756374696f6e2e6669676d656e742e696f05241807207a2bd25fdfc5ad9694a5dd6b4a6c78a71365354300adf335ed6fb771dda0c77d0800\",\"validator_index\":\"102\"},\"voting_power\":\"460698392517608\"},{\"addr\":\"0x50b27eee627c0648ff4867894e264d67de2049ee9a8b92040cb35020b74afa39\",\"config\":{\"consensus_pubkey\":\"0x92d63f78f95d61063bd6d7cb9a664a8dca8df50318926fbd7297dab24a1380cdfdfb69548c55049a71f9db88c96aebef\",\"fullnode_addresses\":\"0x012d0400cea8be2b05261807209abcee839272c308a34900c1c719edcd59a8a4b23ff41833fb1570694a9be6290800\",\"network_addresses\":\"0x012d04000fcc2e590524180720a422440ec2f4fc5dbdbaa5da7ebd69b3e09df3c5d1015c94de877988d89b7a550800\",\"validator_index\":\"103\"},\"voting_power\":\"314533652602703\"},{\"addr\":\"0x890c86c19974b98594a4e5cd7b0b3a69af1b30afc78853a0c11e882801497320\",\"config\":{\"consensus_pubkey\":\"0xa28939b564a461a78e486c5127e69733f1a4dc562324b95cb27c6933fce849583db46739cfe5fa1d6a57947a7d5d895b\",\"fullnode_addresses\":\"0x012d040034cfa2a80526180720627e142a7551e2a41fbc6579aa5e68afbeae25f7d342b5d9e629d4284be4901c0800\",\"network_addresses\":\"0x012d040012d6ab2305241807203fddff34f424c26c1dde8d3ccddbc66b75879c3bffb38589dbf47639c0bfe6030800\",\"validator_index\":\"104\"},\"voting_power\":\"312273487451511\"},{\"addr\":\"0x626495135e0f5a20c38aa4deb456890e7e7462d1bc096e9a90c1a7a3562f0f38\",\"config\":{\"consensus_pubkey\":\"0xaf4d82f967068446e538fa55ce2bc0489417fc3e5627f76223f2626d56f622724396badcf3e5796251384065f542dbea\",\"fullnode_addresses\":\"0x012d040085bac6ee05261807202912b019957a67a122764c649349aee21ae83f95abb8ebc451557e51c6ed876a0800\",\"network_addresses\":\"0x012d040085bac6eb0524180720b0ac8623c2d98e712e354ea56eea834e60c070aff7087378191019589f033f3f0800\",\"validator_index\":\"105\"},\"voting_power\":\"1047595455546138\"},{\"addr\":\"0xdb5247f859ce63dbe8940cf8773be722a60dcc594a8be9aca4b76abceb251b8e\",\"config\":{\"consensus_pubkey\":\"0x8dd8153fda57e5d0acb2ffa887fe3c9bf0fa6dc4a89c87d4e14883bddafc96317f282a3b7fbb8012505f1013949a7105\",\"fullnode_addresses\":\"0x014c0402226170746f732d6d61696e2d706f6f6c2d66756c6c2e657665727374616b652e6f6e6505261807200cb28e7d3cef7ad977e38894be05ab4a158e907456c6a4d2ee88fef484bcf8740800\",\"network_addresses\":\"0x014704021d6170746f732d6d61696e2d706f6f6c2e657665727374616b652e6f6e650524180720d836efefec7c61776616be7fcb604ee6469111d144e7c98359bf5ca3cd9f3a730800\",\"validator_index\":\"106\"},\"voting_power\":\"907628573842295\"},{\"addr\":\"0xe2789cdac410113f017fa684bf08fbacd0877612d84464ae6e8474b56e5f21da\",\"config\":{\"consensus_pubkey\":\"0xb4056d4651add83ea7e3c0e118c648f2e4c57d8d01365ffd788ee22311c8a1ac5347af9f7e0f29f56e7da0ab46ee5397\",\"fullnode_addresses\":\"0x014d04022376666e2d64656c65676174696f6e2e6170746f732d6d61696e6e65742e6134312e696f05261807208a62bf9e307cdf923d1368ecac42dd1e5a32aa4a876519574706c416c88dfb020800\",\"network_addresses\":\"0x014c040222766e2d64656c65676174696f6e2e6170746f732d6d61696e6e65742e6134312e696f05241807201e1e1fdb4c7f203662a36a22cad55ba9cac793a59269b2e807fa5d444dff6f6f0800\",\"validator_index\":\"107\"},\"voting_power\":\"1595411707451437\"},{\"addr\":\"0x95798cb276fc8d784a722794f0ede125681788aa7db6c9e954a667037bc24f85\",\"config\":{\"consensus_pubkey\":\"0xad82504d725d7ea8b6bd4fc122006ea772df4e8988190218033b47c67d4c3a94597efec68259c088d7d30be3ee6027d2\",\"fullnode_addresses\":\"0x012d04002f5b046d05261807200ce31e2a696039fcbe5c9cd5c7b3f24e707abc913a8efe1493cd04dd5be097670800\",\"network_addresses\":\"0x012d04002f5b046d05241807207708f59a87127eb546c1746d83528678f77a1bd4d18cb29f4b9149a9d7cd191a0800\",\"validator_index\":\"108\"},\"voting_power\":\"326233296143794\"},{\"addr\":\"0xf1f6f780321e7259d0feeef98745da7f766eace664c43325779302b2724c8692\",\"config\":{\"consensus_pubkey\":\"0x8628a6924279ab4ba35cdd1e4cb887c6059804eca72c2a11b5cc15fd888b5b5aa67d8dac468b18ac415d09e4789d8074\",\"fullnode_addresses\":\"0x012d040085bac6ec052618072094f89efb818a447be66ec393964f89b870698cf3b9948d9f6d82de7b5621334f0800\",\"network_addresses\":\"0x012d040085bac6ea0524180720f6ba21acc0d9da4f808ba7566e152a457ba4781cc06cd5586d6cf950a9e918290800\",\"validator_index\":\"109\"},\"voting_power\":\"1047776939605283\"},{\"addr\":\"0x877d09996086effe241b1a740d46675754c17f8620ee9be42c5c7e322ce1598c\",\"config\":{\"consensus_pubkey\":\"0xb12b91a8281d1a90cee04e5f3dd3940ce14c85e53261a2cf1c1011549c67b2e3246f0bd83ec269b6699a7c727a5fe9cb\",\"fullnode_addresses\":\"0x014104021776666e2e6170746f732e7a687374616b696e672e636f6d052618072040b087488c7695bc75da8be0ef9ab188bb2d98717e8d8a9b00c6809b637cd1340800\",\"network_addresses\":\"0x014704021d76616c696461746f722e6170746f732e7a687374616b696e672e636f6d0524180720d36ee99d7562efa74ec761c4254a7bca4e8fa0daef358966d00cdde156c1421b0800\",\"validator_index\":\"110\"},\"voting_power\":\"285731520996832\"},{\"addr\":\"0xff90c2afcd5c09b7414e4629d17899bcd763f8673c400a6d983fe15b98cb65d2\",\"config\":{\"consensus_pubkey\":\"0xb3cfce7bc3077bb8c00e91c8c4b36732560de7a64e55c5f37cc2e6e3988eb719d08b205bf52ac637da48804d8d5014f6\",\"fullnode_addresses\":\"0x012d0400923b768f052618072011504bcf48534f2b837f07acd4c5fa21811e41395b17307d770e973a9a46e81e0800\",\"network_addresses\":\"0x012d0400923b769005241807201eb74528db01177d18cc920704dd7e0af5254db96e535c8f7c72b5cb2babd6680800\",\"validator_index\":\"111\"},\"voting_power\":\"415732959864331\"},{\"addr\":\"0x3c4d9be0f74cd198b88eeb087632951465045004ec67cefe6f4f170382a20a46\",\"config\":{\"consensus_pubkey\":\"0xaa322f40638c55ee99aa56dc856f98a531f1c5d94bad1d5285a5a618dfb8807307d2420a614caf5db969bb4a34fbac6b\",\"fullnode_addresses\":\"0x012d04000dd769dc0526180720db969d471ec41876847000bb108c676fb7c0e6c860518029333ffa1dc8c7ee690800\",\"network_addresses\":\"0x012d040034dce718052418072010dbd554c77b63d057b9a24d0ae5cafa3c43cc5fed22f645ecbba58afc0f32300800\",\"validator_index\":\"112\"},\"voting_power\":\"626025503455452\"},{\"addr\":\"0x3d51eeb71188cc7ccf5f6f288a3a51a9a763222883cf392296b3d5ec3f2017ea\",\"config\":{\"consensus_pubkey\":\"0xb985b6b5b4646d16b79e29eac69dd13ace8e22e318e1b98ddfcdf28d412797043950cd01d26dea8b05956cee0bfd1435\",\"fullnode_addresses\":\"0x012d04007cf3976b05261807203f9a2376f526706e4a003e215a2cb3c6dda42d4a931350d25bdbbe0d5578ba340800\",\"network_addresses\":\"0x012d04007277ae9c0524180720ec4b8151fcc0a993f43fe6ee19268615d0076049f0b3eade6c8b80c2efeff0280800\",\"validator_index\":\"113\"},\"voting_power\":\"1003337318442462\"},{\"addr\":\"0x31f82d48dbc4ff7c7ec3fc10fac7683f58bc0505d0cdf02292abdf266d9c0a78\",\"config\":{\"consensus_pubkey\":\"0x8872bd356ba8f1e8aeb4b0a5d274e5a9df0391f9d50d60df56d48fe058d37e82790a2a4061032654d3a73c4ea3f0b41f\",\"fullnode_addresses\":\"0x015104022776616c696461746f722d76666e2e6d61696e6e65742e6170746f732e727063706f6f6c2e636f6d052618072022f1474abb6b1cbf065853bc23e1363cbb185fbc77b1b7016d493ea3eb59e14e0800\",\"network_addresses\":\"0x014d04022376616c696461746f722e6d61696e6e65742e6170746f732e727063706f6f6c2e636f6d0524180720a6af2a57c5de32baa83a3c9b1e0140aea38d3a33a0623b4d7c4ee37d0b4e10620800\",\"validator_index\":\"114\"},\"voting_power\":\"649681951751875\"},{\"addr\":\"0x66fcc9a1275170c140988e8fdc5104fef09568bdd07930f44a290bf55a5550ee\",\"config\":{\"consensus_pubkey\":\"0x8a99aa282c952729e6313851fb12e9a04a8688243a2b84f4a1f55024983895a08c07b3e326124390938d1ac71b8bbcb5\",\"fullnode_addresses\":\"0x01410402176170746f732d76666e2e6a756963797374616b652e696f05261807205fc9f80546d379b9f220af5796e210f4a9691508bc0857e5b6b7429da5ca87480800\",\"network_addresses\":\"0x01400402166170746f732d766e2e6a756963797374616b652e696f05241807203292328d921c03ea8e662cf518497d20f3ab32d81b1101d6658313da4699fe1a0800\",\"validator_index\":\"115\"},\"voting_power\":\"414383328603472\"},{\"addr\":\"0x22c25ea17f339761d512b588feb436a4784332f4bedfb3f17e25db7d8de0c94c\",\"config\":{\"consensus_pubkey\":\"0x8c4a4c2b102a473eaa6c3ccb61a3ec19eafb52dad28293e0d49f55650eded61df90018ed223a53f07a96cb73db34c6d7\",\"fullnode_addresses\":\"0x012d040022767359052618072027a9ed88bddf8f8c43cd84037078d24e92c91e95a51a378839d17f0682e1375c0800\",\"network_addresses\":\"0x012d04002274eb6b0524180720a3c79be67a0766797dbc53ef67fa4b28218ea323daecfeef070f635ffd1e42230800\",\"validator_index\":\"116\"},\"voting_power\":\"413857727748074\"},{\"addr\":\"0xa57ed536dea7ae3250790ab12fbb6ca6ae669bf4eac5a12446b8769e534082f8\",\"config\":{\"consensus_pubkey\":\"0x8ff941f18277c35dde25854bc0241663909163f12f9afa9402eab2832e88364e83acca1c42404de8db2351ff0092c58d\",\"fullnode_addresses\":\"0x016004023676666e5f746f796d616b33727a2e6170746f732e6d61696e6e65742e72657075626c696363727970746f2d736f757263652e696e666f0526180720bb1d143122bbf0635cfef1399a2791b0a18d9459ba44a53447a1a903e3cba9000800\",\"network_addresses\":\"0x015e040234765f746f796d616b33727a2e6170746f732e6d61696e6e65742e72657075626c696363727970746f2d736f757263652e696e666f0524180720fb178575f0edbda0c5dbdab4ae3dcb4863983d32547abe9e7be5198e17c3050e0800\",\"validator_index\":\"117\"},\"voting_power\":\"504654953109763\"},{\"addr\":\"0x2738d91e160d9be37cd9689177546b567e28a3644b702388fd2c2be9c97682de\",\"config\":{\"consensus_pubkey\":\"0x8c43ca96abee9d57c3592eedf9db0fb731578830f5eff31761b165b28ebf86a459d074b06898c20e1c0f9d9476633936\",\"fullnode_addresses\":\"0x012d0400030081d30526180720ae8067a2bdd791ded1fbb680fc8640691e2a7d13ff51949154913631a237ad030800\",\"network_addresses\":\"0x012d0400128a96210524180720d8b9ec3d1a0ddc30fab0d981c9bf645bbb4b95ba3caa620c003f033f0326e6030800\",\"validator_index\":\"118\"},\"voting_power\":\"1002721603684956\"},{\"addr\":\"0xce8294a77912a6802adf093ba15a4f09d2d3c85400d161a0022499de4e2aeb92\",\"config\":{\"consensus_pubkey\":\"0x8aa09cbe115acc682fc01a02d0baf04781f4432131c9c2591c3d2ec334aab6572f05963e7cae785493931e157cbf2905\",\"fullnode_addresses\":\"0x01410402176170746f732d76666e2e7375706572666173742e6f726705261807206279b2a9ceaf4bce8cde62453830d30a01bcb57d3860dd33ccbea1d1402dd1150800\",\"network_addresses\":\"0x01400402166170746f732d766e2e7375706572666173742e6f72670524180720fd48919dd5732dc1c7af597aa2151bfc66c4fd65cc0363bde9437a49fb9b9f2f0800\",\"validator_index\":\"119\"},\"voting_power\":\"496283474162412\"},{\"addr\":\"0xc44406bd36286223e7f2924ef48aa017b133dca73f2837b3692784cb046dda48\",\"config\":{\"consensus_pubkey\":\"0x8ecc0a2a615adda39d970e2826394af2f735fcb8ff329b7e9dd1b633be1a441ac64cc19f17d256aa67b3c2be0a37679d\",\"fullnode_addresses\":\"0x014c04022276666e302e65757765342d302e6d61696e6e65742e6170746f736c6162732e636f6d05261807209ee8f934db91612bd448f575483b900668e3628cf8f636a39cebbffbf5516a5b0800\",\"network_addresses\":\"0x014c04022276616c302e65757765342d302e6d61696e6e65742e6170746f736c6162732e636f6d0524180720bf5c7ea2f09e39473e6ec91ea9eec3f0ba9bc0359bcd1a7d66a13ec51b9456730800\",\"validator_index\":\"120\"},\"voting_power\":\"103626892808062\"},{\"addr\":\"0xbea2323e776d126d319e7f15bf41f624b8cfd19c0484e3b60e6d8ecf1810dd16\",\"config\":{\"consensus_pubkey\":\"0x87dead8aec3980ef0a7940424a3d52c5d848d4990d794d8cc007822256d25ba52bc278e06f7591dd9554d58d8564a808\",\"fullnode_addresses\":\"0x01420402186170746f732d76666e2e73656e7365696e6f64652e636f6d052618072044ca5b55ac181bf4f58112ad0a04a5d9fc16f741474611a599053cab84fc076a0800\",\"network_addresses\":\"0x01420402186170746f732d76616c2e73656e7365696e6f64652e636f6d052418072092bb1b316a6b2675b6752c674fe847a6e7854e66be88410da0a447d561b5b3510800\",\"validator_index\":\"121\"},\"voting_power\":\"310628334445674\"},{\"addr\":\"0xf666b2543ae12ff8e278371e5c3f93d4686d055b442e9271a0f4bd3afa1dd9ab\",\"config\":{\"consensus_pubkey\":\"0xb2243f6166da6c5d1b713224db0b0f849fef441966c7107b639a36d3fd3c3fa9da27a123ee4487c3b966f4c8cf5b3986\",\"fullnode_addresses\":\"0x01400402166170746f732d76666e2d322e616c636f76652e70726f05261807209e83793bbc5f92a700d166e403b55b48fbf0c052fd2c56f981118bda2ddb42390800\",\"network_addresses\":\"0x014604021c6170746f732d76616c696461746f722d322e616c636f76652e70726f0524180720adce17adea5d31283de0e1369be1e5d2bb0dffba3f09be2aa344d815d3609f670800\",\"validator_index\":\"122\"},\"voting_power\":\"309591285688418\"},{\"addr\":\"0x63b0a7343c481fe176603e4e30cc5acc521c75d4310ce1b7b657c8168df66c66\",\"config\":{\"consensus_pubkey\":\"0xa2bea2c2c1f3b2b3a724319a416273932b8784c27e44781ad61c5236326192573302ae9b160cd0d33f422346d410aa8f\",\"fullnode_addresses\":\"0x014504021b6e6f6465312e6d61696e6e65742e6170746f732e6b696c6e2e666905261807200e2bddf8b8797de019a9e9322332fd5ede3c19d4107bddf5d5b9bd450c9b346b0800\",\"network_addresses\":\"0x014a04022076616c696461746f72312e6d61696e6e65742e6170746f732e6b696c6e2e66690524180720e9ec97d24d57bbf1c43070038304243bc18a72edf6eb533480f82714e43061030800\",\"validator_index\":\"123\"},\"voting_power\":\"115759120121731\"},{\"addr\":\"0x3edbf3e6444054c2a5a391221c9023882d0b2478576c445923a39b3bd0cde0a3\",\"config\":{\"consensus_pubkey\":\"0xb3f3ebedd8b3ba81da2697c4a4835949538ae73d427e8bff23c69e7eb8af2a5a394a05bd85e7b9f74b90ba2f90e85ddf\",\"fullnode_addresses\":\"0x01400402166170746f732d76666e2d332e616c636f76652e70726f0526180720249185fc610dc89021028c80115b51eea6dc449cc53b3c92e44c306f792bfd210800\",\"network_addresses\":\"0x014604021c6170746f732d76616c696461746f722d332e616c636f76652e70726f0524180720983194f5774ba7b0e31be20a3985c30f192dfdd4c2ab3a2e5b5d20f7e4ac07270800\",\"validator_index\":\"124\"},\"voting_power\":\"1028754717604293\"},{\"addr\":\"0x2a4f9ee6b2c4376e72f866f7da841340dbe0945b9b58190a6447b2f537b5225b\",\"config\":{\"consensus_pubkey\":\"0xabad7974dcba14053414ce265b9e65f3b5af7db7ae070066b2163f43676c6dc29b9ab06842b6baabce57ce33387fa568\",\"fullnode_addresses\":\"0x016704023d66756c6c6e6f64652e66616365386133392d383030312d343364352d613532322d3665393665666665323231332e6170746f732e6269736f6e2e72756e0526180720b93ae928b3688f0baf852508219ff8541dc725c9678792ac8a8472f32c8abc260800\",\"network_addresses\":\"0x016804023e76616c696461746f722e66616365386133392d383030312d343364352d613532322d3665393665666665323231332e6170746f732e6269736f6e2e72756e05241807207b6e74fe9f97e01653f400ef6141d69157d8f2c4129a92115e89394a1099c6480800\",\"validator_index\":\"125\"},\"voting_power\":\"103415635294511\"},{\"addr\":\"0xbcfe20d6df15fe888dd7c5a15cb32e5396cd358adc02d07c51cc08f3785b79b6\",\"config\":{\"consensus_pubkey\":\"0xab707632125fad2d35cac86ff9046df56cf2eaba6a118d087809a4cdad4e3c6106d5d96696b127b17d43d994ed8f8061\",\"fullnode_addresses\":\"0x016704023d66756c6c6e6f64652e61396236626435622d333431642d346432392d393537632d6661623633656136613131622e6170746f732e6269736f6e2e72756e05261807207666deacf75b48bf16a2f91fdd1830996e9f9403492f1dd0256a5a2efe858e460800\",\"network_addresses\":\"0x016804023e76616c696461746f722e61396236626435622d333431642d346432392d393537632d6661623633656136613131622e6170746f732e6269736f6e2e72756e05241807208caae2c0c82ef6073ffa98b4aeb08b4646ad1e8f70fab6ae426d24d9564703130800\",\"validator_index\":\"126\"},\"voting_power\":\"142240486055964\"},{\"addr\":\"0xded0220633df25f00d4d25a13be131ec5d1a08e93713b0fdf433dc2074dd7872\",\"config\":{\"consensus_pubkey\":\"0x811b0d68f9881c1f0267d974e31b6bab4d41c1ef45b7f3a229a5fe24ab02482856ab82b0143b90c2a66a5f80363aa18c\",\"fullnode_addresses\":\"0x016704023d66756c6c6e6f64652e30326262386531382d366139372d346466382d396462382d3531346630353266663335632e6170746f732e6269736f6e2e72756e052618072094febe2a88d732b2d85b8ffa54c5785aaf9d93c55426c2c52efe8be7a57b98260800\",\"network_addresses\":\"0x016804023e76616c696461746f722e30326262386531382d366139372d346466382d396462382d3531346630353266663335632e6170746f732e6269736f6e2e72756e052418072072cdf235d38b2102431baac3fd34663d0acbd5c7dba4edef83fe0a7a5bb3993a0800\",\"validator_index\":\"127\"},\"voting_power\":\"102710412933937\"},{\"addr\":\"0x33f0c333f6fcb9d1ef54d54093f0482b31bb0bdcd34bfa446e7416ff930453c0\",\"config\":{\"consensus_pubkey\":\"0xb47e1dc1335be93aa7e39ddc83301d52fd354e37e0a7d1b23bb158278fc0e8ed36d3df31889681b563a38d545b36bbc2\",\"fullnode_addresses\":\"0x014b04022176666e2d74662e6170746f732d6d61696e6e65742e7477696e7374616b652e696f0526180720a79f03f5af1f73053ee05112a0c2831845ad55112907e8e37ca4a81444e504290800\",\"network_addresses\":\"0x014a040220766e2d74662e6170746f732d6d61696e6e65742e7477696e7374616b652e696f0524180720f23a9f0e226de5ab8982cd1f43be8e3f03d52823f6e69fc06243ef12e610e3670800\",\"validator_index\":\"128\"},\"voting_power\":\"1031068921618624\"},{\"addr\":\"0x880cb2b03f4158dc927fe6058c5b968636932d49fa1d2896a86bd849456455c7\",\"config\":{\"consensus_pubkey\":\"0xb7dc8b3bcc1daa12536f042cf2de7f922ae920e5000499e3476ab74f73a8bb26682a4531351fb7cb3292fd1e0656b806\",\"fullnode_addresses\":\"0x014704021d73656375726974697a652d76666e2e73656e7365696e6f64652e636f6d0526180720d01d5afab9a0f07ae8f656c57f266d5e3dabb7e1e567d16024d35173fb8be5520800\",\"network_addresses\":\"0x014704021d73656375726974697a652d76616c2e73656e7365696e6f64652e636f6d052418072079afce6a1f2cf113e01ffce73170834dcdf47247349f78df2ebbcbd31deaf53d0800\",\"validator_index\":\"129\"},\"voting_power\":\"1007570120142286\"},{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"config\":{\"consensus_pubkey\":\"0xa05bdc13dbd7e224732cbf1eda9bb92e189c0b4e8919bfc42c0107bffc909f3494b003b5f36a870caa52cda31beebab4\",\"fullnode_addresses\":\"0x012d0400b4d27f8e052618072011a67510b0cc2788b19b3f14edb1dd43acbe7a36d36ed4b98b023628c04f01580800\",\"network_addresses\":\"0x012d0400b4d27f8d05241807204d113530b74b4b308749bb27943edfaa663e54146316ec32729a5ef7b1a52a4e0800\",\"validator_index\":\"130\"},\"voting_power\":\"204154256624189\"},{\"addr\":\"0x4fbd48a3ddf937873e0f50fb3a69172959f83feb46c4868bd3f7c45f1bdc2be0\",\"config\":{\"consensus_pubkey\":\"0x8c710f12d35a6306a6c37e42834d0fa19ba02c14de0c2509331e697d86997460f3c310b74feb3eef8a1cd2a378f5a45b\",\"fullnode_addresses\":\"0x014404021a322d616c7068612e30783131353235313831353331312e636f6d052618072027a5725210ed35137c861ec155684dbe1ee1527a5d9ca2e628f29ecb0535c5720800\",\"network_addresses\":\"0x0143040219322d626574612e30783131353235313831353331312e636f6d0524180720465d7983be89639760de415a2be176775a136ebdb9c8171029e174a80c18465e0800\",\"validator_index\":\"131\"},\"voting_power\":\"1001971040193588\"},{\"addr\":\"0x41484099cd0ab3821ddd330a0cb742cafd6a1621ec1b993f65a8c6c5108a114d\",\"config\":{\"consensus_pubkey\":\"0x8aeb448d571f56ebafa9fa1ed7f85a949aac29f4b42deffbb572b08a82f4c7a8f52a8d6ccf2e63acc1f34970a67c9c89\",\"fullnode_addresses\":\"0x014504021b6170746f732d73766c2d76666e2e6e6f6465696e6672612e636f6d0526180720700da01362b0a068569049d7d9f3ce5ef1b941687d1e622e1ea8777cb60b762c0800\",\"network_addresses\":\"0x014b0402216170746f732d73766c2d76616c696461746f722e6e6f6465696e6672612e636f6d0524180720486ff74803c533b49182c225527509a18f13539b6a68c9cc231dc091150f3b2d0800\",\"validator_index\":\"132\"},\"voting_power\":\"506865202039728\"},{\"addr\":\"0x6e60dd385a87a14d80741ad3070e3ff0ae064e3884e75ee918593126762650cd\",\"config\":{\"consensus_pubkey\":\"0xb261a22cd6d232bf60d7a3e471835dcc8f54b3f4801fb9e4a483501f1b8a34a11ba673cb5b4b3db119d30d5f224d48a4\",\"fullnode_addresses\":\"0x012d040023e73e0605261807201b4bcdd5dc81016f432988f28f56163ef004a47e75500d6362182f0346dab50a0800\",\"network_addresses\":\"0x012d040023e51dfa0524180720133a9d9678cd33b9ec038c0d6cabab4a3aceff6c348312895cfe071989dc494a0800\",\"validator_index\":\"133\"},\"voting_power\":\"190826942554452\"},{\"addr\":\"0xaf0843693e9446fac15e6e019ed3b5c7527e23fa66006cb4625fb844dddcb1a0\",\"config\":{\"consensus_pubkey\":\"0xa5cd0db8cefb0cbed214cf135acae7f3da2d9e403a992239d8b994fa36eb69d59ada305947d161d646312b9349a29a80\",\"fullnode_addresses\":\"0x012d040033a1ac07052618072045f109229e40322f4a1b54a7862125f16eec27e9dc91192e053b8b5b9e7cf4770800\",\"network_addresses\":\"0x012d040033a1ac0605241807208bb4ad834a27255ae8522e3ec54be7585ff257cd075d82c7546abf140b88de670800\",\"validator_index\":\"134\"},\"voting_power\":\"228516839529257\"},{\"addr\":\"0x6c89d2927f78bb3b1743b4cf97d69777c2669cfbb11aff5bdaaa1083db3c3123\",\"config\":{\"consensus_pubkey\":\"0xa6c90b7cea0881911db080ab2e29a7709f809e8afc82a60d6b06c2c0aab2ba11e6e1951c6f8906ae86fc0ce77209a053\",\"fullnode_addresses\":\"0x013e0402146170746f732d76666e2e66617262656e2e78797a052618072065e698b7b7ee50f0d2a12d1e1d79953c96d601137aaa0e7af12334417b77a30e0800\",\"network_addresses\":\"0x013d0402136170746f732d766e2e66617262656e2e78797a0524180720eb78e9bade8541266251c443878324b3aea68deb5bc527d7e9b4018e805b5d4e0800\",\"validator_index\":\"135\"},\"voting_power\":\"101744068251002\"},{\"addr\":\"0xe888a0adfb4ca871bfe6aada8511f5326e877a8ce66a9980ef089eb2218d740c\",\"config\":{\"consensus_pubkey\":\"0xb85d80cb5d945573a708ffd15fa69153d11329755dfc685832816f5aa490b02903dc8c1397282cda5ca7816c8d6c67b6\",\"fullnode_addresses\":\"0x012d040023e156a90526180720ee867b185eff1ed682105b60763e1bf3ad21c2757a2ad2c305603e61d920a20f0800\",\"network_addresses\":\"0x012d040023e002620524180720d28c1386973f0f914c97dfa8a15666491bac9af476588e7fb24381138f667a0a0800\",\"validator_index\":\"136\"},\"voting_power\":\"207448013491878\"},{\"addr\":\"0x1af6830eed3ca4a078110b36b81ec8aa73224c6d0c4c33911089ef6d576645e8\",\"config\":{\"consensus_pubkey\":\"0xa0f5c3009ccd047388def875f276ad3ae93d85a5d871354a13fb506096102964331189f4bc6afacc89ce6c2de6e9a640\",\"fullnode_addresses\":\"0x014404021a6170746f732d666e2e6563686f2d70726f746f636f6c2e78797a05261807200d8f59f3e9cecf4b0a3ce92b08ba7c24b9141b59c0af023ccbae3f6685cc31630800\",\"network_addresses\":\"0x014504021b6170746f732d76616c2e6563686f2d70726f746f636f6c2e78797a0524180720ffe145b3a7e55a085b54994405fc07f0216b6e649791634b74bf3e99e7f2ed2c0800\",\"validator_index\":\"137\"},\"voting_power\":\"201993061852064\"},{\"addr\":\"0x8bf2201bf4cec31f736aacc0f44f29c014ecd8562975aecce19271ca179e8db5\",\"config\":{\"consensus_pubkey\":\"0xa909b0b260c85566b0917d1e40da1656d3c3abd84c9a3287679cec86b301c5fdac4d5bce7425199fe37e957a4127752e\",\"fullnode_addresses\":\"0x014a04022076666e2d322e6170746f732d6d61696e6e65742e7477696e7374616b652e696f0526180720195d1dcdd1d3ee7c4b18c032aa3de5297f77c7ee556f59c4b9136792ca49e1370800\",\"network_addresses\":\"0x014904021f766e2d322e6170746f732d6d61696e6e65742e7477696e7374616b652e696f052418072040e4407e1fec1153112dc058efe144326964a577b47f980d65cf1816d95a833d0800\",\"validator_index\":\"138\"},\"voting_power\":\"909637427450618\"},{\"addr\":\"0xee36c1068076b199cf537bf652b1e586216a7dfb7c3447ff40333c971717eee6\",\"config\":{\"consensus_pubkey\":\"0x8c36e6bcd0c1181880d976ec7472e915a01b946c7ab6bc39e07cfa21ee83c1ac5d1e229c87e2202b85a51351f5697739\",\"fullnode_addresses\":\"0x014504021b76666e5f706f6f6c2e6170746f732e647372766c6162732e6e6574052618072094d44886a684c2882fbdbc3aee0a2eed97461bb68d0dd26b8cf01f2eb81e77330800\",\"network_addresses\":\"0x014404021a766e5f706f6f6c2e6170746f732e647372766c6162732e6e657405241807208d3f418b665e11ee3cb935982f18b66b793602889456f85dcf2db4b88ac263720800\",\"validator_index\":\"139\"},\"voting_power\":\"240640384441589\"},{\"addr\":\"0xadbfddd3d10cad1eed59d2c0793df0bfd1d16255309c38b34b8351daaddecccc\",\"config\":{\"consensus_pubkey\":\"0xaa7f529d110f94ca18e458c86dc254c981e5be4991c06d68911a646521a7ab083ca6a478eb651a828261719a745ec543\",\"fullnode_addresses\":\"0x014504021b6170746f732d6d61696e6e65742d76666e2e7665727365322e696f05261807205ec1236035e269b1c1d13406d139bd8fe47eeeb9bcb25e93b1e54ed177801d0d0800\",\"network_addresses\":\"0x014404021a6170746f732d6d61696e6e65742d766e2e7665727365322e696f05241807202c215c409598707af21f9ab64add05f9fe73d4cbb2e0e26937a40d140aa9db110800\",\"validator_index\":\"140\"},\"voting_power\":\"136051238540677\"},{\"addr\":\"0xe1bee86370ba9adf23e7c009b8b077fd5eef056990cd97f26535c85e891aa747\",\"config\":{\"consensus_pubkey\":\"0x88a0764f599803222d494325258735b8351926b8cd6edc6a4862c64bf0626ad34bd56a9acf48b32f123118aaa781c8d6\",\"fullnode_addresses\":\"0x014a040220637264666b686c6f6376763936323072746163672e62646e6f6465732e6e657405261807206e57910750af787558ee1051f087c0b274bd58581e57a55b36799f682cfd606d0800\",\"network_addresses\":\"0x014a040220637264666b686c6f6376763936323072746163672e62646e6f6465732e6e65740524180720adcae0bb635bceed27d457143717c1ae7cec6aa946ae3b9ce419509a2bd94f2c0800\",\"validator_index\":\"141\"},\"voting_power\":\"201110037434262\"},{\"addr\":\"0x7acdf689a17fed9692e97d15d444d769ba26ca4f95b014736e446724de8fd0c1\",\"config\":{\"consensus_pubkey\":\"0x891bbd9de84877ddc0d53b9711cd305863dcb0deb6ea7c66c849ba05f772204c2d80e8d8b5d2872d7f341aa84f8243e5\",\"fullnode_addresses\":\"0x012d04000febdbfa0526180720a0cd70f605c75c3c4c938426bad92724cdef1c29a1ded9acb62095657b35f8000800\",\"network_addresses\":\"0x012d04000febdbf205241807208668adff268d6fd77260a9b9c048e0bd2cc19c5dd65f707a7c0db718d86a164c0800\",\"validator_index\":\"142\"},\"voting_power\":\"302292611187566\"},{\"addr\":\"0x2d1145fbe500566c204b7f3f3e04b1318a93e44debdd8b5bee8f3fcafccae2c7\",\"config\":{\"consensus_pubkey\":\"0x993e5857821947a97ae3809aa56d5f2c82759bf01226c2bdad32608a24146c266ebba16778f92ed6a4c31fe11c037030\",\"fullnode_addresses\":\"0x014604021c76666e2d736b742e6170746f732d6d61696e6e65742e6134312e696f0526180720e3593f4662d10669c47b02c403f213cb7f64f31ee76b05adce6e9b24bfab5d130800\",\"network_addresses\":\"0x014504021b766e2d736b742e6170746f732d6d61696e6e65742e6134312e696f0524180720c70a46fd0f54e601a928544605b6ac6083fd571b9e4bd33d6e8d8508b0c5e00f0800\",\"validator_index\":\"143\"},\"voting_power\":\"502616004245048\"},{\"addr\":\"0x91df39d4ae2fac731d02ade7848f332ce701e1a598d773e1be1f6382d3959150\",\"config\":{\"consensus_pubkey\":\"0x892b06096a8d632a20a71030282654c8e8dc8d28c39cab429a1631367222881c25d514e79b9d293c6421f14d5113cb59\",\"fullnode_addresses\":\"0x012d0400221fe67805261807200ce2d1800c40783106f514b0609845e5ce32760a2ec6555b676183ecee20ed560800\",\"network_addresses\":\"0x012d040022abc8b10524180720d9e8bba3a490e03dcf1438783d2cb046b347df5c72795eee524b47dd920476270800\",\"validator_index\":\"144\"},\"voting_power\":\"601155864610919\"},{\"addr\":\"0xcfb4330556f9e4d3283a944d4c1763113cee40143182e8d874437368bd1b33ba\",\"config\":{\"consensus_pubkey\":\"0xb200c50a777413c72b638cdff64b04e8134e2454dc152bde6875fc6d67f42fda9c80a2a2cf329671da6982479c24d665\",\"fullnode_addresses\":\"0x014c04022276666e302e65757765342d322e6d61696e6e65742e6170746f736c6162732e636f6d0526180720139207ea83b50ff4a62d899b3a883a3f4dc17d1fa1696c0169ee6083f2a9b8320800\",\"network_addresses\":\"0x014c04022276616c302e65757765342d322e6d61696e6e65742e6170746f736c6162732e636f6d0524180720a7c69c6a3b7cd4b2be101814d0aa0e6fd203b1b7b3d962e84909200189f4d63c0800\",\"validator_index\":\"145\"},\"voting_power\":\"1301571445586643\"},{\"addr\":\"0x7ab6a74d31778b26a8344605d50f5541bcee06c4da509c33dd51124a6113d513\",\"config\":{\"consensus_pubkey\":\"0x83f13919c78c0fabbd6ce2d12417ce2a934db493b3906c1481efad36e438bdd02b336a985758796e0a5906f560db191f\",\"fullnode_addresses\":\"0x012d040040b04053052618072027137483b8969927c4f086f3cdfd7fbb406bde99f975c34939ab346afa4aac3d0800\",\"network_addresses\":\"0x012d04004622fd170524180720c212c7ac1dd2b6c6a423595ba86c34f19f81877857883fe889bfaacdf2d22e7b0800\",\"validator_index\":\"146\"},\"voting_power\":\"100091469802149\"},{\"addr\":\"0xab4a80ccc772691cb03e3ee8d22b5c13acc92472dd4a19987c1aade2691404a\",\"config\":{\"consensus_pubkey\":\"0xa5d1a9397f63c51166932f9be8088d00d947e9e59043c899a8faacd932a7f6cc2103d324b885dc0d5454e6340ae98a0a\",\"fullnode_addresses\":\"0x014c04022276666e302e61706e65312d312e6d61696e6e65742e6170746f736c6162732e636f6d05261807200c5cfb2a5ff006cb92f2ee8cf438ad8aa6702783acaeab85eb9e4e25596cab4e0800\",\"network_addresses\":\"0x014c04022276616c302e61706e65312d312e6d61696e6e65742e6170746f736c6162732e636f6d05241807207349d06429b7858f533d1e36520b8556299cef9e4f869f336a76120fb9c472360800\",\"validator_index\":\"147\"},\"voting_power\":\"680613366745707\"},{\"addr\":\"0xf0d49cff005d03312934ce027e30f4a84143d5af53623b30036e7dac1510c218\",\"config\":{\"consensus_pubkey\":\"0x957ead308d5c803bc86c998c52084da26886b26e9b0faebef4429a96863e072af908f22d78c438135b71c70eaf9d8eb1\",\"fullnode_addresses\":\"0x014b040221626974676f2d66756c6c312e6d61696e6e65742e6170746f732e7032702e6f726705261807208e2d5ecf7dd92cdf560341d5ad8c8c105b84594bce84754d406b37439ba1924c0800\",\"network_addresses\":\"0x014a040220626974676f2d76616c312e6d61696e6e65742e6170746f732e7032702e6f7267052418072014d2cd3b78241cdac16644ffdf9157680b8963c18ced41cc7e9a94ea56cbf21d0800\",\"validator_index\":\"148\"},\"voting_power\":\"2369819363428270\"}],\"consensus_scheme\":0,\"pending_active\":[],\"pending_inactive\":[],\"total_joining_power\":\"1024177918363\",\"total_voting_power\":\"88095538470559473\"}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282", - "stateKeyHash": "11yLrAC90lw1fapughKi02ey6pZEc/O7LHMnEExfd4w=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"0\"},\"deposit_events\":{\"counter\":\"22\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"22\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282", - "stateKeyHash": "0of4vRtGQvNe/0vUKOBNDxaT6P0MJXJKZ6B5JdR5wyA=", - "type": { - "address": "0x1", - "module": "stake", - "name": "StakePool" - }, - "typeStr": "0x1::stake::StakePool", - "data": "{\"active\":{\"value\":\"204151692720922\"},\"add_stake_events\":{\"counter\":\"16\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"6\"}}},\"delegated_voter\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"distribute_rewards_events\":{\"counter\":\"1440\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"12\"}}},\"inactive\":{\"value\":\"2622762999\"},\"increase_lockup_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"10\"}}},\"initialize_validator_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"4\"}}},\"join_validator_set_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"11\"}}},\"leave_validator_set_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"15\"}}},\"locked_until_secs\":\"1730915993\",\"operator_address\":\"0xb1a1d4624c5163445c993d9db9cd5bd3fc6b2c5e85a14216c3781d04d4f92d08\",\"pending_active\":{\"value\":\"1103000000\"},\"pending_inactive\":{\"value\":\"2563903267\"},\"reactivate_stake_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"7\"}}},\"rotate_consensus_key_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"8\"}}},\"set_operator_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"5\"}}},\"unlock_stake_events\":{\"counter\":\"12\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"13\"}}},\"update_network_and_fullnode_addresses_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"9\"}}},\"withdraw_stake_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"14\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282", - "stateKeyHash": "HoFb08JPrZMefUn9pNirTvzesYh9oHB/uuR7kLFpWAc=", - "type": { - "address": "0x1", - "module": "delegation_pool", - "name": "DelegationPool" - }, - "typeStr": "0x1::delegation_pool::DelegationPool", - "data": "{\"active_shares\":{\"scaling_factor\":\"10000000000000000\",\"shares\":{\"inner\":{\"handle\":\"0x47da3279e65643854e3abb7af1fd2a9082dda18f10c469759e2b3cd964044ab3\"},\"length\":\"15\"},\"total_coins\":\"204152795720922\",\"total_shares\":\"2000205706018468258190989373484\"},\"add_stake_events\":{\"counter\":\"16\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"16\"}}},\"distribute_commission_events\":{\"counter\":\"83\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"20\"}}},\"inactive_shares\":{\"handle\":\"0xd5d080845aad4a0e20ad583dac7e2e0119ce534a313a0cfd939dd11b5acb111e\"},\"observed_lockup_cycle\":{\"index\":\"4\"},\"operator_commission_percentage\":\"900\",\"pending_withdrawals\":{\"handle\":\"0xd65ef475c9329ea3f1a12e57c63f2ef907ab497e00d2e367c6cec270ba4cee64\"},\"reactivate_stake_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"17\"}}},\"stake_pool_signer_cap\":{\"account\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\"},\"total_coins_inactive\":\"2622762999\",\"unlock_stake_events\":{\"counter\":\"12\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"18\"}}},\"withdraw_stake_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"19\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282", - "stateKeyHash": "FP5gVF5g95HXpzN8ytfYoLIhZlK+cDyfjfTVf6kAyGI=", - "type": { - "address": "0x1", - "module": "delegation_pool", - "name": "GovernanceRecords" - }, - "typeStr": "0x1::delegation_pool::GovernanceRecords", - "data": "{\"create_proposal_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"22\"}}},\"delegate_voting_power_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"23\"}}},\"delegated_votes\":{\"buckets\":{\"inner\":{\"handle\":\"0xb87334b5be84b86399a779e0e9a9487caad7e6bd37a7ae59c05c5676764820eb\"},\"length\":\"3\"},\"level\":1,\"num_buckets\":\"3\",\"size\":\"17\",\"split_load_threshold\":75,\"target_bucket_size\":\"10\"},\"vote_delegation\":{\"buckets\":{\"inner\":{\"handle\":\"0x2d4a524628268af00d4b0fa8aaf8e84fb58d6f0d7972a951ebbafc7e2042d006\"},\"length\":\"3\"},\"level\":1,\"num_buckets\":\"3\",\"size\":\"17\",\"split_load_threshold\":75,\"target_bucket_size\":\"9\"},\"vote_events\":{\"counter\":\"17\",\"guid\":{\"id\":{\"addr\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\",\"creation_num\":\"21\"}}},\"votes\":{\"buckets\":{\"inner\":{\"handle\":\"0x81bdfdf934342eaafbfe09b4ce2f6a337a5f172c6c401e7e8da50d6cdca0315d\"},\"length\":\"2\"},\"level\":1,\"num_buckets\":\"2\",\"size\":\"17\",\"split_load_threshold\":75,\"target_bucket_size\":\"18\"},\"votes_per_proposal\":{\"buckets\":{\"inner\":{\"handle\":\"0xb1114d3dc9173f6e35bc1b46b040023cf6cbab60e429302bf2271525c5ba3696\"},\"length\":\"2\"},\"level\":1,\"num_buckets\":\"2\",\"size\":\"17\",\"split_load_threshold\":75,\"target_bucket_size\":\"42\"}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952", - "stateKeyHash": "gETv9CDRRWAhKeDsNeLEo4K6jh+3GM+1yym3D1i0/p8=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"79200189\"},\"deposit_events\":{\"counter\":\"40\",\"guid\":{\"id\":{\"addr\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"55\",\"guid\":{\"id\":{\"addr\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952", - "stateKeyHash": "fLq21WF1RT+wQhLUUSuyaqwXh1UybhD68DG3oWFmIB0=", - "type": { - "address": "0x1", - "module": "account", - "name": "Account" - }, - "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\",\"coin_register_events\":{\"counter\":\"25\",\"guid\":{\"id\":{\"addr\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"78\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"146\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", - "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", - "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", - "data": { - "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", - "keyType": "address", - "value": "\"112245508685882051\"", - "valueType": "u128" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "9Xdu7BZDW22oE1D2/LNnLNB96gEgSYJ+x+QDA/kR8wU=", - "handle": "0x2d4a524628268af00d4b0fa8aaf8e84fb58d6f0d7972a951ebbafc7e2042d006", - "key": "0x0000000000000000", - "data": { - "key": "\"0\"", - "keyType": "u64", - "value": "[{\"hash\":\"6979483115129658744\",\"key\":\"0x29e6421074d0f8c1c076d6563a1de662946c9b0a441cabdd76b4ae9379c513b9\",\"value\":{\"last_locked_until_secs\":\"0\",\"pending_voter\":\"0x29e6421074d0f8c1c076d6563a1de662946c9b0a441cabdd76b4ae9379c513b9\",\"voter\":\"0x29e6421074d0f8c1c076d6563a1de662946c9b0a441cabdd76b4ae9379c513b9\"}},{\"hash\":\"16375248214741987812\",\"key\":\"0x98fe3070c497cd7e52c7e0b6eeb18a0b910604124e7c739a4896653be44e9781\",\"value\":{\"last_locked_until_secs\":\"1722089485\",\"pending_voter\":\"0x98fe3070c497cd7e52c7e0b6eeb18a0b910604124e7c739a4896653be44e9781\",\"voter\":\"0x98fe3070c497cd7e52c7e0b6eeb18a0b910604124e7c739a4896653be44e9781\"}},{\"hash\":\"930222532477502732\",\"key\":\"0x896ef68e5eee178faf74122e3b7b48b74290d2e1c40dde50728e10ef503da119\",\"value\":{\"last_locked_until_secs\":\"1722089485\",\"pending_voter\":\"0x896ef68e5eee178faf74122e3b7b48b74290d2e1c40dde50728e10ef503da119\",\"voter\":\"0x896ef68e5eee178faf74122e3b7b48b74290d2e1c40dde50728e10ef503da119\"}},{\"hash\":\"6031278649259050940\",\"key\":\"0xc02c84f869b1a5172f21ce56b4733ae2fca8aa14b57e5e8f00db790ea285fd9b\",\"value\":{\"last_locked_until_secs\":\"1724682896\",\"pending_voter\":\"0xc02c84f869b1a5172f21ce56b4733ae2fca8aa14b57e5e8f00db790ea285fd9b\",\"voter\":\"0xc02c84f869b1a5172f21ce56b4733ae2fca8aa14b57e5e8f00db790ea285fd9b\"}},{\"hash\":\"664909098963046500\",\"key\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\",\"value\":{\"last_locked_until_secs\":\"1730915993\",\"pending_voter\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\",\"voter\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\"}}]", - "valueType": "vector<0x1::smart_table::Entry>" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "LG1Usi9F5BN384MHsfAyxmufHLEchj1gZdf5scD9Rmc=", - "handle": "0x47da3279e65643854e3abb7af1fd2a9082dda18f10c469759e2b3cd964044ab3", - "key": "0x0000000000000000000000000000000000000000000000000000000000000000", - "data": { - "key": "\"0x0\"", - "keyType": "address", - "value": "\"152470119682369959286\"", - "valueType": "u128" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "PGTGSqPlEHx68Ov78pC5GXc+r/MWaeYsGPpt1k/5BsM=", - "handle": "0x47da3279e65643854e3abb7af1fd2a9082dda18f10c469759e2b3cd964044ab3", - "key": "0xb1a1d4624c5163445c993d9db9cd5bd3fc6b2c5e85a14216c3781d04d4f92d08", - "data": { - "key": "\"0xb1a1d4624c5163445c993d9db9cd5bd3fc6b2c5e85a14216c3781d04d4f92d08\"", - "keyType": "address", - "value": "\"25118843728449721241657181\"", - "valueType": "u128" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "v0ujUoNkUtGcQk1Dm5NSV6ocMIOHgVkHb092dJaF77o=", - "handle": "0x47da3279e65643854e3abb7af1fd2a9082dda18f10c469759e2b3cd964044ab3", - "key": "0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952", - "data": { - "key": "\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\"", - "keyType": "address", - "value": "\"10806591008202773939813398\"", - "valueType": "u128" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "UQcWrBKvjvqTSmpo6tFQE1OvbiB16QWawIoj78nSrFA=", - "handle": "0xb87334b5be84b86399a779e0e9a9487caad7e6bd37a7ae59c05c5676764820eb", - "key": "0x0000000000000000", - "data": { - "key": "\"0\"", - "keyType": "u64", - "value": "[{\"hash\":\"6979483115129658744\",\"key\":\"0x29e6421074d0f8c1c076d6563a1de662946c9b0a441cabdd76b4ae9379c513b9\",\"value\":{\"active_shares\":\"2000000000000000000000000000000\",\"active_shares_next_lockup\":\"2000000000000000000000000000000\",\"last_locked_until_secs\":\"0\",\"pending_inactive_shares\":\"0\"}},{\"hash\":\"16375248214741987812\",\"key\":\"0x98fe3070c497cd7e52c7e0b6eeb18a0b910604124e7c739a4896653be44e9781\",\"value\":{\"active_shares\":\"13262685066752048172324252\",\"active_shares_next_lockup\":\"13262685066752048172324252\",\"last_locked_until_secs\":\"1722089485\",\"pending_inactive_shares\":\"0\"}},{\"hash\":\"930222532477502732\",\"key\":\"0x896ef68e5eee178faf74122e3b7b48b74290d2e1c40dde50728e10ef503da119\",\"value\":{\"active_shares\":\"34877401591671454671104304\",\"active_shares_next_lockup\":\"34877401591671454671104304\",\"last_locked_until_secs\":\"1729703448\",\"pending_inactive_shares\":\"0\"}},{\"hash\":\"6031278649259050940\",\"key\":\"0xc02c84f869b1a5172f21ce56b4733ae2fca8aa14b57e5e8f00db790ea285fd9b\",\"value\":{\"active_shares\":\"10938777059257542029402807\",\"active_shares_next_lockup\":\"10938777059257542029402807\",\"last_locked_until_secs\":\"1724682896\",\"pending_inactive_shares\":\"0\"}},{\"hash\":\"664909098963046500\",\"key\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\",\"value\":{\"active_shares\":\"10806591008202773939813398\",\"active_shares_next_lockup\":\"10806591008202773939813398\",\"last_locked_until_secs\":\"1730915993\",\"pending_inactive_shares\":\"0\"}}]", - "valueType": "vector<0x1::smart_table::Entry>" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "fZRzb+q7MwtzXBzZqpY19p3Nryh+eSw4BVQ4MVWmm0k=", - "handle": "0xb87334b5be84b86399a779e0e9a9487caad7e6bd37a7ae59c05c5676764820eb", - "key": "0x0100000000000000", - "data": { - "key": "\"1\"", - "keyType": "u64", - "value": "[{\"hash\":\"12736911355601039089\",\"key\":\"0xb1a1d4624c5163445c993d9db9cd5bd3fc6b2c5e85a14216c3781d04d4f92d08\",\"value\":{\"active_shares\":\"25118843728449721241657181\",\"active_shares_next_lockup\":\"25118843728449721241657181\",\"last_locked_until_secs\":\"1730915993\",\"pending_inactive_shares\":\"25639851983718399220760460\"}},{\"hash\":\"7797948686568424061\",\"key\":\"0x0\",\"value\":{\"active_shares\":\"152470119682369959286\",\"active_shares_next_lockup\":\"152470119682369959286\",\"last_locked_until_secs\":\"1730915993\",\"pending_inactive_shares\":\"0\"}},{\"hash\":\"13858633305312752977\",\"key\":\"0x94ee9966a3d69705eaae29ef5b5f38747c8eaaa65c8b680db8ac0bce5dae282a\",\"value\":{\"active_shares\":\"0\",\"active_shares_next_lockup\":\"0\",\"last_locked_until_secs\":\"1729703448\",\"pending_inactive_shares\":\"26213571470000000000000000\"}},{\"hash\":\"8609209306266606137\",\"key\":\"0x76f2dbf501c514f3dd6e96f9b511f2cbd20fac265cf44d185268c7cf367c814b\",\"value\":{\"active_shares\":\"12927830795544929564501625\",\"active_shares_next_lockup\":\"12927830795544929564501625\",\"last_locked_until_secs\":\"1724682896\",\"pending_inactive_shares\":\"0\"}},{\"hash\":\"11590363594355174939\",\"key\":\"0x6cdd2e750e1188d98f644e6628d1ac399b74cb2ce0b6b84fb696c044e567c60d\",\"value\":{\"active_shares\":\"10784956641648224341898476\",\"active_shares_next_lockup\":\"10784956641648224341898476\",\"last_locked_until_secs\":\"1729703448\",\"pending_inactive_shares\":\"0\"}},{\"hash\":\"15216442237181271931\",\"key\":\"0xface9c7372f35fa461ad168cb1094e523a0a89f8e2796b0e21c217c85e19d71a\",\"value\":{\"active_shares\":\"22758713397477337947993963\",\"active_shares_next_lockup\":\"22758713397477337947993963\",\"last_locked_until_secs\":\"1730915993\",\"pending_inactive_shares\":\"0\"}},{\"hash\":\"2932381372283928247\",\"key\":\"0xa64189d523f0084ef7c24a7b950ac1123732d79efd543954b4e83aeafabaac42\",\"value\":{\"active_shares\":\"10791010049065335484646666\",\"active_shares_next_lockup\":\"10791010049065335484646666\",\"last_locked_until_secs\":\"1729703448\",\"pending_inactive_shares\":\"0\"}},{\"hash\":\"9092696905113526367\",\"key\":\"0x252c3c3f676bb41e37ae79ef4efe3dd4802c7a175e68819e73af37f55200fdfc\",\"value\":{\"active_shares\":\"10864889004782414356809020\",\"active_shares_next_lockup\":\"10864889004782414356809020\",\"last_locked_until_secs\":\"1729703448\",\"pending_inactive_shares\":\"0\"}}]", - "valueType": "vector<0x1::smart_table::Entry>" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "tygkxYlyEo6ARrh05adaJv0ZHDLvn0ly7FiKAR0cxJ8=", - "handle": "0xd5d080845aad4a0e20ad583dac7e2e0119ce534a313a0cfd939dd11b5acb111e", - "key": "0x0400000000000000", - "data": { - "key": "{\"index\":\"4\"}", - "keyType": "0x1::delegation_pool::ObservedLockupCycle", - "value": "{\"scaling_factor\":\"10000000000000000\",\"shares\":{\"inner\":{\"handle\":\"0xfffc3802cd3b421aebb2b49bef3e7edf01bf0f0d145b40c898a5aa369a7fb955\"},\"length\":\"1\"},\"total_coins\":\"2563903267\",\"total_shares\":\"25635777079116921058748870\"}", - "valueType": "0x1::pool_u64_unbound::Pool" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "BusPtZeHgwOG27V5PK6gxY5mu1qtCIEFiQH1lNYNzuo=", - "handle": "0xfffc3802cd3b421aebb2b49bef3e7edf01bf0f0d145b40c898a5aa369a7fb955", - "key": "0xb1a1d4624c5163445c993d9db9cd5bd3fc6b2c5e85a14216c3781d04d4f92d08", - "data": { - "key": "\"0xb1a1d4624c5163445c993d9db9cd5bd3fc6b2c5e85a14216c3781d04d4f92d08\"", - "keyType": "address", - "value": "\"25635777079116921058748870\"", - "valueType": "u128" - } - } - } - ] - }, - "epoch": "8969", - "blockHeight": "243311411", - "type": "TRANSACTION_TYPE_USER", - "sizeInfo": { - "transactionBytes": 268, - "eventSizeInfo": [ - { - "typeTagBytes": 76, - "totalBytes": 204 - }, - { - "typeTagBytes": 71, - "totalBytes": 183 - }, - { - "typeTagBytes": 53, - "totalBytes": 109 - }, - { - "typeTagBytes": 52, - "totalBytes": 108 - }, - { - "typeTagBytes": 53, - "totalBytes": 109 - }, - { - "typeTagBytes": 54, - "totalBytes": 142 - }, - { - "typeTagBytes": 64, - "totalBytes": 192 - }, - { - "typeTagBytes": 63, - "totalBytes": 103 - } - ], - "writeOpSizeInfo": [ - { - "keyBytes": 87, - "valueBytes": 34705 - }, - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 680 - }, - { - "keyBytes": 99, - "valueBytes": 432 - }, - { - "keyBytes": 102, - "valueBytes": 408 - }, - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 147 - }, - { - "keyBytes": 66, - "valueBytes": 16 - }, - { - "keyBytes": 42, - "valueBytes": 561 - }, - { - "keyBytes": 66, - "valueBytes": 16 - }, - { - "keyBytes": 66, - "valueBytes": 16 - }, - { - "keyBytes": 66, - "valueBytes": 16 - }, - { - "keyBytes": 42, - "valueBytes": 481 - }, - { - "keyBytes": 42, - "valueBytes": 769 - }, - { - "keyBytes": 42, - "valueBytes": 72 - }, - { - "keyBytes": 66, - "valueBytes": 16 - } - ] - }, - "user": { - "request": { - "sender": "0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952", - "sequenceNumber": "145", - "maxGasAmount": "2688", - "gasUnitPrice": "100", - "expirationTimestampSecs": { - "seconds": "1729804067" - }, - "payload": { - "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", - "entryFunctionPayload": { - "function": { - "module": { - "address": "0x1", - "name": "delegation_pool" - }, - "name": "add_stake" - }, - "arguments": [ - "\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\"", - "\"1103000000\"" - ], - "entryFunctionIdStr": "0x1::delegation_pool::add_stake" - } - }, - "signature": { - "type": "TYPE_ED25519", - "ed25519": { - "publicKey": "2tWsmYoNJw52IHjuPCziKJQ7XJTKlOYP8sZZ/UU9GP0=", - "signature": "S3ykjMTZb5gX4vPkLJkfCV10g+UZYatHDTjor5OGeAku3/p7cb8pSEwDNd17bdMwvS/86OuFNGU+pCCHYwqgAg==" - } - } - }, - "events": [ - { - "key": { - "creationNumber": "20", - "accountAddress": "0x001232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282" - }, - "sequenceNumber": "82", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "delegation_pool", - "name": "DistributeCommissionEvent" - } - }, - "typeStr": "0x1::delegation_pool::DistributeCommissionEvent", - "data": "{\"commission_active\":\"2563777394\",\"commission_pending_inactive\":\"32197\",\"operator\":\"0xb1a1d4624c5163445c993d9db9cd5bd3fc6b2c5e85a14216c3781d04d4f92d08\",\"pool_address\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\"}" - }, - { - "key": { - "accountAddress": "0x0" - }, - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "delegation_pool", - "name": "DistributeCommission" - } - }, - "typeStr": "0x1::delegation_pool::DistributeCommission", - "data": "{\"beneficiary\":\"0xb1a1d4624c5163445c993d9db9cd5bd3fc6b2c5e85a14216c3781d04d4f92d08\",\"commission_active\":\"2563777394\",\"commission_pending_inactive\":\"32197\",\"operator\":\"0xb1a1d4624c5163445c993d9db9cd5bd3fc6b2c5e85a14216c3781d04d4f92d08\",\"pool_address\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\"}" - }, - { - "key": { - "creationNumber": "3", - "accountAddress": "0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952" - }, - "sequenceNumber": "54", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "coin", - "name": "WithdrawEvent" - } - }, - "typeStr": "0x1::coin::WithdrawEvent", - "data": "{\"amount\":\"1103000000\"}" - }, - { - "key": { - "creationNumber": "2", - "accountAddress": "0x001232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282" - }, - "sequenceNumber": "21", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "coin", - "name": "DepositEvent" - } - }, - "typeStr": "0x1::coin::DepositEvent", - "data": "{\"amount\":\"1103000000\"}" - }, - { - "key": { - "creationNumber": "3", - "accountAddress": "0x001232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282" - }, - "sequenceNumber": "21", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "coin", - "name": "WithdrawEvent" - } - }, - "typeStr": "0x1::coin::WithdrawEvent", - "data": "{\"amount\":\"1103000000\"}" - }, - { - "key": { - "creationNumber": "6", - "accountAddress": "0x001232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282" - }, - "sequenceNumber": "15", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "stake", - "name": "AddStakeEvent" - } - }, - "typeStr": "0x1::stake::AddStakeEvent", - "data": "{\"amount_added\":\"1103000000\",\"pool_address\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\"}" - }, - { - "key": { - "creationNumber": "16", - "accountAddress": "0x001232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282" - }, - "sequenceNumber": "15", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "delegation_pool", - "name": "AddStakeEvent" - } - }, - "typeStr": "0x1::delegation_pool::AddStakeEvent", - "data": "{\"add_stake_fee\":\"15562\",\"amount_added\":\"1103000000\",\"delegator_address\":\"0xd394ba7a55f6d0cb4952679fac1db53926869ed975d3fdcf8fedcbbb7480b952\",\"pool_address\":\"0x1232f58b963938486a11f88c1c36d61d82738b1828625a95a1e85b4c8d1282\"}" - }, - { - "key": { - "accountAddress": "0x0" - }, - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "transaction_fee", - "name": "FeeStatement" - } - }, - "typeStr": "0x1::transaction_fee::FeeStatement", - "data": "{\"execution_gas_units\":\"26\",\"io_gas_units\":\"23\",\"storage_fee_octas\":\"129600\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"1344\"}" - } - ] - } -} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/214433968_ans_lookup.json b/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/214433968_ans_lookup.json deleted file mode 100644 index de3ffe4ae8074..0000000000000 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/214433968_ans_lookup.json +++ /dev/null @@ -1,243 +0,0 @@ -{ - "timestamp": { - "seconds": "1691494645", - "nanos": 85585000 - }, - "version": "214433968", - "info": { - "hash": "p2mwf7M/7GcGiTvfflhXp+iEHHA54ZW+gjLxM9CiQTw=", - "stateChangeHash": "blFxBE6oaHIdI5uXAy7j7GoLiHbrGPHUlBfMvexbbVQ=", - "eventRootHash": "6XY62wcnX3kOCQ+lTW+QOimGiL39rCxeiqvVKmiamcg=", - "gasUsed": "35", - "success": true, - "vmStatus": "Executed successfully", - "accumulatorRootHash": "mlzH++kw7gK9khOHHo1rkTbvAG12iYKEsqN7hSvqehw=", - "changes": [ - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006", - "stateKeyHash": "qspP7DSdlSw6+daqDMLmjFx11i9HS/UIx3fyNVtNnRU=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"110758984\"},\"deposit_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"7\",\"guid\":{\"id\":{\"addr\":\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006", - "stateKeyHash": "cXA79NBtJgepdKahkaqhTkr8+6hcrhXGCvEUAMYfjQU=", - "type": { - "address": "0x1", - "module": "account", - "name": "Account" - }, - "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\",\"coin_register_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"12\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"10\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006", - "stateKeyHash": "fIbdQ5Yu+MsRusJ4mhPVecZRXdyEKtD95WtjUo/uC1U=", - "type": { - "address": "0x3", - "module": "token", - "name": "TokenStore" - }, - "typeStr": "0x3::token::TokenStore", - "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\",\"creation_num\":\"8\"}}},\"deposit_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\",\"creation_num\":\"6\"}}},\"direct_transfer\":false,\"mutate_token_property_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\",\"creation_num\":\"9\"}}},\"tokens\":{\"handle\":\"0x53621280f0c9e381f0aee24750cf8a62e37966e014c73e6f6075040705766430\"},\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\",\"creation_num\":\"7\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "stateKeyHash": "q4Wci+JMAePdRidB+XcB9eieDZ0/LA5Awh7i8qY+ekI=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetNameAddressEventsV1" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetNameAddressEventsV1", - "data": "{\"set_name_events\":{\"counter\":\"107460\",\"guid\":{\"id\":{\"addr\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"creation_num\":\"4\"}}}}" - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", - "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", - "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", - "data": { - "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", - "keyType": "address", - "value": "\"104879388586174126\"", - "valueType": "u128" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "s4NRRy2W/l+mVlubpKaVMG6gS77b5Z1PhgMkjQnCmyI=", - "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", - "key": "0x01033033380f63727970746f676c61646961746f72", - "data": { - "key": "{\"domain_name\":\"cryptogladiator\",\"subdomain_name\":{\"vec\":[\"038\"]}}", - "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1", - "value": "{\"expiration_time_sec\":\"1715246873\",\"property_version\":\"1\",\"target_address\":{\"vec\":[\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\"]}}", - "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordV1" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "dMPAJnhb6Xu3SIvQv2ci8ImnthcANXKbKxNCbP+1s8E=", - "handle": "0x53621280f0c9e381f0aee24750cf8a62e37966e014c73e6f6075040705766430", - "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d6573205631173033382e63727970746f676c61646961746f722e6170740100000000000000", - "data": { - "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"038.cryptogladiator.apt\"}}", - "keyType": "0x3::token::TokenId", - "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"038.cryptogladiator.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x7c939c6400000000\"}},{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x09737562646f6d61696e\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x19973c6600000000\"}}]}}}", - "valueType": "0x3::token::Token" - } - } - } - ] - }, - "epoch": "3604", - "blockHeight": "78523174", - "type": "TRANSACTION_TYPE_USER", - "sizeInfo": { - "transactionBytes": 285, - "eventSizeInfo": [ - { - "typeTagBytes": 64, - "totalBytes": 182 - }, - { - "typeTagBytes": 68, - "totalBytes": 346 - } - ], - "writeOpSizeInfo": [ - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 147 - }, - { - "keyBytes": 85, - "valueBytes": 225 - }, - { - "keyBytes": 99, - "valueBytes": 48 - }, - { - "keyBytes": 66, - "valueBytes": 16 - }, - { - "keyBytes": 55, - "valueBytes": 49 - }, - { - "keyBytes": 113, - "valueBytes": 188 - } - ] - }, - "user": { - "request": { - "sender": "0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006", - "sequenceNumber": "9", - "maxGasAmount": "70", - "gasUnitPrice": "100", - "expirationTimestampSecs": { - "seconds": "1691494700" - }, - "payload": { - "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", - "entryFunctionPayload": { - "function": { - "module": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "name": "domains" - }, - "name": "set_subdomain_address" - }, - "arguments": [ - "\"038\"", - "\"cryptogladiator\"", - "\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\"" - ], - "entryFunctionIdStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::set_subdomain_address" - } - }, - "signature": { - "type": "TYPE_ED25519", - "ed25519": { - "publicKey": "O575q+OaPUey682OrOiF7JCuIQK1nCs9qdSIe0BeUvQ=", - "signature": "xP0yplENYkvp0+6fvj5My9wbe1f1iQYbOiolkm7XCv6TwLRqJQDdkehDbOFHKMdDdzJbhDCjvm7ibxpjIzAlDg==" - } - } - }, - "events": [ - { - "key": { - "creationNumber": "4", - "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" - }, - "sequenceNumber": "107459", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetNameAddressEventV1" - } - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetNameAddressEventV1", - "data": "{\"domain_name\":\"cryptogladiator\",\"expiration_time_secs\":\"1715246873\",\"new_address\":{\"vec\":[\"0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006\"]},\"property_version\":\"1\",\"subdomain_name\":{\"vec\":[\"038\"]}}" - }, - { - "key": { - "creationNumber": "9", - "accountAddress": "0x2905e3f55d20eb418ea62569b2aea9a5a7afef17c05c9236364c9bb613d84006" - }, - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "MutateTokenPropertyMapEvent" - } - }, - "typeStr": "0x3::token::MutateTokenPropertyMapEvent", - "data": "{\"keys\":[\"type\",\"expiration_time_sec\"],\"new_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"038.cryptogladiator.apt\"}},\"old_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"038.cryptogladiator.apt\"}},\"types\":[\"0x1::string::String\",\"u64\"],\"values\":[\"0x09737562646f6d61696e\",\"0x19973c6600000000\"]}" - } - ] - } -} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/2739163_ans_current_ans_lookup.json b/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/2739163_ans_current_ans_lookup.json deleted file mode 100644 index cdd2b135aabea..0000000000000 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/2739163_ans_current_ans_lookup.json +++ /dev/null @@ -1,554 +0,0 @@ -{ - "timestamp": { - "seconds": "1666161427", - "nanos": 319022000 - }, - "version": "2739163", - "info": { - "hash": "bGBehR+SkR9LE3vFScA95XkjcJ6B6ajMkHP47u3wXkI=", - "stateChangeHash": "cPuY+90B8Si2dopoiJlp9nsUpqQer8YhfbQK64uxd3Q=", - "eventRootHash": "+GO09DMrs4kwf0ZtQ3Yjh9vK7AbXAuYDQoHExNd8Xc4=", - "gasUsed": "20828", - "success": true, - "vmStatus": "Executed successfully", - "accumulatorRootHash": "r0BvAf6NW1uSynvnXHCoLI4NEIwbtfGifrZ3246X6lQ=", - "changes": [ - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838", - "stateKeyHash": "aAmhjO7ZOImINOiEUZ/O9E+t2P3yHIM4r8WhApN87Ns=", - "type": { - "address": "0x3", - "module": "token", - "name": "TokenStore" - }, - "typeStr": "0x3::token::TokenStore", - "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"7\"}}},\"deposit_events\":{\"counter\":\"8882\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"5\"}}},\"direct_transfer\":false,\"mutate_token_property_events\":{\"counter\":\"4441\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"8\"}}},\"tokens\":{\"handle\":\"0xa18985171700c1f43182fd5b63a389b960b72ccae13aedd6cda384f566a45857\"},\"withdraw_events\":{\"counter\":\"8882\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"6\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838", - "stateKeyHash": "Xje+VRCKryCJ5bUZLsYSyRBNVyz22fidfih9glQjqL8=", - "type": { - "address": "0x3", - "module": "token", - "name": "Collections" - }, - "typeStr": "0x3::token::Collections", - "data": "{\"collection_data\":{\"handle\":\"0x5a608d04222bd2de8c9fe6ddc7bc277c390cbc87bdf2688fcdb513b34179fe69\"},\"create_collection_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"2\"}}},\"create_token_data_events\":{\"counter\":\"4410\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"3\"}}},\"mint_token_events\":{\"counter\":\"4441\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"4\"}}},\"token_data\":{\"handle\":\"0x7c579e47a2ca935a7d06f90736a0be7a46d31467a190d453e6be308f7b8ced87\"}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0", - "stateKeyHash": "an17fkHWckbHy8TUFh1URbcl0SNTryKFffSmn7563QE=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"5993209100\"},\"deposit_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"4\",\"guid\":{\"id\":{\"addr\":\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0", - "stateKeyHash": "/bIKvNhHfAGWrfiD6pC7bump6G4x8jX0sgscHB/CFik=", - "type": { - "address": "0x1", - "module": "account", - "name": "Account" - }, - "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"8\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"5\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0", - "stateKeyHash": "pJhea7RID/AkgwGn6VIFjUlURQ+MyNyW51Tqzc1aE70=", - "type": { - "address": "0x3", - "module": "token", - "name": "TokenStore" - }, - "typeStr": "0x3::token::TokenStore", - "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\",\"creation_num\":\"6\"}}},\"deposit_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\",\"creation_num\":\"4\"}}},\"direct_transfer\":true,\"mutate_token_property_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\",\"creation_num\":\"7\"}}},\"tokens\":{\"handle\":\"0xd8215d9cac0244c0e4ff5603e42e4b6e1ad92a69fd5ea23a73f0fff79208109f\"},\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\",\"creation_num\":\"5\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x78ee3915e67ef5d19fa91d1e05e60ae08751efd12ce58e23fc1109de87ea7865", - "stateKeyHash": "joMl1nETFJgKkA1huR4txIHsW1DwfGc1ZQouuEfF62I=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"12339045941500\"},\"deposit_events\":{\"counter\":\"4031\",\"guid\":{\"id\":{\"addr\":\"0x78ee3915e67ef5d19fa91d1e05e60ae08751efd12ce58e23fc1109de87ea7865\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x78ee3915e67ef5d19fa91d1e05e60ae08751efd12ce58e23fc1109de87ea7865\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "stateKeyHash": "PRT+heWBbgyc4UmVjGbYj1woWhI9Kq+dsxI5F7l9Q1Y=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "RegisterNameEventsV1" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::RegisterNameEventsV1", - "data": "{\"register_name_events\":{\"counter\":\"4441\",\"guid\":{\"id\":{\"addr\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"creation_num\":\"5\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "stateKeyHash": "q4Wci+JMAePdRidB+XcB9eieDZ0/LA5Awh7i8qY+ekI=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetNameAddressEventsV1" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetNameAddressEventsV1", - "data": "{\"set_name_events\":{\"counter\":\"4098\",\"guid\":{\"id\":{\"addr\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"creation_num\":\"4\"}}}}" - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", - "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", - "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", - "data": { - "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", - "keyType": "address", - "value": "\"100097405859481624\"", - "valueType": "u128" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "bdas1Z4+JOgy7ljZDkuChhPwjAiyc8iY1VCtEFczqZY=", - "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", - "key": "0x0003302d30", - "data": { - "key": "{\"domain_name\":\"0-0\",\"subdomain_name\":{\"vec\":[]}}", - "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1", - "value": "{\"expiration_time_sec\":\"1697697427\",\"property_version\":\"1\",\"target_address\":{\"vec\":[\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\"]}}", - "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordV1" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "HZFE4QhcrZIPummP1ZzfyzurQ55jpPwV5lPxduC8m9Q=", - "handle": "0x7c579e47a2ca935a7d06f90736a0be7a46d31467a190d453e6be308f7b8ced87", - "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d657320563107302d302e617074", - "data": { - "key": "{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}", - "keyType": "0x3::token::TokenDataId", - "value": "{\"default_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x139b4f6300000000\"}}]}},\"description\":\"This is an official Aptos Labs Name Service Name\",\"largest_property_version\":\"1\",\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"0-0.apt\",\"royalty\":{\"payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\"},\"supply\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/0-0.apt\"}", - "valueType": "0x3::token::TokenData" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "z+S79df6MqBal/Dx1K9eG4X1l4OOOrBElRSXO7IpOuQ=", - "handle": "0xd8215d9cac0244c0e4ff5603e42e4b6e1ad92a69fd5ea23a73f0fff79208109f", - "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d657320563107302d302e6170740100000000000000", - "data": { - "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}}", - "keyType": "0x3::token::TokenId", - "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x139b4f6300000000\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x93ce306500000000\"}}]}}}", - "valueType": "0x3::token::Token" - } - } - } - ] - }, - "epoch": "79", - "blockHeight": "1181280", - "type": "TRANSACTION_TYPE_USER", - "sizeInfo": { - "transactionBytes": 312, - "eventSizeInfo": [ - { - "typeTagBytes": 53, - "totalBytes": 109 - }, - { - "typeTagBytes": 52, - "totalBytes": 108 - }, - { - "typeTagBytes": 61, - "totalBytes": 408 - }, - { - "typeTagBytes": 53, - "totalBytes": 172 - }, - { - "typeTagBytes": 55, - "totalBytes": 166 - }, - { - "typeTagBytes": 54, - "totalBytes": 173 - }, - { - "typeTagBytes": 53, - "totalBytes": 172 - }, - { - "typeTagBytes": 68, - "totalBytes": 311 - }, - { - "typeTagBytes": 54, - "totalBytes": 173 - }, - { - "typeTagBytes": 53, - "totalBytes": 172 - }, - { - "typeTagBytes": 62, - "totalBytes": 139 - }, - { - "typeTagBytes": 64, - "totalBytes": 166 - } - ], - "writeOpSizeInfo": [ - { - "keyBytes": 85, - "valueBytes": 225 - }, - { - "keyBytes": 86, - "valueBytes": 208 - }, - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 147 - }, - { - "keyBytes": 85, - "valueBytes": 225 - }, - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 97, - "valueBytes": 48 - }, - { - "keyBytes": 99, - "valueBytes": 48 - }, - { - "keyBytes": 66, - "valueBytes": 16 - }, - { - "keyBytes": 39, - "valueBytes": 49 - }, - { - "keyBytes": 89, - "valueBytes": 258 - }, - { - "keyBytes": 97, - "valueBytes": 169 - } - ] - }, - "user": { - "request": { - "sender": "0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0", - "sequenceNumber": "4", - "maxGasAmount": "41400", - "gasUnitPrice": "100", - "expirationTimestampSecs": { - "seconds": "1666161448" - }, - "payload": { - "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", - "entryFunctionPayload": { - "function": { - "module": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "name": "domains" - }, - "name": "register_domain_with_signature" - }, - "arguments": [ - "\"0-0\"", - "1", - "\"0x4094d6e92f6f53cbe829353ca96ecdaa334c0a301a911bb009df25cb96b5bb7f4455e6b28bc664f71c59be65fbca96b4249f4c4a107e422fabc79128f3b43303\"" - ], - "entryFunctionIdStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::register_domain_with_signature" - } - }, - "signature": { - "type": "TYPE_ED25519", - "ed25519": { - "publicKey": "+N/0xb5NCczpimSEkojEKnNBeJ5pIwgHrn15g5MCEYo=", - "signature": "5BMukOKbRB2lf1ooHnt8DuVNSLtC7DnHajLVg2wNtFleUvr5VPWTDutjC/NkDxr60b7gM9uE49bYzdGIk/xPAg==" - } - } - }, - "events": [ - { - "key": { - "creationNumber": "3", - "accountAddress": "0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0" - }, - "sequenceNumber": "3", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "coin", - "name": "WithdrawEvent" - } - }, - "typeStr": "0x1::coin::WithdrawEvent", - "data": "{\"amount\":\"8000000000\"}" - }, - { - "key": { - "creationNumber": "2", - "accountAddress": "0x78ee3915e67ef5d19fa91d1e05e60ae08751efd12ce58e23fc1109de87ea7865" - }, - "sequenceNumber": "4030", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "coin", - "name": "DepositEvent" - } - }, - "typeStr": "0x1::coin::DepositEvent", - "data": "{\"amount\":\"8000000000\"}" - }, - { - "key": { - "creationNumber": "3", - "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" - }, - "sequenceNumber": "4409", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "CreateTokenDataEvent" - } - }, - "typeStr": "0x3::token::CreateTokenDataEvent", - "data": "{\"description\":\"This is an official Aptos Labs Name Service Name\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"},\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"0-0.apt\",\"property_keys\":[\"creation_time_sec\",\"type\"],\"property_types\":[\"u64\",\"0x1::string::String\"],\"property_values\":[\"0x139b4f6300000000\",\"0x06646f6d61696e\"],\"royalty_payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/0-0.apt\"}" - }, - { - "key": { - "creationNumber": "5", - "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" - }, - "sequenceNumber": "8880", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "DepositEvent" - } - }, - "typeStr": "0x3::token::DepositEvent", - "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}}}" - }, - { - "key": { - "creationNumber": "4", - "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" - }, - "sequenceNumber": "4440", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "MintTokenEvent" - } - }, - "typeStr": "0x3::token::MintTokenEvent", - "data": "{\"amount\":\"1\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}}" - }, - { - "key": { - "creationNumber": "6", - "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" - }, - "sequenceNumber": "8880", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "WithdrawEvent" - } - }, - "typeStr": "0x3::token::WithdrawEvent", - "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}}}" - }, - { - "key": { - "creationNumber": "5", - "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" - }, - "sequenceNumber": "8881", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "DepositEvent" - } - }, - "typeStr": "0x3::token::DepositEvent", - "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}}}" - }, - { - "key": { - "creationNumber": "8", - "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" - }, - "sequenceNumber": "4440", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "MutateTokenPropertyMapEvent" - } - }, - "typeStr": "0x3::token::MutateTokenPropertyMapEvent", - "data": "{\"keys\":[\"type\",\"expiration_time_sec\"],\"new_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}},\"old_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}},\"types\":[\"0x1::string::String\",\"u64\"],\"values\":[\"0x06646f6d61696e\",\"0x93ce306500000000\"]}" - }, - { - "key": { - "creationNumber": "6", - "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" - }, - "sequenceNumber": "8881", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "WithdrawEvent" - } - }, - "typeStr": "0x3::token::WithdrawEvent", - "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}}}" - }, - { - "key": { - "creationNumber": "4", - "accountAddress": "0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0" - }, - "sequenceNumber": "2", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "DepositEvent" - } - }, - "typeStr": "0x3::token::DepositEvent", - "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"0-0.apt\"}}}" - }, - { - "key": { - "creationNumber": "5", - "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" - }, - "sequenceNumber": "4440", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "RegisterNameEventV1" - } - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::RegisterNameEventV1", - "data": "{\"domain_name\":\"0-0\",\"expiration_time_secs\":\"1697697427\",\"property_version\":\"1\",\"registration_fee_octas\":\"8000000000\",\"subdomain_name\":{\"vec\":[]}}" - }, - { - "key": { - "creationNumber": "4", - "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" - }, - "sequenceNumber": "4097", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetNameAddressEventV1" - } - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetNameAddressEventV1", - "data": "{\"domain_name\":\"0-0\",\"expiration_time_secs\":\"1697697427\",\"new_address\":{\"vec\":[\"0x36e993c5c2a55c82915ef398d844dd62be64cb42d69ec4f80000cbb09919add0\"]},\"property_version\":\"1\",\"subdomain_name\":{\"vec\":[]}}" - } - ] - } -} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/275584410_ans_current_ans_primary_name.json b/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/275584410_ans_current_ans_primary_name.json deleted file mode 100644 index 0054a1d61122c..0000000000000 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/275584410_ans_current_ans_primary_name.json +++ /dev/null @@ -1,585 +0,0 @@ -{ - "timestamp": { - "seconds": "1695703114", - "nanos": 96497000 - }, - "version": "275584410", - "info": { - "hash": "+mmrVMSQ9L27K7ZlV9qzbtkwFiDCvXhrmQ2dRvBbQNo=", - "stateChangeHash": "5tdECPOBVViDQQTJAoWydx+aE5v2aEzhYdIuUHlTBw8=", - "eventRootHash": "5Kn0s0GnOHCgtylGNIKFSz43831sUZ4Prc+VIRYkrV8=", - "gasUsed": "2294", - "success": true, - "vmStatus": "Executed successfully", - "accumulatorRootHash": "5kU5bt+UzgV//IdVOyHqMT/jZ1Q1obA3iRdGuIaPK9w=", - "changes": [ - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7", - "stateKeyHash": "ElYWhd7mWJX0G2l59welX0CPQ4QHGhXEuBLYF56w8ck=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"1254960046535\"},\"deposit_events\":{\"counter\":\"11\",\"guid\":{\"id\":{\"addr\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7", - "stateKeyHash": "vV/ALCsC43g7v8DGhs8OiSaZhYg41Uzd+/LdVcRatqM=", - "type": { - "address": "0x1", - "module": "account", - "name": "Account" - }, - "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0x000000007c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"8\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"28\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7", - "stateKeyHash": "Sj6cYOU7wveH2XwuPBKI1rPYHRN5xRdQfnZZnnwTMlw=", - "type": { - "address": "0x3", - "module": "token", - "name": "TokenStore" - }, - "typeStr": "0x3::token::TokenStore", - "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"creation_num\":\"6\"}}},\"deposit_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"creation_num\":\"4\"}}},\"direct_transfer\":true,\"mutate_token_property_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"creation_num\":\"7\"}}},\"tokens\":{\"handle\":\"0x1c03e426986f58abcd452520ade9e325948f5bd068f9292f0c705d78cf249a0e\"},\"withdraw_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"creation_num\":\"5\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7", - "stateKeyHash": "o5IBy6uNRmyLGrMXkT4mX6fN3NiMR348RmmH7IkHYq0=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "v2_1_domains", - "name": "ReverseRecord" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::v2_1_domains::ReverseRecord", - "data": "{\"token_addr\":{\"vec\":[\"0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20\"]}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df", - "stateKeyHash": "ov6i4wX5Z/3XfMmokikYDOT1v9dAzedpOFklzOtE+sk=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "v2_1_domains", - "name": "RegisterNameEvents" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::v2_1_domains::RegisterNameEvents", - "data": "{\"register_name_events\":{\"counter\":\"256\",\"guid\":{\"id\":{\"addr\":\"0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df\",\"creation_num\":\"5\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df", - "stateKeyHash": "ov6i4wX5Z/3XfMmokikYDOT1v9dAzedpOFklzOtE+sk=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "v2_1_domains", - "name": "RenewNameEvents" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::v2_1_domains::RenewNameEvents", - "data": "{\"renew_name_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df\",\"creation_num\":\"6\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df", - "stateKeyHash": "ov6i4wX5Z/3XfMmokikYDOT1v9dAzedpOFklzOtE+sk=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "v2_1_domains", - "name": "SetReverseLookupEvents" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::v2_1_domains::SetReverseLookupEvents", - "data": "{\"set_reverse_lookup_events\":{\"counter\":\"91\",\"guid\":{\"id\":{\"addr\":\"0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df\",\"creation_num\":\"7\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df", - "stateKeyHash": "ov6i4wX5Z/3XfMmokikYDOT1v9dAzedpOFklzOtE+sk=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "v2_1_domains", - "name": "SetTargetAddressEvents" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::v2_1_domains::SetTargetAddressEvents", - "data": "{\"set_name_events\":{\"counter\":\"284\",\"guid\":{\"id\":{\"addr\":\"0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df\",\"creation_num\":\"4\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746", - "stateKeyHash": "QPEAlSWynglsidGkzbP//4VitcvhIrKurAUO0+StkfM=", - "type": { - "address": "0x1", - "module": "object", - "name": "ObjectCore" - }, - "typeStr": "0x1::object::ObjectCore", - "data": "{\"allow_ungated_transfer\":false,\"guid_creation_num\":\"1125899906842628\",\"owner\":\"0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df\",\"transfer_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746\",\"creation_num\":\"1125899906842624\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746", - "stateKeyHash": "QPEAlSWynglsidGkzbP//4VitcvhIrKurAUO0+StkfM=", - "type": { - "address": "0x4", - "module": "collection", - "name": "Collection" - }, - "typeStr": "0x4::collection::Collection", - "data": "{\"creator\":\"0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df\",\"description\":\".apt names from Aptos Labs\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746\",\"creation_num\":\"1125899906842627\"}}},\"name\":\"Aptos Domain Names V2\",\"uri\":\"https://aptosnames.com\"}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746", - "stateKeyHash": "QPEAlSWynglsidGkzbP//4VitcvhIrKurAUO0+StkfM=", - "type": { - "address": "0x4", - "module": "collection", - "name": "UnlimitedSupply" - }, - "typeStr": "0x4::collection::UnlimitedSupply", - "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746\",\"creation_num\":\"1125899906842625\"}}},\"current_supply\":\"242\",\"mint_events\":{\"counter\":\"242\",\"guid\":{\"id\":{\"addr\":\"0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746\",\"creation_num\":\"1125899906842626\"}}},\"total_minted\":\"242\"}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x673edba0e0b864ca3eb458fdd45d55f6eced59bb5bdc3b1f3671fae0f9ea4e4d", - "stateKeyHash": "V4Isr6llE556kr41rw6XFKYVvLfzm8d5JDjusnlyunY=", - "type": { - "address": "0x3", - "module": "token", - "name": "TokenStore" - }, - "typeStr": "0x3::token::TokenStore", - "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x673edba0e0b864ca3eb458fdd45d55f6eced59bb5bdc3b1f3671fae0f9ea4e4d\",\"creation_num\":\"4\"}}},\"deposit_events\":{\"counter\":\"227\",\"guid\":{\"id\":{\"addr\":\"0x673edba0e0b864ca3eb458fdd45d55f6eced59bb5bdc3b1f3671fae0f9ea4e4d\",\"creation_num\":\"2\"}}},\"direct_transfer\":false,\"mutate_token_property_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x673edba0e0b864ca3eb458fdd45d55f6eced59bb5bdc3b1f3671fae0f9ea4e4d\",\"creation_num\":\"5\"}}},\"tokens\":{\"handle\":\"0x9fdd179360735701130d02f5573569a8cdfdc2612b038ec188c8f5aaa6b7634c\"},\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x673edba0e0b864ca3eb458fdd45d55f6eced59bb5bdc3b1f3671fae0f9ea4e4d\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "stateKeyHash": "sj36uNjBXWXJieS4t0ZKkDQhUIgNqjO2LgqDnUtIyhQ=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetReverseLookupEventsV1" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetReverseLookupEventsV1", - "data": "{\"set_reverse_lookup_events\":{\"counter\":\"109530\",\"guid\":{\"id\":{\"addr\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"creation_num\":\"6\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20", - "stateKeyHash": "dpyEnMXIxzrGQBey7wiHCOvXSHlnqu8O673oXjLWgn8=", - "type": { - "address": "0x1", - "module": "object", - "name": "ObjectCore" - }, - "typeStr": "0x1::object::ObjectCore", - "data": "{\"allow_ungated_transfer\":true,\"guid_creation_num\":\"1125899906842626\",\"owner\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"transfer_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20\",\"creation_num\":\"1125899906842624\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20", - "stateKeyHash": "dpyEnMXIxzrGQBey7wiHCOvXSHlnqu8O673oXjLWgn8=", - "type": { - "address": "0x4", - "module": "token", - "name": "Token" - }, - "typeStr": "0x4::token::Token", - "data": "{\"collection\":{\"inner\":\"0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746\"},\"description\":\"This is an official Aptos Labs Name Service Name\",\"index\":\"242\",\"mutation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20\",\"creation_num\":\"1125899906842625\"}}},\"name\":\"guguru.apt\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v2/metadata/guguru.apt\"}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20", - "stateKeyHash": "dM2PYrnDkidDJRIJjPeycroAAIv5chBIX04LrHQLK/U=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "v2_1_domains", - "name": "NameRecord" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::v2_1_domains::NameRecord", - "data": "{\"domain_name\":\"guguru\",\"expiration_time_sec\":\"1729186406\",\"extend_ref\":{\"self\":\"0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20\"},\"registration_time_sec\":\"1695703114\",\"target_address\":{\"vec\":[\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\"]},\"transfer_ref\":{\"self\":\"0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20\"}}" - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", - "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", - "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", - "data": { - "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", - "keyType": "address", - "value": "\"105701978080613442\"", - "valueType": "u128" - } - } - }, - { - "type": "TYPE_DELETE_TABLE_ITEM", - "deleteTableItem": { - "stateKeyHash": "UeRK+0B6CKMee7hBbpVBofwydQ+jSJ/XrIGSlWEjL0s=", - "handle": "0x1c03e426986f58abcd452520ade9e325948f5bd068f9292f0c705d78cf249a0e", - "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d65732056310a6775677572752e6170740100000000000000", - "data": { - "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"guguru.apt\"}}", - "keyType": "0x3::token::TokenId" - } - } - }, - { - "type": "TYPE_DELETE_TABLE_ITEM", - "deleteTableItem": { - "stateKeyHash": "tWVOaCQxoh+QkVwGvguMFsjzNotZ7d/GFwHf1K3xRFw=", - "handle": "0x1d5f57aa505a2fa463b7a46341913b65757e3177c46a5e483a29d953627bee62", - "key": "0x000000007c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7", - "data": { - "key": "\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\"", - "keyType": "address" - } - } - }, - { - "type": "TYPE_DELETE_TABLE_ITEM", - "deleteTableItem": { - "stateKeyHash": "mUDN4RaEm96EbRa6svMdjlF/BzrH4lUSkqFEyYdQgxc=", - "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", - "key": "0x0006677567757275", - "data": { - "key": "{\"domain_name\":\"guguru\",\"subdomain_name\":{\"vec\":[]}}", - "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "C1lkr/sBxiAlQ6W9JkR1NId5dJq7khMGF1uU5ERxMwQ=", - "handle": "0x9fdd179360735701130d02f5573569a8cdfdc2612b038ec188c8f5aaa6b7634c", - "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d65732056310a6775677572752e6170740100000000000000", - "data": { - "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"guguru.apt\"}}", - "keyType": "0x3::token::TokenId", - "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"guguru.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x66e34e6300000000\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0xe616306500000000\"}}]}}}", - "valueType": "0x3::token::Token" - } - } - } - ] - }, - "epoch": "4191", - "blockHeight": "96498487", - "type": "TRANSACTION_TYPE_USER", - "sizeInfo": { - "transactionBytes": 234, - "eventSizeInfo": [ - { - "typeTagBytes": 54, - "totalBytes": 176 - }, - { - "typeTagBytes": 53, - "totalBytes": 175 - }, - { - "typeTagBytes": 55, - "totalBytes": 143 - }, - { - "typeTagBytes": 55, - "totalBytes": 199 - }, - { - "typeTagBytes": 65, - "totalBytes": 137 - }, - { - "typeTagBytes": 69, - "totalBytes": 166 - }, - { - "typeTagBytes": 69, - "totalBytes": 170 - }, - { - "typeTagBytes": 66, - "totalBytes": 123 - } - ], - "writeOpSizeInfo": [ - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 147 - }, - { - "keyBytes": 85, - "valueBytes": 225 - }, - { - "keyBytes": 95, - "valueBytes": 33 - }, - { - "keyBytes": 93, - "valueBytes": 462 - }, - { - "keyBytes": 87, - "valueBytes": 524 - }, - { - "keyBytes": 85, - "valueBytes": 225 - }, - { - "keyBytes": 101, - "valueBytes": 48 - }, - { - "keyBytes": 87, - "valueBytes": 399 - }, - { - "keyBytes": 93, - "valueBytes": 179 - }, - { - "keyBytes": 66, - "valueBytes": 16 - }, - { - "keyBytes": 100 - }, - { - "keyBytes": 66 - }, - { - "keyBytes": 42 - }, - { - "keyBytes": 100, - "valueBytes": 172 - } - ] - }, - "user": { - "request": { - "sender": "0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7", - "sequenceNumber": "27", - "maxGasAmount": "4586", - "gasUnitPrice": "100", - "expirationTimestampSecs": { - "seconds": "1695703203" - }, - "payload": { - "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", - "entryFunctionPayload": { - "function": { - "module": { - "address": "0xf50e0bb52c52bd66b5f542f867418c63181f6d9eaa869008525beb553d97fb7d", - "name": "bulk" - }, - "name": "bulk_migrate_domain" - }, - "arguments": [ - "[\"guguru\"]" - ], - "entryFunctionIdStr": "0xf50e0bb52c52bd66b5f542f867418c63181f6d9eaa869008525beb553d97fb7d::bulk::bulk_migrate_domain" - } - }, - "signature": { - "type": "TYPE_ED25519", - "ed25519": { - "publicKey": "E+D1P34LLxW7NeYnHQ0OwYg/t/y1nDUExI4vokKG1zc=", - "signature": "uEd/o0JOneju6bBbKCAnqQzUBEhawiOhdwyUhAc/At/A7nI2p2kGSp0LMclnLxo9qRzmXo3WlW4Z11PhaRqMCA==" - } - } - }, - "events": [ - { - "key": { - "creationNumber": "5", - "accountAddress": "0x000000007c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7" - }, - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "WithdrawEvent" - } - }, - "typeStr": "0x3::token::WithdrawEvent", - "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"guguru.apt\"}}}" - }, - { - "key": { - "creationNumber": "2", - "accountAddress": "0x673edba0e0b864ca3eb458fdd45d55f6eced59bb5bdc3b1f3671fae0f9ea4e4d" - }, - "sequenceNumber": "226", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "DepositEvent" - } - }, - "typeStr": "0x3::token::DepositEvent", - "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"guguru.apt\"}}}" - }, - { - "key": { - "creationNumber": "1125899906842626", - "accountAddress": "0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746" - }, - "sequenceNumber": "241", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x4", - "module": "collection", - "name": "MintEvent" - } - }, - "typeStr": "0x4::collection::MintEvent", - "data": "{\"index\":\"242\",\"token\":\"0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20\"}" - }, - { - "key": { - "creationNumber": "1125899906842624", - "accountAddress": "0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20" - }, - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "object", - "name": "TransferEvent" - } - }, - "typeStr": "0x1::object::TransferEvent", - "data": "{\"from\":\"0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df\",\"object\":\"0xf04d6f00aa820b0662de65df585879539497c1f79718193d99db2de3d7cecd20\",\"to\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\"}" - }, - { - "key": { - "creationNumber": "5", - "accountAddress": "0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df" - }, - "sequenceNumber": "255", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "v2_1_domains", - "name": "RegisterNameEvent" - } - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::v2_1_domains::RegisterNameEvent", - "data": "{\"domain_name\":\"guguru\",\"expiration_time_secs\":\"1729186406\",\"registration_fee_octas\":\"0\",\"subdomain_name\":{\"vec\":[]}}" - }, - { - "key": { - "creationNumber": "4", - "accountAddress": "0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df" - }, - "sequenceNumber": "283", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "v2_1_domains", - "name": "SetTargetAddressEvent" - } - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::v2_1_domains::SetTargetAddressEvent", - "data": "{\"domain_name\":\"guguru\",\"expiration_time_secs\":\"1729186406\",\"new_address\":{\"vec\":[\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\"]},\"subdomain_name\":{\"vec\":[]}}" - }, - { - "key": { - "creationNumber": "7", - "accountAddress": "0x14464c04472a91941854ba9ffc48691e071874a1bcb51b89ff15afa5f80b76df" - }, - "sequenceNumber": "90", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "v2_1_domains", - "name": "SetReverseLookupEvent" - } - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::v2_1_domains::SetReverseLookupEvent", - "data": "{\"account_addr\":\"0x7c9f6724cfc3ead36713389148bbeb48a310dacd43a767b52ada4be7\",\"curr_domain_name\":{\"vec\":[\"guguru\"]},\"curr_expiration_time_secs\":{\"vec\":[\"1729186406\"]},\"curr_subdomain_name\":{\"vec\":[]},\"prev_domain_name\":{\"vec\":[]},\"prev_expiration_time_secs\":{\"vec\":[]},\"prev_subdomain_name\":{\"vec\":[]}}" - }, - { - "key": { - "creationNumber": "6", - "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" - }, - "sequenceNumber": "109529", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetReverseLookupEventV1" - } - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetReverseLookupEventV1", - "data": "{\"domain_name\":\"guguru\",\"subdomain_name\":{\"vec\":[]},\"target_address\":{\"vec\":[]}}" - } - ] - } -} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/83883373_stake_withdraw.json b/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/83883373_stake_withdraw.json deleted file mode 100644 index 39b88336fbfaa..0000000000000 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/83883373_stake_withdraw.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "timestamp": { - "seconds": "1675841492", - "nanos": 180341000 - }, - "version": "83883373", - "info": { - "hash": "Tm0WqmZvVdIKwuqPUquDMz5ZgAIDFaeTEKMVFXOUJE0=", - "stateChangeHash": "k9gaFUHlhY5SKbrpGadJS/v575btDhin1wwNVMZOZQI=", - "eventRootHash": "6l5rKId+YiU4Mg9CSO+Sc4qxsodFDUkyIknbl2il0SU=", - "gasUsed": "2298", - "success": true, - "vmStatus": "Executed successfully", - "accumulatorRootHash": "MUvnZ1h21Nr/fiKdpuz/ZXGtA2dZQiuEJzTgokD5xSE=", - "changes": [ - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a", - "stateKeyHash": "pyEfDaMVlxRCufn897ABaYR4MSr1qyrWibBuPQDCtFk=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"10509767\"},\"deposit_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a", - "stateKeyHash": "iuh3YqK9vk+YhHEciWmSlVeFF/LaJSEqTMF8TOoaxmg=", - "type": { - "address": "0x1", - "module": "stake", - "name": "StakePool" - }, - "typeStr": "0x1::stake::StakePool", - "data": "{\"active\":{\"value\":\"0\"},\"add_stake_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"6\"}}},\"delegated_voter\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"distribute_rewards_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"12\"}}},\"inactive\":{\"value\":\"0\"},\"increase_lockup_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"10\"}}},\"initialize_validator_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"4\"}}},\"join_validator_set_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"11\"}}},\"leave_validator_set_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"15\"}}},\"locked_until_secs\":\"0\",\"operator_address\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"pending_active\":{\"value\":\"0\"},\"pending_inactive\":{\"value\":\"0\"},\"reactivate_stake_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"7\"}}},\"rotate_consensus_key_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"8\"}}},\"set_operator_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"5\"}}},\"unlock_stake_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"13\"}}},\"update_network_and_fullnode_addresses_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"9\"}}},\"withdraw_stake_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"14\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a", - "stateKeyHash": "6N3NF5uMdLTkUL55cWs/RDFlmYrbFYzNVnSM6fJ7TSM=", - "type": { - "address": "0x1", - "module": "account", - "name": "Account" - }, - "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"16\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"4\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", - "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", - "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", - "data": { - "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", - "keyType": "address", - "value": "\"101879261462066764\"", - "valueType": "u128" - } - } - } - ] - }, - "epoch": "1423", - "blockHeight": "31382696", - "type": "TRANSACTION_TYPE_USER", - "sizeInfo": { - "transactionBytes": 224, - "eventSizeInfo": [ - { - "typeTagBytes": 59, - "totalBytes": 147 - }, - { - "typeTagBytes": 52, - "totalBytes": 108 - } - ], - "writeOpSizeInfo": [ - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 680 - }, - { - "keyBytes": 84, - "valueBytes": 147 - }, - { - "keyBytes": 66, - "valueBytes": 16 - } - ] - }, - "user": { - "request": { - "sender": "0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a", - "sequenceNumber": "3", - "maxGasAmount": "3234", - "gasUnitPrice": "133", - "expirationTimestampSecs": { - "seconds": "1675843278" - }, - "payload": { - "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", - "entryFunctionPayload": { - "function": { - "module": { - "address": "0x1", - "name": "stake" - }, - "name": "withdraw" - }, - "arguments": [ - "\"10000000\"" - ], - "entryFunctionIdStr": "0x1::stake::withdraw" - } - }, - "signature": { - "type": "TYPE_ED25519", - "ed25519": { - "publicKey": "2SW62O6FdPqnup3jHt/Ho7n6ZvjaSOdXJDpWtlL0tmg=", - "signature": "g41Asc/doVVpdvZtzmjv950movxtC+l14wXtSd19CzIug884qOh6nxSAA+28NnRNi4SHjvW4Vm3C72Fl0oJBDA==" - } - } - }, - "events": [ - { - "key": { - "creationNumber": "14", - "accountAddress": "0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a" - }, - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "stake", - "name": "WithdrawStakeEvent" - } - }, - "typeStr": "0x1::stake::WithdrawStakeEvent", - "data": "{\"amount_withdrawn\":\"10000000\",\"pool_address\":\"0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a\"}" - }, - { - "key": { - "creationNumber": "2", - "accountAddress": "0xb7ad608a12c20efa02482aaa783ee4986fd5510e8ca678307534469b2c28297a" - }, - "sequenceNumber": "2", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "coin", - "name": "DepositEvent" - } - }, - "typeStr": "0x1::coin::DepositEvent", - "data": "{\"amount\":\"10000000\"}" - } - ] - } -} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/92331132_ans_primary_name.json b/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/92331132_ans_primary_name.json deleted file mode 100644 index c5566021dcb4d..0000000000000 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/92331132_ans_primary_name.json +++ /dev/null @@ -1,299 +0,0 @@ -{ - "timestamp": { - "seconds": "1677175225", - "nanos": 161699000 - }, - "version": "92331132", - "info": { - "hash": "3p526hoyFmd7YbjuXcNApB896m672foseZNwimfAM9M=", - "stateChangeHash": "DpL14PHgQZbvM6nnj9YiF9MsWs7x6Z1tDYQooeuEMCY=", - "eventRootHash": "oR5nxMGuUX8BHf6ZIzZRJLip4FjIHYX09LCPx3NhCDg=", - "gasUsed": "6403", - "success": true, - "vmStatus": "Executed successfully", - "accumulatorRootHash": "rL7vMUua78UuyYREnHB6jvchYse2pV7mQb5yg7C9Wmc=", - "changes": [ - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "stateKeyHash": "q4Wci+JMAePdRidB+XcB9eieDZ0/LA5Awh7i8qY+ekI=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetNameAddressEventsV1" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetNameAddressEventsV1", - "data": "{\"set_name_events\":{\"counter\":\"30007\",\"guid\":{\"id\":{\"addr\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"creation_num\":\"4\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "stateKeyHash": "sj36uNjBXWXJieS4t0ZKkDQhUIgNqjO2LgqDnUtIyhQ=", - "type": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetReverseLookupEventsV1" - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetReverseLookupEventsV1", - "data": "{\"set_reverse_lookup_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"creation_num\":\"6\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41", - "stateKeyHash": "Av40LJkn6KV7YPRIi6Fg8pkgRK0n5X1vHk/USouVVOQ=", - "type": { - "address": "0x1", - "module": "coin", - "name": "CoinStore", - "genericTypeParams": [ - { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x1", - "module": "aptos_coin", - "name": "AptosCoin" - } - } - ] - }, - "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"6043294736\"},\"deposit_events\":{\"counter\":\"9\",\"guid\":{\"id\":{\"addr\":\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"16\",\"guid\":{\"id\":{\"addr\":\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\",\"creation_num\":\"3\"}}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41", - "stateKeyHash": "32re4D0TTgpA4b7Ob7z3JRje3NhS6eVzY0ay6WxkwBg=", - "type": { - "address": "0x1", - "module": "account", - "name": "Account" - }, - "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"9\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"21\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" - } - }, - { - "type": "TYPE_WRITE_RESOURCE", - "writeResource": { - "address": "0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41", - "stateKeyHash": "+mB27IuoeoRSdFxGTKzw4Mx1AW9Shx+LlTBHEepyDvc=", - "type": { - "address": "0x3", - "module": "token", - "name": "TokenStore" - }, - "typeStr": "0x3::token::TokenStore", - "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\",\"creation_num\":\"6\"}}},\"deposit_events\":{\"counter\":\"16\",\"guid\":{\"id\":{\"addr\":\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\",\"creation_num\":\"4\"}}},\"direct_transfer\":true,\"mutate_token_property_events\":{\"counter\":\"5\",\"guid\":{\"id\":{\"addr\":\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\",\"creation_num\":\"7\"}}},\"tokens\":{\"handle\":\"0x4f59fbe8917d06d223836156a314a62ee5cb83a553eefab08e302bfbb870ccae\"},\"withdraw_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\",\"creation_num\":\"5\"}}}}" - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", - "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", - "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", - "data": { - "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", - "keyType": "address", - "value": "\"102128958197159981\"", - "valueType": "u128" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "8m5IP6/LL5vVjOFhkTQ0IBueD9L4+poC+AUwn/qvb+0=", - "handle": "0x1d5f57aa505a2fa463b7a46341913b65757e3177c46a5e483a29d953627bee62", - "key": "0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41", - "data": { - "key": "\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\"", - "keyType": "address", - "value": "{\"domain_name\":\"zihanxx\",\"subdomain_name\":{\"vec\":[]}}", - "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "OnrZk0xT062935mUf9hCMpw92AuZsYZzd5dVsJLmH3E=", - "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", - "key": "0x00077a6968616e7878", - "data": { - "key": "{\"domain_name\":\"zihanxx\",\"subdomain_name\":{\"vec\":[]}}", - "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1", - "value": "{\"expiration_time_sec\":\"1697761575\",\"property_version\":\"1\",\"target_address\":{\"vec\":[\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\"]}}", - "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordV1" - } - } - }, - { - "type": "TYPE_WRITE_TABLE_ITEM", - "writeTableItem": { - "stateKeyHash": "cxoSQyEnDhrvr5dB+ndWCshmt6uuMNIKlaRoGyUj7HA=", - "handle": "0x4f59fbe8917d06d223836156a314a62ee5cb83a553eefab08e302bfbb870ccae", - "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d65732056310b7a6968616e78782e6170740100000000000000", - "data": { - "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"zihanxx.apt\"}}", - "keyType": "0x3::token::TokenId", - "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"zihanxx.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0xa795506300000000\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x27c9316500000000\"}}]}}}", - "valueType": "0x3::token::Token" - } - } - } - ] - }, - "epoch": "1609", - "blockHeight": "34965221", - "type": "TRANSACTION_TYPE_USER", - "sizeInfo": { - "transactionBytes": 244, - "eventSizeInfo": [ - { - "typeTagBytes": 64, - "totalBytes": 170 - }, - { - "typeTagBytes": 68, - "totalBytes": 319 - }, - { - "typeTagBytes": 66, - "totalBytes": 156 - } - ], - "writeOpSizeInfo": [ - { - "keyBytes": 99, - "valueBytes": 48 - }, - { - "keyBytes": 101, - "valueBytes": 48 - }, - { - "keyBytes": 138, - "valueBytes": 105 - }, - { - "keyBytes": 84, - "valueBytes": 147 - }, - { - "keyBytes": 85, - "valueBytes": 225 - }, - { - "keyBytes": 66, - "valueBytes": 16 - }, - { - "keyBytes": 66, - "valueBytes": 9 - }, - { - "keyBytes": 43, - "valueBytes": 49 - }, - { - "keyBytes": 101, - "valueBytes": 173 - } - ] - }, - "user": { - "request": { - "sender": "0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41", - "sequenceNumber": "20", - "maxGasAmount": "12746", - "gasUnitPrice": "100", - "expirationTimestampSecs": { - "seconds": "1677175284" - }, - "payload": { - "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", - "entryFunctionPayload": { - "function": { - "module": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "name": "domains" - }, - "name": "set_reverse_lookup_entry" - }, - "arguments": [ - "\"\"", - "\"zihanxx\"" - ], - "entryFunctionIdStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::set_reverse_lookup_entry" - } - }, - "signature": { - "type": "TYPE_ED25519", - "ed25519": { - "publicKey": "FUI0dtsKyBysZGUPHrEEhF7frRD1nsb8BypG5/PUam0=", - "signature": "jwFHdEa4IaRWNfWpgAiMV0SHW4b3nn0Ffkmxk/1sXblpb2yhbydokCK/0YD/gecDRpi3e/+VsvCOUQRPoYH6Bw==" - } - } - }, - "events": [ - { - "key": { - "creationNumber": "4", - "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" - }, - "sequenceNumber": "30006", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetNameAddressEventV1" - } - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetNameAddressEventV1", - "data": "{\"domain_name\":\"zihanxx\",\"expiration_time_secs\":\"1697761575\",\"new_address\":{\"vec\":[\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\"]},\"property_version\":\"1\",\"subdomain_name\":{\"vec\":[]}}" - }, - { - "key": { - "creationNumber": "7", - "accountAddress": "0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41" - }, - "sequenceNumber": "4", - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x3", - "module": "token", - "name": "MutateTokenPropertyMapEvent" - } - }, - "typeStr": "0x3::token::MutateTokenPropertyMapEvent", - "data": "{\"keys\":[\"type\",\"expiration_time_sec\"],\"new_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"zihanxx.apt\"}},\"old_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"zihanxx.apt\"}},\"types\":[\"0x1::string::String\",\"u64\"],\"values\":[\"0x06646f6d61696e\",\"0x27c9316500000000\"]}" - }, - { - "key": { - "creationNumber": "6", - "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" - }, - "type": { - "type": "MOVE_TYPES_STRUCT", - "struct": { - "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", - "module": "domains", - "name": "SetReverseLookupEventV1" - } - }, - "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::SetReverseLookupEventV1", - "data": "{\"domain_name\":\"zihanxx\",\"subdomain_name\":{\"vec\":[]},\"target_address\":{\"vec\":[\"0xa86a4f2516626b2538c2dbc9d4bc19d93d19c86fe14e5b4517937b18f7535d41\"]}}" - } - ] - } -} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/generated_transactions.rs b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/generated_transactions.rs new file mode 100644 index 0000000000000..3a912bafad1ad --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/generated_transactions.rs @@ -0,0 +1,436 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 +#![allow(dead_code)] +#![allow(unused_variables)] + +pub const IMPORTED_MAINNET_TXNS_121508544_STAKE_DISTRIBUTE: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/121508544_stake_distribute.json" +)); + +pub const IMPORTED_MAINNET_TXNS_590098441_USER_TXN_SINGLE_SENDER_ED25519: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/590098441_user_txn_single_sender_ed25519.json")); + +pub const IMPORTED_MAINNET_TXNS_145959468_ACCOUNT_TRANSACTION: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/145959468_account_transaction.json" +)); + +pub const IMPORTED_MAINNET_TXNS_2175935_USER_TXN_MULTI_ED25519: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2175935_user_txn_multi_ed25519.json" +)); + +pub const IMPORTED_MAINNET_TXNS_2200077877_ACCOUNT_RESTORATION_ROTATED_TO_SINGLE_SECP256K1: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2200077877_account_restoration_rotated_to_single_secp256k1.json")); + +pub const IMPORTED_MAINNET_TXNS_1831971037_STAKE_DELEGATION_POOL: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/1831971037_stake_delegation_pool.json" +)); + +pub const IMPORTED_MAINNET_TXNS_527013476_USER_TXN_SINGLE_SENDER_SECP256K1_ECDSA: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/527013476_user_txn_single_sender_secp256k1_ecdsa.json")); + +pub const IMPORTED_MAINNET_TXNS_118489_PROPOSAL_VOTE: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/118489_proposal_vote.json" +)); + +pub const IMPORTED_MAINNET_TXNS_1058723093_TOKEN_V1_MINT_WITHDRAW_DEPOSIT_EVENTS: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/1058723093_token_v1_mint_withdraw_deposit_events.json")); + +pub const IMPORTED_MAINNET_TXNS_1845035942_DEFAULT_CURRENT_TABLE_ITEMS: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/1845035942_default_current_table_items.json" + )); + +pub const IMPORTED_MAINNET_TXNS_125600867_STAKE_DELEGATION_POOL: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/125600867_stake_delegation_pool.json" +)); + +pub const IMPORTED_MAINNET_TXNS_513424821_DEFAULT_BLOCK_METADATA_TRANSACTIONS: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/513424821_default_block_metadata_transactions.json")); + +pub const IMPORTED_MAINNET_TXNS_103958588_MULTI_AGENTS: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/103958588_multi_agents.json" +)); + +pub const IMPORTED_MAINNET_TXNS_999929475_COIN_AND_FA_TRANSFERS: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/999929475_coin_and_fa_transfers.json" +)); + +pub const IMPORTED_MAINNET_TXNS_11648867_TOKEN_V1_BURN_EVENT: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/11648867_token_v1_burn_event.json" +)); + +pub const IMPORTED_MAINNET_TXNS_1056780409_ANS_CURRENT_ANS_PRIMARY_NAME_V2: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/1056780409_ans_current_ans_primary_name_v2.json")); + +pub const IMPORTED_MAINNET_TXNS_2200077591_ACCOUNT_RESTORATION_SINGLE_ED25519: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2200077591_account_restoration_single_ed25519.json")); + +pub const IMPORTED_MAINNET_TXNS_2212040150_TRANSACTION_WITHOUT_EVENTS: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2212040150_transaction_without_events.json" + )); + +pub const IMPORTED_MAINNET_TXNS_464961735_USER_TXN_SINGLE_KEY_ED25519: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/464961735_user_txn_single_key_ed25519.json" + )); + +pub const IMPORTED_MAINNET_TXNS_438536688_ANS_CURRENT_ANS_LOOKUP_V2: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/438536688_ans_current_ans_lookup_v2.json" + )); + +pub const IMPORTED_MAINNET_TXNS_578318306_OBJECTS_WRITE_RESOURCE: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/578318306_objects_write_resource.json" +)); + +pub const IMPORTED_MAINNET_TXNS_999930475_TOKEN_V2_CONCURRENT_MINT: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/999930475_token_v2_concurrent_mint.json" + )); + +pub const IMPORTED_MAINNET_TXNS_124094774_DELEGATED_POOL_BALANCE: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/124094774_delegated_pool_balance.json" +)); + +pub const IMPORTED_MAINNET_TXNS_97963136_TOKEN_V2_CANCEL_OFFER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/97963136_token_v2_cancel_offer.json" +)); + +pub const IMPORTED_MAINNET_TXNS_152449628_COIN_INFO_WRITE: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/152449628_coin_info_write.json" +)); + +pub const IMPORTED_MAINNET_TXNS_602320562_TOKEN_V2_APTOS_TOKEN_MINT: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/602320562_token_v2_aptos_token_mint.json" + )); + +pub const IMPORTED_MAINNET_TXNS_1830706009_STAKER_GOVERNANCE_RECORD: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/1830706009_staker_governance_record.json" + )); + +pub const IMPORTED_MAINNET_TXNS_423176063_ACCOUNT_TRANSACTION_DELETE: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/423176063_account_transaction_delete.json" + )); + +pub const IMPORTED_MAINNET_TXNS_303690531_ANS_LOOKUP_V2: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/303690531_ans_lookup_v2.json" +)); + +pub const IMPORTED_MAINNET_TXNS_2200077800_ACCOUNT_RESTORATION_ROTATED_TO_MULTI_KEY: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/2200077800_account_restoration_rotated_to_multi_key.json")); + +pub const IMPORTED_MAINNET_TXNS_1803170308_USER_TXN_MULTI_KEY_KEYLESS: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/1803170308_user_txn_multi_key_keyless.json" + )); + +pub const IMPORTED_MAINNET_TXNS_508365567_FA_V1_EVENTS: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/508365567_fa_v1_events.json" +)); + +pub const IMPORTED_MAINNET_TXNS_1806220919_OBJECT_UNTRANSFERABLE: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/1806220919_object_untransferable.json" +)); + +pub const IMPORTED_MAINNET_TXNS_578366445_TOKEN_V2_BURN_EVENT_V2: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/578366445_token_v2_burn_event_v2.json" +)); + +pub const IMPORTED_MAINNET_TXNS_325355235_TOKEN_V2_UNLIMITED_SUPPLY_MINT: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/325355235_token_v2_unlimited_supply_mint.json")); + +pub const IMPORTED_MAINNET_TXNS_551057865_USER_TXN_SINGLE_SENDER_WEBAUTH: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/551057865_user_txn_single_sender_webauth.json")); + +pub const IMPORTED_MAINNET_TXNS_84023785_TOKEN_V2_CLAIM_OFFER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/84023785_token_v2_claim_offer.json" +)); + +pub const IMPORTED_MAINNET_TXNS_141135867_TOKEN_V1_OFFER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/141135867_token_v1_offer.json" +)); + +pub const IMPORTED_MAINNET_TXNS_976087151_USER_TXN_SINGLE_SENDER_KEYLESS: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/976087151_user_txn_single_sender_keyless.json")); + +pub const IMPORTED_MAINNET_TXNS_2080538_ANS_LOOKUP_V1: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/2080538_ans_lookup_v1.json" +)); + +pub const IMPORTED_MAINNET_TXNS_139449359_STAKE_REACTIVATE: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/139449359_stake_reactivate.json" +)); + +pub const IMPORTED_MAINNET_TXNS_308783012_FA_TRANSFER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/308783012_fa_transfer.json" +)); + +pub const IMPORTED_MAINNET_TXNS_453498957_TOKEN_V2_MINT_AND_TRANSFER_EVENT_V1: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/453498957_token_v2_mint_and_transfer_event_v1.json")); + +pub const IMPORTED_MAINNET_TXNS_1080786089_TOKEN_V2_BURN_EVENT_V1: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/1080786089_token_v2_burn_event_v1.json" +)); + +pub const IMPORTED_MAINNET_TXNS_967255533_TOKEN_V2_MUTATION_EVENT: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/967255533_token_v2_mutation_event.json" +)); + +pub const IMPORTED_MAINNET_TXNS_407418623_USER_TXN_SINGLE_KEY_SECP256K1_ECDSA: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_mainnet_txns/407418623_user_txn_single_key_secp256k1_ecdsa.json")); + +pub const IMPORTED_MAINNET_TXNS_537250181_TOKEN_V2_FIXED_SUPPLY_MINT: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/537250181_token_v2_fixed_supply_mint.json" + )); + +pub const IMPORTED_MAINNET_TXNS_4827964_STAKE_INITIALIZE: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/4827964_stake_initialize.json" +)); + +pub const IMPORTED_MAINNET_TXNS_155112189_DEFAULT_TABLE_ITEMS: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/155112189_default_table_items.json" +)); + +pub const IMPORTED_MAINNET_TXNS_178179220_TOKEN_V1_MUTATE_EVENT: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/178179220_token_v1_mutate_event.json" +)); + +pub const IMPORTED_MAINNET_TXNS_685_USER_TXN_ED25519: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_mainnet_txns/685_user_txn_ed25519.json" +)); +pub const ALL_IMPORTED_MAINNET_TXNS: &[&[u8]] = &[ + IMPORTED_MAINNET_TXNS_121508544_STAKE_DISTRIBUTE, + IMPORTED_MAINNET_TXNS_590098441_USER_TXN_SINGLE_SENDER_ED25519, + IMPORTED_MAINNET_TXNS_145959468_ACCOUNT_TRANSACTION, + IMPORTED_MAINNET_TXNS_2175935_USER_TXN_MULTI_ED25519, + IMPORTED_MAINNET_TXNS_2200077877_ACCOUNT_RESTORATION_ROTATED_TO_SINGLE_SECP256K1, + IMPORTED_MAINNET_TXNS_1831971037_STAKE_DELEGATION_POOL, + IMPORTED_MAINNET_TXNS_527013476_USER_TXN_SINGLE_SENDER_SECP256K1_ECDSA, + IMPORTED_MAINNET_TXNS_118489_PROPOSAL_VOTE, + IMPORTED_MAINNET_TXNS_1058723093_TOKEN_V1_MINT_WITHDRAW_DEPOSIT_EVENTS, + IMPORTED_MAINNET_TXNS_1845035942_DEFAULT_CURRENT_TABLE_ITEMS, + IMPORTED_MAINNET_TXNS_125600867_STAKE_DELEGATION_POOL, + IMPORTED_MAINNET_TXNS_513424821_DEFAULT_BLOCK_METADATA_TRANSACTIONS, + IMPORTED_MAINNET_TXNS_103958588_MULTI_AGENTS, + IMPORTED_MAINNET_TXNS_999929475_COIN_AND_FA_TRANSFERS, + IMPORTED_MAINNET_TXNS_11648867_TOKEN_V1_BURN_EVENT, + IMPORTED_MAINNET_TXNS_1056780409_ANS_CURRENT_ANS_PRIMARY_NAME_V2, + IMPORTED_MAINNET_TXNS_2200077591_ACCOUNT_RESTORATION_SINGLE_ED25519, + IMPORTED_MAINNET_TXNS_2212040150_TRANSACTION_WITHOUT_EVENTS, + IMPORTED_MAINNET_TXNS_464961735_USER_TXN_SINGLE_KEY_ED25519, + IMPORTED_MAINNET_TXNS_438536688_ANS_CURRENT_ANS_LOOKUP_V2, + IMPORTED_MAINNET_TXNS_578318306_OBJECTS_WRITE_RESOURCE, + IMPORTED_MAINNET_TXNS_999930475_TOKEN_V2_CONCURRENT_MINT, + IMPORTED_MAINNET_TXNS_124094774_DELEGATED_POOL_BALANCE, + IMPORTED_MAINNET_TXNS_97963136_TOKEN_V2_CANCEL_OFFER, + IMPORTED_MAINNET_TXNS_152449628_COIN_INFO_WRITE, + IMPORTED_MAINNET_TXNS_602320562_TOKEN_V2_APTOS_TOKEN_MINT, + IMPORTED_MAINNET_TXNS_1830706009_STAKER_GOVERNANCE_RECORD, + IMPORTED_MAINNET_TXNS_423176063_ACCOUNT_TRANSACTION_DELETE, + IMPORTED_MAINNET_TXNS_303690531_ANS_LOOKUP_V2, + IMPORTED_MAINNET_TXNS_2200077800_ACCOUNT_RESTORATION_ROTATED_TO_MULTI_KEY, + IMPORTED_MAINNET_TXNS_1803170308_USER_TXN_MULTI_KEY_KEYLESS, + IMPORTED_MAINNET_TXNS_508365567_FA_V1_EVENTS, + IMPORTED_MAINNET_TXNS_1806220919_OBJECT_UNTRANSFERABLE, + IMPORTED_MAINNET_TXNS_578366445_TOKEN_V2_BURN_EVENT_V2, + IMPORTED_MAINNET_TXNS_325355235_TOKEN_V2_UNLIMITED_SUPPLY_MINT, + IMPORTED_MAINNET_TXNS_551057865_USER_TXN_SINGLE_SENDER_WEBAUTH, + IMPORTED_MAINNET_TXNS_84023785_TOKEN_V2_CLAIM_OFFER, + IMPORTED_MAINNET_TXNS_141135867_TOKEN_V1_OFFER, + IMPORTED_MAINNET_TXNS_976087151_USER_TXN_SINGLE_SENDER_KEYLESS, + IMPORTED_MAINNET_TXNS_2080538_ANS_LOOKUP_V1, + IMPORTED_MAINNET_TXNS_139449359_STAKE_REACTIVATE, + IMPORTED_MAINNET_TXNS_308783012_FA_TRANSFER, + IMPORTED_MAINNET_TXNS_453498957_TOKEN_V2_MINT_AND_TRANSFER_EVENT_V1, + IMPORTED_MAINNET_TXNS_1080786089_TOKEN_V2_BURN_EVENT_V1, + IMPORTED_MAINNET_TXNS_967255533_TOKEN_V2_MUTATION_EVENT, + IMPORTED_MAINNET_TXNS_407418623_USER_TXN_SINGLE_KEY_SECP256K1_ECDSA, + IMPORTED_MAINNET_TXNS_537250181_TOKEN_V2_FIXED_SUPPLY_MINT, + IMPORTED_MAINNET_TXNS_4827964_STAKE_INITIALIZE, + IMPORTED_MAINNET_TXNS_155112189_DEFAULT_TABLE_ITEMS, + IMPORTED_MAINNET_TXNS_178179220_TOKEN_V1_MUTATE_EVENT, + IMPORTED_MAINNET_TXNS_685_USER_TXN_ED25519, +]; + +pub const IMPORTED_TESTNET_TXNS_5979639459_COIN_REGISTER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/5979639459_coin_register.json" +)); + +pub const IMPORTED_TESTNET_TXNS_1255836496_V2_FA_METADATA_: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/1255836496_v2_fa_metadata_.json" +)); + +pub const IMPORTED_TESTNET_TXNS_646928741_NO_EVENTS: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/646928741_no_events.json" +)); + +pub const IMPORTED_TESTNET_TXNS_5992795934_FA_ACTIVITIES: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/5992795934_fa_activities.json" +)); + +pub const IMPORTED_TESTNET_TXNS_4462417704_SECONDARY_STORE_BURNT: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/4462417704_secondary_store_burnt.json" +)); + +pub const IMPORTED_TESTNET_TXNS_2646510387_CONCURRENT_FA: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/2646510387_concurrent_fa.json" +)); + +pub const IMPORTED_TESTNET_TXNS_3_EMPTY_TXN: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/3_empty_txn.json" +)); + +pub const IMPORTED_TESTNET_TXNS_278556781_V1_COIN_REGISTER_FA_METADATA: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/278556781_v1_coin_register_fa_metadata.json" + )); + +pub const IMPORTED_TESTNET_TXNS_5523474016_VALIDATOR_TXN: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/5523474016_validator_txn.json" +)); + +pub const IMPORTED_TESTNET_TXNS_2_NEW_BLOCK_EVENT: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/2_new_block_event.json" +)); + +pub const IMPORTED_TESTNET_TXNS_1_GENESIS: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/1_genesis.json" +)); + +pub const IMPORTED_TESTNET_TXNS_769222973_MULTISIG: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/769222973_multisig.json" +)); + +pub const IMPORTED_TESTNET_TXNS_1200394037_FA_V2_FROZEN_EVENT: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_testnet_txns/1200394037_fa_v2_frozen_event.json" +)); +pub const ALL_IMPORTED_TESTNET_TXNS: &[&[u8]] = &[ + IMPORTED_TESTNET_TXNS_5979639459_COIN_REGISTER, + IMPORTED_TESTNET_TXNS_1255836496_V2_FA_METADATA_, + IMPORTED_TESTNET_TXNS_646928741_NO_EVENTS, + IMPORTED_TESTNET_TXNS_5992795934_FA_ACTIVITIES, + IMPORTED_TESTNET_TXNS_4462417704_SECONDARY_STORE_BURNT, + IMPORTED_TESTNET_TXNS_2646510387_CONCURRENT_FA, + IMPORTED_TESTNET_TXNS_3_EMPTY_TXN, + IMPORTED_TESTNET_TXNS_278556781_V1_COIN_REGISTER_FA_METADATA, + IMPORTED_TESTNET_TXNS_5523474016_VALIDATOR_TXN, + IMPORTED_TESTNET_TXNS_2_NEW_BLOCK_EVENT, + IMPORTED_TESTNET_TXNS_1_GENESIS, + IMPORTED_TESTNET_TXNS_769222973_MULTISIG, + IMPORTED_TESTNET_TXNS_1200394037_FA_V2_FROZEN_EVENT, +]; + +pub const IMPORTED_DEVNET_TXNS_19922017_TOKEN_V1_OFFER_CLAIM: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_devnet_txns/19922017_token_v1_offer_claim.json" +)); + +pub const IMPORTED_DEVNET_TXNS_78753811_COIN_TRANSFER_WITH_V2_EVENTS: &[u8] = + include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/imported_devnet_txns/78753811_coin_transfer_with_v2_events.json" + )); + +pub const IMPORTED_DEVNET_TXNS_78753832_TOKEN_V2_MINT_TRANSFER_WITH_V2_EVENTS: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_devnet_txns/78753832_token_v2_mint_transfer_with_v2_events.json")); + +pub const IMPORTED_DEVNET_TXNS_78753831_TOKEN_V1_MINT_TRANSFER_WITH_V2_EVENTS: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/imported_devnet_txns/78753831_token_v1_mint_transfer_with_v2_events.json")); +pub const ALL_IMPORTED_DEVNET_TXNS: &[&[u8]] = &[ + IMPORTED_DEVNET_TXNS_19922017_TOKEN_V1_OFFER_CLAIM, + IMPORTED_DEVNET_TXNS_78753811_COIN_TRANSFER_WITH_V2_EVENTS, + IMPORTED_DEVNET_TXNS_78753832_TOKEN_V2_MINT_TRANSFER_WITH_V2_EVENTS, + IMPORTED_DEVNET_TXNS_78753831_TOKEN_V1_MINT_TRANSFER_WITH_V2_EVENTS, +]; + +pub const SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT4: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/scripted_transactions/simple_user_script4.json" +)); + +pub const SCRIPTED_TRANSACTIONS_FA_DOUBLE_TRANSFER: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/scripted_transactions/fa_double_transfer.json" +)); + +pub const SCRIPTED_TRANSACTIONS_FA_MINT_TRANSFER_BURN: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/scripted_transactions/fa_mint_transfer_burn.json" +)); + +pub const SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT2: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/scripted_transactions/simple_user_script2.json" +)); + +pub const SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT3: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/scripted_transactions/simple_user_script3.json" +)); + +pub const SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT1: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/json_transactions/scripted_transactions/simple_user_script1.json" +)); +pub const ALL_SCRIPTED_TRANSACTIONS: &[&[u8]] = &[ + SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT4, + SCRIPTED_TRANSACTIONS_FA_DOUBLE_TRANSFER, + SCRIPTED_TRANSACTIONS_FA_MINT_TRANSFER_BURN, + SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT2, + SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT3, + SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT1, +]; + +pub fn get_transaction_name(const_data: &[u8]) -> Option<&'static str> { + match const_data { + SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT4 => Some("simple_user_script4"), + SCRIPTED_TRANSACTIONS_FA_DOUBLE_TRANSFER => Some("fa_double_transfer"), + SCRIPTED_TRANSACTIONS_FA_MINT_TRANSFER_BURN => Some("fa_mint_transfer_burn"), + SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT2 => Some("simple_user_script2"), + SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT3 => Some("simple_user_script3"), + SCRIPTED_TRANSACTIONS_SIMPLE_USER_SCRIPT1 => Some("simple_user_script1"), + + _ => None, + } +} diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_devnet_txns/19922017_token_v1_offer_claim.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_devnet_txns/19922017_token_v1_offer_claim.json new file mode 100644 index 0000000000000..8b42c8268dd10 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_devnet_txns/19922017_token_v1_offer_claim.json @@ -0,0 +1,239 @@ +{ + "timestamp": { + "seconds": "1732838021", + "nanos": 291148000 + }, + "version": "19922017", + "info": { + "hash": "aKpZ+nqLpSG3dZ0ihl+hZDlN+DZT94VNuEF63ZsKaqg=", + "stateChangeHash": "+Q3vQHg8B3NwUA0EWAQJ6W9odtdr2znblhA5LGvk+J4=", + "eventRootHash": "TPhosvNZBaZD7yIXEYjKedcoSeHZTlRrcfL/r9NbSt8=", + "gasUsed": "1003", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "pMAO0JbiH97+YmZlukux4VQ5JTxnlgGH8sStITIN0pE=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a", + "stateKeyHash": "3PKNnyclqWa+n2dhFjJL16nOtwEXWHvSmm6QjATiOZc=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"99948060\"},\"deposit_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a", + "stateKeyHash": "9kRa2muVQOxLQ89dLRlZqunw8dAmtdrM9O12kK/+aWQ=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"coin_register_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"8\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a", + "stateKeyHash": "x3MhI8Zmr7ypCLYqYtKa7OV46nDR/OY2a/7/7uJUt2c=", + "type": { + "address": "0x3", + "module": "token", + "name": "TokenStore" + }, + "typeStr": "0x3::token::TokenStore", + "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"creation_num\":\"6\"}}},\"deposit_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"creation_num\":\"4\"}}},\"direct_transfer\":false,\"mutate_token_property_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"creation_num\":\"7\"}}},\"tokens\":{\"handle\":\"0xa5e6f84af35d356027c1513b37248bae3968c20720af6fc2d5c58b7c90ffda55\"},\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"creation_num\":\"5\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"18447247123872670479\"", + "valueType": "u128" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "/YnW9dam+wishtjQGgep+A8/XjIc7AQ0FcCCoC4cTCA=", + "handle": "0xa5e6f84af35d356027c1513b37248bae3968c20720af6fc2d5c58b7c90ffda55", + "key": "0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e07416c696365277313416c696365277320666972737420746f6b656e0000000000000000", + "data": { + "key": "{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Alice's\",\"creator\":\"0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e\",\"name\":\"Alice's first token\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Alice's\",\"creator\":\"0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e\",\"name\":\"Alice's first token\"}},\"token_properties\":{\"map\":{\"data\":[]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_DELETE_TABLE_ITEM", + "deleteTableItem": { + "stateKeyHash": "QqPmMOTnJ0I4/NPvmLPmOryr0zn7u6A4RXqtuwuaGiI=", + "handle": "0xc4b3a532f522e5cc021427b4d729938073a6d34949bd397490d4bbf96a4703f1", + "key": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99ad77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e07416c696365277313416c696365277320666972737420746f6b656e0000000000000000", + "data": { + "key": "{\"to_addr\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"token_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Alice's\",\"creator\":\"0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e\",\"name\":\"Alice's first token\"}}}", + "keyType": "0x3::token_transfers::TokenOfferId" + } + } + } + ] + }, + "epoch": "17", + "blockHeight": "2463154", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 334, + "eventSizeInfo": [ + { + "typeTagBytes": 53, + "totalBytes": 161 + }, + { + "typeTagBytes": 56, + "totalBytes": 196 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 85, + "valueBytes": 225 + }, + { + "keyBytes": 66, + "valueBytes": 16 + }, + { + "keyBytes": 102, + "valueBytes": 77 + }, + { + "keyBytes": 134 + } + ] + }, + "user": { + "request": { + "sender": "0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a", + "maxGasAmount": "200000", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1732838041" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x3", + "name": "token_transfers" + }, + "name": "claim_script" + }, + "arguments": [ + "\"0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e\"", + "\"0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e\"", + "\"Alice's\"", + "\"Alice's first token\"", + "\"0\"" + ], + "entryFunctionIdStr": "0x3::token_transfers::claim_script" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "jzbjRIJ61M2u3gFc3NSYGbERPM0ilJmYWS6bifc3Hag=", + "signature": "GuA0SWD+oWzlbJ+b4s92V/t2p32CqxkqPQUjDKGq04j7wnXKngio7YOVAK/3sAQchXjuKtJ2xK8v8thuf5dUBA==" + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "TokenDeposit" + } + }, + "typeStr": "0x3::token::TokenDeposit", + "data": "{\"account\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Alice's\",\"creator\":\"0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e\",\"name\":\"Alice's first token\"}}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token_transfers", + "name": "Claim" + } + }, + "typeStr": "0x3::token_transfers::Claim", + "data": "{\"account\":\"0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e\",\"amount\":\"1\",\"to_address\":\"0xe2ebcbacd81584f97b6ba9a458239ea083428d75158c0d42ef38b6379527e99a\",\"token_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Alice's\",\"creator\":\"0xd77942ad91c35a2d165fdec8f6a28ec48b6bb9f905db2fd0ac8a7e481a9c543e\",\"name\":\"Alice's first token\"}}}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"5\",\"io_gas_units\":\"4\",\"storage_fee_octas\":\"99400\",\"storage_fee_refund_octas\":\"48360\",\"total_charge_gas_units\":\"1003\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_devnet_txns/78753811_coin_transfer_with_v2_events.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_devnet_txns/78753811_coin_transfer_with_v2_events.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_devnet_txns/78753811_coin_transfer_with_v2_events.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_devnet_txns/78753811_coin_transfer_with_v2_events.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_devnet_txns/78753831_token_v1_mint_transfer_with_v2_events.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_devnet_txns/78753831_token_v1_mint_transfer_with_v2_events.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_devnet_txns/78753831_token_v1_mint_transfer_with_v2_events.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_devnet_txns/78753831_token_v1_mint_transfer_with_v2_events.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_devnet_txns/78753832_token_v2_mint_transfer_with_v2_events.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_devnet_txns/78753832_token_v2_mint_transfer_with_v2_events.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_devnet_txns/78753832_token_v2_mint_transfer_with_v2_events.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_devnet_txns/78753832_token_v2_mint_transfer_with_v2_events.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/103958588_multi_agents.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/103958588_multi_agents.json new file mode 100644 index 0000000000000..062ea5885e93e --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/103958588_multi_agents.json @@ -0,0 +1,242 @@ +{ + "timestamp": { + "seconds": "1679156666", + "nanos": 242260000 + }, + "version": "103958588", + "info": { + "hash": "zRZisYjmPQmK/cgRi0lgCbh94lbMWwBzSlWgulvHUXE=", + "stateChangeHash": "Jv7xmCx7njwxAcIGBYT9GNvCsQLOxCv+DFDX40KD/O0=", + "eventRootHash": "WBj2eLwtoSMY8gkFNoUJrTeCfOYpgxVp8ZY4fsAsNi4=", + "gasUsed": "996", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "7nnqtU001FC6xYzyv5rRQeiN1dvsjKWbgBzoKQ2QVo8=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x214e588b8a8260a97420bf729c0d06d9691f3a1bab65b65f65e61227004505c1", + "stateKeyHash": "mDQFtJmfsWEztOhVyvHw6WiUdn+PJ7w/31JFk2oMjl4=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xfbab9fb68bd2103925317b6a540baa20087b1e7a7a4eb90badee04abb6b5a16f", + "module": "blt", + "name": "Blt" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0xfbab9fb68bd2103925317b6a540baa20087b1e7a7a4eb90badee04abb6b5a16f::blt::Blt>", + "data": "{\"coin\":{\"value\":\"0\"},\"deposit_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x214e588b8a8260a97420bf729c0d06d9691f3a1bab65b65f65e61227004505c1\",\"creation_num\":\"4\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x214e588b8a8260a97420bf729c0d06d9691f3a1bab65b65f65e61227004505c1\",\"creation_num\":\"5\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x214e588b8a8260a97420bf729c0d06d9691f3a1bab65b65f65e61227004505c1", + "stateKeyHash": "hM4il8rmTBhgpm8bRBe+amOBpOzoY8pp0+MC+WhNJV8=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x214e588b8a8260a97420bf729c0d06d9691f3a1bab65b65f65e61227004505c1\",\"coin_register_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x214e588b8a8260a97420bf729c0d06d9691f3a1bab65b65f65e61227004505c1\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"6\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x214e588b8a8260a97420bf729c0d06d9691f3a1bab65b65f65e61227004505c1\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"0\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x66e46c568a91a9ff082dd5eb39920c6e451415ef17301457bd771b3bfd056971", + "stateKeyHash": "aYq41wULwlXL0jqEPM2JyoLa96c+Mf0fE6+FLr9GrR8=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"11657700\"},\"deposit_events\":{\"counter\":\"12\",\"guid\":{\"id\":{\"addr\":\"0x66e46c568a91a9ff082dd5eb39920c6e451415ef17301457bd771b3bfd056971\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"72\",\"guid\":{\"id\":{\"addr\":\"0x66e46c568a91a9ff082dd5eb39920c6e451415ef17301457bd771b3bfd056971\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x66e46c568a91a9ff082dd5eb39920c6e451415ef17301457bd771b3bfd056971", + "stateKeyHash": "dI+ssr7akla6uj7fgJI4HC5RpsleZKdlnGzSUHXCFx4=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x66e46c568a91a9ff082dd5eb39920c6e451415ef17301457bd771b3bfd056971\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x66e46c568a91a9ff082dd5eb39920c6e451415ef17301457bd771b3bfd056971\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x66e46c568a91a9ff082dd5eb39920c6e451415ef17301457bd771b3bfd056971\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"206\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"102500662852386424\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "1885", + "blockHeight": "40088443", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 623, + "eventSizeInfo": [ + { + "typeTagBytes": 60, + "totalBytes": 148 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 125, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x66e46c568a91a9ff082dd5eb39920c6e451415ef17301457bd771b3bfd056971", + "sequenceNumber": "205", + "maxGasAmount": "50000", + "gasUnitPrice": "101", + "expirationTimestampSecs": { + "seconds": "1709078400" + }, + "payload": { + "type": "TYPE_SCRIPT_PAYLOAD", + "scriptPayload": { + "code": { + "bytecode": "oRzrCwUAAAAGAQACAwIGBAgCBQoKBxQWCCogAAAAAQMBAQAAAgIMDAABCQABBgwMbWFuYWdlZF9jb2luCHJlZ2lzdGVyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAABAw4BOAAC", + "abi": { + "name": "main", + "visibility": "VISIBILITY_PUBLIC", + "isEntry": true, + "genericTypeParams": [ + {} + ], + "params": [ + { + "type": "MOVE_TYPES_SIGNER" + }, + { + "type": "MOVE_TYPES_SIGNER" + } + ] + } + }, + "typeArguments": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0xfbab9fb68bd2103925317b6a540baa20087b1e7a7a4eb90badee04abb6b5a16f", + "module": "blt", + "name": "Blt" + } + } + ] + } + }, + "signature": { + "type": "TYPE_MULTI_AGENT", + "multiAgent": { + "sender": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "0FuLU6dy8E3l2eg5/cRSoOA0z0ye88S6ZgRpTYmdsSo=", + "signature": "5ea7EvzkyEHbr1Fg2ICLiXop7tUACbyGQhkQ2yCsDxns8UUuExopKOosMQj60W+or0Timz/ml/sIwFah4roqDA==" + } + }, + "secondarySignerAddresses": [ + "0x214e588b8a8260a97420bf729c0d06d9691f3a1bab65b65f65e61227004505c1" + ], + "secondarySigners": [ + { + "type": "TYPE_MULTI_ED25519", + "multiEd25519": { + "publicKeys": [ + "BUfR0Y8jG9loVB4CquGTBE0Gr3qMxUdj03xuQieUkLs=", + "aF/6Wxfr8csy2D3GXII8sOOKdIkqz6Wfu1VZjtsdGk4=", + "aF/6Wxfr8csy2D3GXII8sOOKdIkqz6Wfu1VZjtsdGk4=", + "Az2udl4ueEbO0pji8z3d9YoINsWasEsGmvofLKFfnW4=" + ], + "signatures": [ + "3PQIl9DjAf/E00X+9Qtt1dahkidYHSV0i4akKsSIk2NMHGxoiXgMY7ZCivwa1MXqa6Eb1INlcCNj91/qLosaBA==", + "3ENohVxIPNwiFWHSU8Bk7SFaNej3yOTSewFD9mxL62OP01shng5SoGd7e0IxYryqRy7yg02ni+owayWHJ6BqBg==" + ], + "threshold": 2, + "publicKeyIndices": [ + 0, + 3 + ] + } + } + ] + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0x214e588b8a8260a97420bf729c0d06d9691f3a1bab65b65f65e61227004505c1" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "account", + "name": "CoinRegisterEvent" + } + }, + "typeStr": "0x1::account::CoinRegisterEvent", + "data": "{\"type_info\":{\"account_address\":\"0xfbab9fb68bd2103925317b6a540baa20087b1e7a7a4eb90badee04abb6b5a16f\",\"module_name\":\"0x626c74\",\"struct_name\":\"0x426c74\"}}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1056780409_ans_current_ans_primary_name_v2.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1056780409_ans_current_ans_primary_name_v2.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1056780409_ans_current_ans_primary_name_v2.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1056780409_ans_current_ans_primary_name_v2.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1058723093_token_v1_mint_withdraw_deposit_events.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1058723093_token_v1_mint_withdraw_deposit_events.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1058723093_token_v1_mint_withdraw_deposit_events.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1058723093_token_v1_mint_withdraw_deposit_events.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1080786089_token_v2_burn_event_v1.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1080786089_token_v2_burn_event_v1.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1080786089_token_v2_burn_event_v1.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1080786089_token_v2_burn_event_v1.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/11648867_token_v1_burn_event.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/11648867_token_v1_burn_event.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/11648867_token_v1_burn_event.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/11648867_token_v1_burn_event.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/118489_proposal_vote.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/118489_proposal_vote.json new file mode 100644 index 0000000000000..f0f15948a0e5d --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/118489_proposal_vote.json @@ -0,0 +1,253 @@ +{ + "timestamp": { + "seconds": "1665639039", + "nanos": 148518000 + }, + "version": "118489", + "info": { + "hash": "28B9LfrOVBfFO1kbdP2PAF1EZVXo3iA3qgkujIOPR/A=", + "stateChangeHash": "//+uQ4msceHz9s9Cc1JT9fxIlViJp5uo687iFjqcWh4=", + "eventRootHash": "0/nHr8KW/GgUqWz2TTnsF9NhZBcL3BeMuU34plD485o=", + "gasUsed": "2723", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "8SEzHBO+xlGbB/pFPNkbfts7+NSaFeSajjy8hmat6nM=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1", + "stateKeyHash": "jc5YaAws7YpkBtMRsCOPJZr/MlhYmA4914HzpLVGovI=", + "type": { + "address": "0x1", + "module": "voting", + "name": "VotingForum", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "governance_proposal", + "name": "GovernanceProposal" + } + } + ] + }, + "typeStr": "0x1::voting::VotingForum<0x1::governance_proposal::GovernanceProposal>", + "data": "{\"events\":{\"create_proposal_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x1\",\"creation_num\":\"5\"}}},\"register_forum_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x1\",\"creation_num\":\"6\"}}},\"resolve_proposal_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1\",\"creation_num\":\"7\"}}},\"vote_events\":{\"counter\":\"13\",\"guid\":{\"id\":{\"addr\":\"0x1\",\"creation_num\":\"8\"}}}},\"next_proposal_id\":\"1\",\"proposals\":{\"handle\":\"0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1", + "stateKeyHash": "raB+wNt/rD08QNWjFd+UCckIMZFTC+6hQ/rOVU/aWU0=", + "type": { + "address": "0x1", + "module": "aptos_governance", + "name": "GovernanceEvents" + }, + "typeStr": "0x1::aptos_governance::GovernanceEvents", + "data": "{\"create_proposal_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x1\",\"creation_num\":\"9\"}}},\"update_config_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1\",\"creation_num\":\"10\"}}},\"vote_events\":{\"counter\":\"13\",\"guid\":{\"id\":{\"addr\":\"0x1\",\"creation_num\":\"11\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf8beaf5570741b3034306fea06f384d1353ec73587a51dd014456301d8a4d09f", + "stateKeyHash": "aHpCBjvp1eA0OMTmt+GsKjSuxpHeVNPis2pr3bEeFgY=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"199727700\"},\"deposit_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xf8beaf5570741b3034306fea06f384d1353ec73587a51dd014456301d8a4d09f\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xf8beaf5570741b3034306fea06f384d1353ec73587a51dd014456301d8a4d09f\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf8beaf5570741b3034306fea06f384d1353ec73587a51dd014456301d8a4d09f", + "stateKeyHash": "mgg1wrlGArR2bzvr8zXsK4UojabkuyKDLzAMOJuYoaA=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xf8beaf5570741b3034306fea06f384d1353ec73587a51dd014456301d8a4d09f\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xf8beaf5570741b3034306fea06f384d1353ec73587a51dd014456301d8a4d09f\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xf8beaf5570741b3034306fea06f384d1353ec73587a51dd014456301d8a4d09f\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"100002482545705622\"", + "valueType": "u128" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "v5mmcIVu11hftThMjjLcfo//0T4qCYGXoofr6CDhdUM=", + "handle": "0x38ff67f17cf7998cd41ed5267b52cff7af37d06a22e8b390ce44b69680fc0e97", + "key": "0x0000000000000000", + "data": { + "key": "\"0\"", + "keyType": "u64", + "value": "{\"creation_time_secs\":\"1665637092\",\"early_resolution_vote_threshold\":{\"vec\":[\"50000847671301291\"]},\"execution_content\":{\"vec\":[{\"dummy_field\":false}]},\"execution_hash\":\"0x14bbbcc8b5ecd167b4527fc6f8caee3f9a12f93e8543eabaae696bf1eedec044\",\"expiration_secs\":\"1666241892\",\"is_resolved\":false,\"metadata\":{\"data\":[{\"key\":\"metadata_hash\",\"value\":\"0x31323164623539383831643239333466306238306536366437316133383838353131646264353130376634383765303563313266336462373862303266613265\"},{\"key\":\"metadata_location\",\"value\":\"0x68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f6170746f732d6c6162732f6d61696e6e65742d70726f706f73616c732f6d61696e2f6d657461646174612f302d7265647563652d696e6372656173652d6c696d69742d746f2d31302e6a736f6e\"},{\"key\":\"RESOLVABLE_TIME_METADATA_KEY\",\"value\":\"0x7fa2476300000000\"}]},\"min_vote_threshold\":\"40000000000000000\",\"no_votes\":\"0\",\"proposer\":\"0xbc7cd15595245af1ae39d91d3cd16e024de3544c1d528d568350a13b71e23917\",\"resolution_time_secs\":\"0\",\"yes_votes\":\"13712956527832946\"}", + "valueType": "0x1::voting::Proposal<0x1::governance_proposal::GovernanceProposal>" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bl7kcjSjN1DLzeGTO+59sTkuZEI3wciIcpZsKSc8BUY=", + "handle": "0xdc3189011da6e60643ef48030b4f8fc315beddc236c6c523db96778af7b47056", + "key": "0xd60280852b50c341b22bba06562a817293d7b834eac251e7600b25d8bdd9efa30000000000000000", + "data": { + "key": "{\"proposal_id\":\"0\",\"stake_pool\":\"0xd60280852b50c341b22bba06562a817293d7b834eac251e7600b25d8bdd9efa3\"}", + "keyType": "0x1::aptos_governance::RecordKey", + "value": "true", + "valueType": "bool" + } + } + } + ] + }, + "epoch": "6", + "blockHeight": "59007", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 266, + "eventSizeInfo": [ + { + "typeTagBytes": 51, + "totalBytes": 115 + }, + { + "typeTagBytes": 61, + "totalBytes": 190 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 160, + "valueBytes": 232 + }, + { + "keyBytes": 102, + "valueBytes": 144 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + }, + { + "keyBytes": 42, + "valueBytes": 405 + }, + { + "keyBytes": 74, + "valueBytes": 1 + } + ] + }, + "user": { + "request": { + "sender": "0xf8beaf5570741b3034306fea06f384d1353ec73587a51dd014456301d8a4d09f", + "maxGasAmount": "4039", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1665639068" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x1", + "name": "aptos_governance" + }, + "name": "vote" + }, + "arguments": [ + "\"0xd60280852b50c341b22bba06562a817293d7b834eac251e7600b25d8bdd9efa3\"", + "\"0\"", + "true" + ], + "entryFunctionIdStr": "0x1::aptos_governance::vote" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "05gmffsH/FrOFCvnjN2hohk8+vnqA5GSv+Usy+t+JV8=", + "signature": "0fy2ZHB6Fs3V18EooOVOSqTb8E5JErvgWDL73hYtcOlIDcj5zKriYqVq4sd4n204sobUWwsRecg6d2nuxxZADQ==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "8", + "accountAddress": "0x1" + }, + "sequenceNumber": "12", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "voting", + "name": "VoteEvent" + } + }, + "typeStr": "0x1::voting::VoteEvent", + "data": "{\"num_votes\":\"100004794376617\",\"proposal_id\":\"0\"}" + }, + { + "key": { + "creationNumber": "11", + "accountAddress": "0x1" + }, + "sequenceNumber": "12", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_governance", + "name": "VoteEvent" + } + }, + "typeStr": "0x1::aptos_governance::VoteEvent", + "data": "{\"num_votes\":\"100004794376617\",\"proposal_id\":\"0\",\"should_pass\":true,\"stake_pool\":\"0xd60280852b50c341b22bba06562a817293d7b834eac251e7600b25d8bdd9efa3\",\"voter\":\"0xf8beaf5570741b3034306fea06f384d1353ec73587a51dd014456301d8a4d09f\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/121508544_stake_distribute.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/121508544_stake_distribute.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/121508544_stake_distribute.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/121508544_stake_distribute.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/124094774_delegated_pool_balance.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/124094774_delegated_pool_balance.json new file mode 100644 index 0000000000000..0eb789edbc087 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/124094774_delegated_pool_balance.json @@ -0,0 +1,355 @@ +{ + "timestamp": { + "seconds": "1681798647", + "nanos": 616307000 + }, + "version": "124094774", + "info": { + "hash": "KBlOmUe9mlzhCd0rw+y51GN+KpPRZEuJ61/Pfnp+CQE=", + "stateChangeHash": "GYYlzk0uDSSRQ2k9/q0zCx54TrrkKmIvd3suLKM8ESM=", + "eventRootHash": "9yOjJd7jZCQq/ucHZawzT0nVbiLF0N0GbF/S2epPH+w=", + "gasUsed": "461", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "afr4q1QEh3KaRam3X1bj7mQc0/uG6FJkWCK4kxiUjVs=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a", + "stateKeyHash": "VeAJK9P6q3yCKLTHf1ObiiuLKX4D4eeI12CVlL6KMpo=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"946815900\"},\"deposit_events\":{\"counter\":\"163\",\"guid\":{\"id\":{\"addr\":\"0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"234\",\"guid\":{\"id\":{\"addr\":\"0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a", + "stateKeyHash": "bhy836bN3Vmrh1Y6ws8p4vAd99gfpzGozu2T+RIEffw=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a\",\"coin_register_events\":{\"counter\":\"27\",\"guid\":{\"id\":{\"addr\":\"0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"64\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"618\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e", + "stateKeyHash": "m1zMzEiA39MGlIddKEkREn3Sb0UJH7Xfgom+eafwuZs=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"0\"},\"deposit_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e", + "stateKeyHash": "pJ+IFgI8eausfa+EIuI55Y2CXCjo3qlIlLNnIA7ntc0=", + "type": { + "address": "0x1", + "module": "stake", + "name": "StakePool" + }, + "typeStr": "0x1::stake::StakePool", + "data": "{\"active\":{\"value\":\"4102000000\"},\"add_stake_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"6\"}}},\"delegated_voter\":\"0xcec29699a9bf0f26a7e525a626a5d876b185f60c670a89849939da1587185d08\",\"distribute_rewards_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"12\"}}},\"inactive\":{\"value\":\"0\"},\"increase_lockup_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"10\"}}},\"initialize_validator_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"4\"}}},\"join_validator_set_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"11\"}}},\"leave_validator_set_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"15\"}}},\"locked_until_secs\":\"0\",\"operator_address\":\"0xcec29699a9bf0f26a7e525a626a5d876b185f60c670a89849939da1587185d08\",\"pending_active\":{\"value\":\"0\"},\"pending_inactive\":{\"value\":\"0\"},\"reactivate_stake_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"7\"}}},\"rotate_consensus_key_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"8\"}}},\"set_operator_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"5\"}}},\"unlock_stake_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"13\"}}},\"update_network_and_fullnode_addresses_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"9\"}}},\"withdraw_stake_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"14\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e", + "stateKeyHash": "lSgRVdnN3gVJ1UPeq5eZ8v2GgApTFhnFwIg3ViBP+7A=", + "type": { + "address": "0x1", + "module": "delegation_pool", + "name": "DelegationPool" + }, + "typeStr": "0x1::delegation_pool::DelegationPool", + "data": "{\"active_shares\":{\"scaling_factor\":\"10000000000000000\",\"shares\":{\"inner\":{\"handle\":\"0x20a562f3cce72009287a03c003fadcfc61093d3bde0054a165b3cc568b0e0b7e\"},\"length\":\"3\"},\"total_coins\":\"4102000000\",\"total_shares\":\"41020000000000000000000000\"},\"add_stake_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"16\"}}},\"distribute_commission_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"20\"}}},\"inactive_shares\":{\"handle\":\"0xcc401582c138de63fab2b47a5820c85b9eacee8c543e0daef120d94a4c7d7813\"},\"observed_lockup_cycle\":{\"index\":\"0\"},\"operator_commission_percentage\":\"1200\",\"pending_withdrawals\":{\"handle\":\"0x103338a7bf343ce3a027cc93f5a039659f92ca1dfb07488f863ec874946f7de3\"},\"reactivate_stake_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"17\"}}},\"stake_pool_signer_cap\":{\"account\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"},\"total_coins_inactive\":\"0\",\"unlock_stake_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"18\"}}},\"withdraw_stake_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\",\"creation_num\":\"19\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"102998465170159767\"", + "valueType": "u128" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "BGXQC/Llb8L/pxiUR4bjxtCU8o3yQK93m+eGI1qjmaU=", + "handle": "0x20a562f3cce72009287a03c003fadcfc61093d3bde0054a165b3cc568b0e0b7e", + "key": "0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a", + "data": { + "key": "\"0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a\"", + "keyType": "address", + "value": "\"21000000000000000000000000\"", + "valueType": "u128" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "kN5I82wub68cybmXHub7uMdgvbV98DHpHpwTog9deUg=", + "handle": "0xcc401582c138de63fab2b47a5820c85b9eacee8c543e0daef120d94a4c7d7813", + "key": "0x0000000000000000", + "data": { + "key": "{\"index\":\"0\"}", + "keyType": "0x1::delegation_pool::ObservedLockupCycle", + "value": "{\"scaling_factor\":\"10000000000000000\",\"shares\":{\"inner\":{\"handle\":\"0xb744e4bc7e64146adaae0ff1f86b2e1229265d39683d142fc80b23006ae49ac3\"},\"length\":\"0\"},\"total_coins\":\"0\",\"total_shares\":\"0\"}", + "valueType": "0x1::pool_u64_unbound::Pool" + } + } + } + ] + }, + "epoch": "2254", + "blockHeight": "48212529", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 268, + "eventSizeInfo": [ + { + "typeTagBytes": 76, + "totalBytes": 204 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 54, + "totalBytes": 142 + }, + { + "typeTagBytes": 64, + "totalBytes": 192 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 680 + }, + { + "keyBytes": 99, + "valueBytes": 432 + }, + { + "keyBytes": 66, + "valueBytes": 16 + }, + { + "keyBytes": 66, + "valueBytes": 16 + }, + { + "keyBytes": 42, + "valueBytes": 72 + } + ] + }, + "user": { + "request": { + "sender": "0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a", + "sequenceNumber": "617", + "maxGasAmount": "2000000", + "gasUnitPrice": "124", + "expirationTimestampSecs": { + "seconds": "1681798707" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x1", + "name": "delegation_pool" + }, + "name": "add_stake" + }, + "arguments": [ + "\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"", + "\"2100000000\"" + ], + "entryFunctionIdStr": "0x1::delegation_pool::add_stake" + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "22GrUTv4/K+U3x7/d2M9UVU6o/wttfpL4Veu6eKRt2c=", + "signature": "VEf0RZ1ix1a9oxSY29T21/p+J+0v/9ooL+LUeDeU6gEMa6nKd/DL25T8yehSbkDcqw+SyF1WTLzq1R+cTeHfAA==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "20", + "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "delegation_pool", + "name": "DistributeCommissionEvent" + } + }, + "typeStr": "0x1::delegation_pool::DistributeCommissionEvent", + "data": "{\"commission_active\":\"0\",\"commission_pending_inactive\":\"0\",\"operator\":\"0xcec29699a9bf0f26a7e525a626a5d876b185f60c670a89849939da1587185d08\",\"pool_address\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a" + }, + "sequenceNumber": "233", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"2100000000\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"2100000000\"}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"2100000000\"}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "stake", + "name": "AddStakeEvent" + } + }, + "typeStr": "0x1::stake::AddStakeEvent", + "data": "{\"amount_added\":\"2100000000\",\"pool_address\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"}" + }, + { + "key": { + "creationNumber": "16", + "accountAddress": "0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "delegation_pool", + "name": "AddStakeEvent" + } + }, + "typeStr": "0x1::delegation_pool::AddStakeEvent", + "data": "{\"add_stake_fee\":\"0\",\"amount_added\":\"2100000000\",\"delegator_address\":\"0x5aa16d9f590b635f8cc17ba4abf40f60c77df0078cf5296a539cfbb9e87a285a\",\"pool_address\":\"0xd081e2f4a2f162e04214acb3723f81d279e70ae67096883ee8ec353c772e2a8e\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/125600867_stake_delegation_pool.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/125600867_stake_delegation_pool.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/125600867_stake_delegation_pool.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/125600867_stake_delegation_pool.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/139449359_stake_reactivate.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/139449359_stake_reactivate.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/139449359_stake_reactivate.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/139449359_stake_reactivate.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/141135867_token_v1_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/141135867_token_v1_offer.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/141135867_token_v1_offer.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/141135867_token_v1_offer.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/145959468_account_transaction.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/145959468_account_transaction.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/145959468_account_transaction.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/145959468_account_transaction.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/152449628_coin_info_write.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/152449628_coin_info_write.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/152449628_coin_info_write.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/152449628_coin_info_write.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/155112189_default_table_items.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/155112189_default_table_items.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/155112189_default_table_items.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/155112189_default_table_items.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/178179220_token_v1_mutate_event.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/178179220_token_v1_mutate_event.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/178179220_token_v1_mutate_event.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/178179220_token_v1_mutate_event.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1803170308_user_txn_multi_key_keyless.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1803170308_user_txn_multi_key_keyless.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1803170308_user_txn_multi_key_keyless.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1803170308_user_txn_multi_key_keyless.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1806220919_object_untransferable.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1806220919_object_untransferable.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1806220919_object_untransferable.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1806220919_object_untransferable.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1830706009_staker_governance_record.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1830706009_staker_governance_record.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1830706009_staker_governance_record.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1830706009_staker_governance_record.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1831971037_stake_delegation_pool.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1831971037_stake_delegation_pool.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1831971037_stake_delegation_pool.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1831971037_stake_delegation_pool.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1845035942_default_current_table_items.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1845035942_default_current_table_items.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/1845035942_default_current_table_items.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/1845035942_default_current_table_items.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2080538_ans_lookup_v1.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2080538_ans_lookup_v1.json new file mode 100644 index 0000000000000..36d35cb9a1a77 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2080538_ans_lookup_v1.json @@ -0,0 +1,1944 @@ +{ + "timestamp": { + "seconds": "1666112072", + "nanos": 647995000 + }, + "version": "2080538", + "info": { + "hash": "9whCecMPg5iFDH4C0nJGy/uAciA59yY1h6F+Io51lrU=", + "stateChangeHash": "s0waF6SD9n/sFcnnwoHkfWmpyGP/IkSX+oFOXYCz6kQ=", + "eventRootHash": "dE/8Fc+Pe6QuJvAIExUaeT1R+aus/oVwB3o0YkSN67A=", + "gasUsed": "80438", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "bPlmcUs84FSHBRZeDPAtmLuLSv9KiQ+P1PGzpySpIjA=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838", + "stateKeyHash": "7ReW/xRy95ukhGFiMXZ2r43bnKZv5VzfGxWCcre83Ds=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"coin_register_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"9\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"0\",\"signer_capability_offer\":{\"for\":{\"vec\":[\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\"]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838", + "stateKeyHash": "aAmhjO7ZOImINOiEUZ/O9E+t2P3yHIM4r8WhApN87Ns=", + "type": { + "address": "0x3", + "module": "token", + "name": "TokenStore" + }, + "typeStr": "0x3::token::TokenStore", + "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"7\"}}},\"deposit_events\":{\"counter\":\"12\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"5\"}}},\"direct_transfer\":false,\"mutate_token_property_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"8\"}}},\"tokens\":{\"handle\":\"0xa18985171700c1f43182fd5b63a389b960b72ccae13aedd6cda384f566a45857\"},\"withdraw_events\":{\"counter\":\"12\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"6\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838", + "stateKeyHash": "Xje+VRCKryCJ5bUZLsYSyRBNVyz22fidfih9glQjqL8=", + "type": { + "address": "0x3", + "module": "token", + "name": "Collections" + }, + "typeStr": "0x3::token::Collections", + "data": "{\"collection_data\":{\"handle\":\"0x5a608d04222bd2de8c9fe6ddc7bc277c390cbc87bdf2688fcdb513b34179fe69\"},\"create_collection_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"2\"}}},\"create_token_data_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"3\"}}},\"mint_token_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"creation_num\":\"4\"}}},\"token_data\":{\"handle\":\"0x7c579e47a2ca935a7d06f90736a0be7a46d31467a190d453e6be308f7b8ced87\"}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", + "stateKeyHash": "PRT+heWBbgyc4UmVjGbYj1woWhI9Kq+dsxI5F7l9Q1Y=", + "type": { + "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", + "module": "domains", + "name": "RegisterNameEventsV1" + }, + "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::RegisterNameEventsV1", + "data": "{\"register_name_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"creation_num\":\"5\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d", + "stateKeyHash": "2IFuIc20ACMDujSLTIy7XvbaAp3E8z2OzG9WZH30IxI=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"141897700\"},\"deposit_events\":{\"counter\":\"3\",\"guid\":{\"id\":{\"addr\":\"0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d", + "stateKeyHash": "l6Tfv9Rw8sUEQ5hD4rKUOVWuC+7Mk2uf3sNpVr9uPBg=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"8\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"2\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d", + "stateKeyHash": "NMggaaFct/j2B7zs23a5BDMR6n0Zo9yOhPAun4kIolQ=", + "type": { + "address": "0x3", + "module": "token", + "name": "TokenStore" + }, + "typeStr": "0x3::token::TokenStore", + "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d\",\"creation_num\":\"6\"}}},\"deposit_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d\",\"creation_num\":\"4\"}}},\"direct_transfer\":true,\"mutate_token_property_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d\",\"creation_num\":\"7\"}}},\"tokens\":{\"handle\":\"0xb865d9c44c486e139d1f6ff8909ed24fb42ff1020803b69a4b9a3f7a32626b59\"},\"withdraw_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d\",\"creation_num\":\"5\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94", + "stateKeyHash": "fXcvN6JyZTRHhKctqomctHEfjOeyB5GGX8mXu2eAttQ=", + "type": { + "address": "0x3", + "module": "token", + "name": "TokenStore" + }, + "typeStr": "0x3::token::TokenStore", + "data": "{\"burn_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94\",\"creation_num\":\"6\"}}},\"deposit_events\":{\"counter\":\"6\",\"guid\":{\"id\":{\"addr\":\"0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94\",\"creation_num\":\"4\"}}},\"direct_transfer\":true,\"mutate_token_property_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94\",\"creation_num\":\"7\"}}},\"tokens\":{\"handle\":\"0x24d45ee1bd0fc0da572bb0277ff3e34c5863e65b6e2e6ee87596573e231c6223\"},\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94\",\"creation_num\":\"5\"}}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"100087042443440331\"", + "valueType": "u128" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "21CLwMCGYh3h1AFcm3zdTBB0pNWuLJspZNR7qmjRkRw=", + "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", + "key": "0x0003676f64", + "data": { + "key": "{\"domain_name\":\"god\",\"subdomain_name\":{\"vec\":[]}}", + "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1", + "value": "{\"expiration_time_sec\":\"1697648072\",\"property_version\":\"1\",\"target_address\":{\"vec\":[]}}", + "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordV1" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "RPH7JndDd1qgovPhUfsTp2V3YMUtkJp4l4aoiumLUlw=", + "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", + "key": "0x00036d6178", + "data": { + "key": "{\"domain_name\":\"max\",\"subdomain_name\":{\"vec\":[]}}", + "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1", + "value": "{\"expiration_time_sec\":\"1697648072\",\"property_version\":\"1\",\"target_address\":{\"vec\":[]}}", + "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordV1" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "Q5gc8X+H7sIKMa52T2MVeaFSlVm9WNJStGG2r2S2icM=", + "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", + "key": "0x000461736861", + "data": { + "key": "{\"domain_name\":\"asha\",\"subdomain_name\":{\"vec\":[]}}", + "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1", + "value": "{\"expiration_time_sec\":\"1697648072\",\"property_version\":\"1\",\"target_address\":{\"vec\":[]}}", + "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordV1" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "KjXMPkTnHpVuMGsRBELu6XqSuL79tvuwu4V3NA+KM3c=", + "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", + "key": "0x00056368726973", + "data": { + "key": "{\"domain_name\":\"chris\",\"subdomain_name\":{\"vec\":[]}}", + "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1", + "value": "{\"expiration_time_sec\":\"1697648072\",\"property_version\":\"1\",\"target_address\":{\"vec\":[]}}", + "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordV1" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "x4iXUerpeKSVxsoul2y6n3u7gdyGaUXi0FcM0B2l+qg=", + "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", + "key": "0x00056461766964", + "data": { + "key": "{\"domain_name\":\"david\",\"subdomain_name\":{\"vec\":[]}}", + "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1", + "value": "{\"expiration_time_sec\":\"1697648072\",\"property_version\":\"1\",\"target_address\":{\"vec\":[]}}", + "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordV1" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "yT9l3PQOL5SZIaLAWE+zWWoL0q0VPChZ+Uz/70JWMbo=", + "handle": "0x21a0fd41330f3a0a38173c7c0e4ac59cd51505f0594f64d3d637c12425c3c155", + "key": "0x00066d616179616e", + "data": { + "key": "{\"domain_name\":\"maayan\",\"subdomain_name\":{\"vec\":[]}}", + "keyType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordKeyV1", + "value": "{\"expiration_time_sec\":\"1697648072\",\"property_version\":\"1\",\"target_address\":{\"vec\":[]}}", + "valueType": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::NameRecordV1" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "/n78sdF0PxzJ6lYsaaRsOZuG18C0ZjBTVFKyMEEdJMs=", + "handle": "0x24d45ee1bd0fc0da572bb0277ff3e34c5863e65b6e2e6ee87596573e231c6223", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d657320563107676f642e6170740100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0xc80d306500000000\"}}]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "+6mETNnzHf8rq7l7XSVuZxZoYK5o6rhfV0ZP2Eh4rII=", + "handle": "0x24d45ee1bd0fc0da572bb0277ff3e34c5863e65b6e2e6ee87596573e231c6223", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d6573205631076d61782e6170740100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0xc80d306500000000\"}}]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "At0YPZ6Hk1UMUB4xiuK5DWTogUvJBmBbDu8KqTI+QG0=", + "handle": "0x24d45ee1bd0fc0da572bb0277ff3e34c5863e65b6e2e6ee87596573e231c6223", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d657320563108617368612e6170740100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0xc80d306500000000\"}}]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "zR7wUAFHFAyiM+MJDaLaUsr3w8i532+16FMY2y2jbmI=", + "handle": "0x24d45ee1bd0fc0da572bb0277ff3e34c5863e65b6e2e6ee87596573e231c6223", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d65732056310963687269732e6170740100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0xc80d306500000000\"}}]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "cIf9tZFz2g9StpkcAn/ctvXHB9LqWYiNSh0mSPPka5s=", + "handle": "0x24d45ee1bd0fc0da572bb0277ff3e34c5863e65b6e2e6ee87596573e231c6223", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d65732056310964617669642e6170740100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0xc80d306500000000\"}}]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "mD52SBfGiWUYIzHWDbru7ZaV6wtL0qMK70sBEniY1OA=", + "handle": "0x24d45ee1bd0fc0da572bb0277ff3e34c5863e65b6e2e6ee87596573e231c6223", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d65732056310a6d616179616e2e6170740100000000000000", + "data": { + "key": "{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}}", + "keyType": "0x3::token::TokenId", + "value": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}},\"token_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}},{\"key\":\"expiration_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0xc80d306500000000\"}}]}}}", + "valueType": "0x3::token::Token" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "Tsj/otWc1q7QzqPtzqDSAdUzlyfFSE35ziI4UHnld4Y=", + "handle": "0x7c579e47a2ca935a7d06f90736a0be7a46d31467a190d453e6be308f7b8ced87", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d657320563107676f642e617074", + "data": { + "key": "{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}", + "keyType": "0x3::token::TokenDataId", + "value": "{\"default_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}}]}},\"description\":\"This is an official Aptos Labs Name Service Name\",\"largest_property_version\":\"1\",\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"god.apt\",\"royalty\":{\"payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\"},\"supply\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/god.apt\"}", + "valueType": "0x3::token::TokenData" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "MddRFfIcImawOC+Oj44WLEg/RqMqHQQAFWsqxlNRpV4=", + "handle": "0x7c579e47a2ca935a7d06f90736a0be7a46d31467a190d453e6be308f7b8ced87", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d6573205631076d61782e617074", + "data": { + "key": "{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}", + "keyType": "0x3::token::TokenDataId", + "value": "{\"default_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}}]}},\"description\":\"This is an official Aptos Labs Name Service Name\",\"largest_property_version\":\"1\",\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"max.apt\",\"royalty\":{\"payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\"},\"supply\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/max.apt\"}", + "valueType": "0x3::token::TokenData" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "2bPi1mhJa5cKhL3BQ6UV3Psk5Vwas/SNQTkshJy0XIk=", + "handle": "0x7c579e47a2ca935a7d06f90736a0be7a46d31467a190d453e6be308f7b8ced87", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d657320563108617368612e617074", + "data": { + "key": "{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}", + "keyType": "0x3::token::TokenDataId", + "value": "{\"default_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}}]}},\"description\":\"This is an official Aptos Labs Name Service Name\",\"largest_property_version\":\"1\",\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"asha.apt\",\"royalty\":{\"payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\"},\"supply\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/asha.apt\"}", + "valueType": "0x3::token::TokenData" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bD2PBBwhFXOC9BLMUZu8rNXch8E3k8/o9jVSXWwv16g=", + "handle": "0x7c579e47a2ca935a7d06f90736a0be7a46d31467a190d453e6be308f7b8ced87", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d65732056310963687269732e617074", + "data": { + "key": "{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}", + "keyType": "0x3::token::TokenDataId", + "value": "{\"default_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}}]}},\"description\":\"This is an official Aptos Labs Name Service Name\",\"largest_property_version\":\"1\",\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"chris.apt\",\"royalty\":{\"payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\"},\"supply\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/chris.apt\"}", + "valueType": "0x3::token::TokenData" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "FxH76NHlHPYw7x6INSczRGdRTn5Rp/V3kBa1yvtzkeU=", + "handle": "0x7c579e47a2ca935a7d06f90736a0be7a46d31467a190d453e6be308f7b8ced87", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d65732056310964617669642e617074", + "data": { + "key": "{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}", + "keyType": "0x3::token::TokenDataId", + "value": "{\"default_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}}]}},\"description\":\"This is an official Aptos Labs Name Service Name\",\"largest_property_version\":\"1\",\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"david.apt\",\"royalty\":{\"payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\"},\"supply\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/david.apt\"}", + "valueType": "0x3::token::TokenData" + } + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "faTEKj5frBPfKA5e/LpQXbZuG/hDqUfa8uWB9jN+Fys=", + "handle": "0x7c579e47a2ca935a7d06f90736a0be7a46d31467a190d453e6be308f7b8ced87", + "key": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e19818380e4170746f73204e616d65732056310a6d616179616e2e617074", + "data": { + "key": "{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}", + "keyType": "0x3::token::TokenDataId", + "value": "{\"default_properties\":{\"map\":{\"data\":[{\"key\":\"type\",\"value\":{\"type\":\"0x1::string::String\",\"value\":\"0x06646f6d61696e\"}},{\"key\":\"creation_time_sec\",\"value\":{\"type\":\"u64\",\"value\":\"0x48da4e6300000000\"}}]}},\"description\":\"This is an official Aptos Labs Name Service Name\",\"largest_property_version\":\"1\",\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"maayan.apt\",\"royalty\":{\"payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\"},\"supply\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/maayan.apt\"}", + "valueType": "0x3::token::TokenData" + } + } + } + ] + }, + "epoch": "71", + "blockHeight": "1024425", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 845, + "eventSizeInfo": [ + { + "typeTagBytes": 61, + "totalBytes": 417 + }, + { + "typeTagBytes": 53, + "totalBytes": 175 + }, + { + "typeTagBytes": 55, + "totalBytes": 169 + }, + { + "typeTagBytes": 54, + "totalBytes": 176 + }, + { + "typeTagBytes": 53, + "totalBytes": 175 + }, + { + "typeTagBytes": 68, + "totalBytes": 317 + }, + { + "typeTagBytes": 54, + "totalBytes": 176 + }, + { + "typeTagBytes": 53, + "totalBytes": 175 + }, + { + "typeTagBytes": 62, + "totalBytes": 142 + }, + { + "typeTagBytes": 54, + "totalBytes": 176 + }, + { + "typeTagBytes": 53, + "totalBytes": 175 + }, + { + "typeTagBytes": 61, + "totalBytes": 408 + }, + { + "typeTagBytes": 53, + "totalBytes": 172 + }, + { + "typeTagBytes": 55, + "totalBytes": 166 + }, + { + "typeTagBytes": 54, + "totalBytes": 173 + }, + { + "typeTagBytes": 53, + "totalBytes": 172 + }, + { + "typeTagBytes": 68, + "totalBytes": 311 + }, + { + "typeTagBytes": 54, + "totalBytes": 173 + }, + { + "typeTagBytes": 53, + "totalBytes": 172 + }, + { + "typeTagBytes": 62, + "totalBytes": 139 + }, + { + "typeTagBytes": 54, + "totalBytes": 173 + }, + { + "typeTagBytes": 53, + "totalBytes": 172 + }, + { + "typeTagBytes": 61, + "totalBytes": 414 + }, + { + "typeTagBytes": 53, + "totalBytes": 174 + }, + { + "typeTagBytes": 55, + "totalBytes": 168 + }, + { + "typeTagBytes": 54, + "totalBytes": 175 + }, + { + "typeTagBytes": 53, + "totalBytes": 174 + }, + { + "typeTagBytes": 68, + "totalBytes": 315 + }, + { + "typeTagBytes": 54, + "totalBytes": 175 + }, + { + "typeTagBytes": 53, + "totalBytes": 174 + }, + { + "typeTagBytes": 62, + "totalBytes": 141 + }, + { + "typeTagBytes": 54, + "totalBytes": 175 + }, + { + "typeTagBytes": 53, + "totalBytes": 174 + }, + { + "typeTagBytes": 61, + "totalBytes": 408 + }, + { + "typeTagBytes": 53, + "totalBytes": 172 + }, + { + "typeTagBytes": 55, + "totalBytes": 166 + }, + { + "typeTagBytes": 54, + "totalBytes": 173 + }, + { + "typeTagBytes": 53, + "totalBytes": 172 + }, + { + "typeTagBytes": 68, + "totalBytes": 311 + }, + { + "typeTagBytes": 54, + "totalBytes": 173 + }, + { + "typeTagBytes": 53, + "totalBytes": 172 + }, + { + "typeTagBytes": 62, + "totalBytes": 139 + }, + { + "typeTagBytes": 54, + "totalBytes": 173 + }, + { + "typeTagBytes": 53, + "totalBytes": 172 + }, + { + "typeTagBytes": 61, + "totalBytes": 411 + }, + { + "typeTagBytes": 53, + "totalBytes": 173 + }, + { + "typeTagBytes": 55, + "totalBytes": 167 + }, + { + "typeTagBytes": 54, + "totalBytes": 174 + }, + { + "typeTagBytes": 53, + "totalBytes": 173 + }, + { + "typeTagBytes": 68, + "totalBytes": 313 + }, + { + "typeTagBytes": 54, + "totalBytes": 174 + }, + { + "typeTagBytes": 53, + "totalBytes": 173 + }, + { + "typeTagBytes": 62, + "totalBytes": 140 + }, + { + "typeTagBytes": 54, + "totalBytes": 174 + }, + { + "typeTagBytes": 53, + "totalBytes": 173 + }, + { + "typeTagBytes": 61, + "totalBytes": 414 + }, + { + "typeTagBytes": 53, + "totalBytes": 174 + }, + { + "typeTagBytes": 55, + "totalBytes": 168 + }, + { + "typeTagBytes": 54, + "totalBytes": 175 + }, + { + "typeTagBytes": 53, + "totalBytes": 174 + }, + { + "typeTagBytes": 68, + "totalBytes": 315 + }, + { + "typeTagBytes": 54, + "totalBytes": 175 + }, + { + "typeTagBytes": 53, + "totalBytes": 174 + }, + { + "typeTagBytes": 62, + "totalBytes": 141 + }, + { + "typeTagBytes": 54, + "totalBytes": 175 + }, + { + "typeTagBytes": 53, + "totalBytes": 174 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 84, + "valueBytes": 179 + }, + { + "keyBytes": 85, + "valueBytes": 225 + }, + { + "keyBytes": 86, + "valueBytes": 208 + }, + { + "keyBytes": 97, + "valueBytes": 48 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 85, + "valueBytes": 225 + }, + { + "keyBytes": 85, + "valueBytes": 225 + }, + { + "keyBytes": 66, + "valueBytes": 16 + }, + { + "keyBytes": 39, + "valueBytes": 17 + }, + { + "keyBytes": 39, + "valueBytes": 17 + }, + { + "keyBytes": 40, + "valueBytes": 17 + }, + { + "keyBytes": 41, + "valueBytes": 17 + }, + { + "keyBytes": 41, + "valueBytes": 17 + }, + { + "keyBytes": 42, + "valueBytes": 17 + }, + { + "keyBytes": 97, + "valueBytes": 169 + }, + { + "keyBytes": 97, + "valueBytes": 169 + }, + { + "keyBytes": 98, + "valueBytes": 170 + }, + { + "keyBytes": 99, + "valueBytes": 171 + }, + { + "keyBytes": 99, + "valueBytes": 171 + }, + { + "keyBytes": 100, + "valueBytes": 172 + }, + { + "keyBytes": 89, + "valueBytes": 258 + }, + { + "keyBytes": 89, + "valueBytes": 258 + }, + { + "keyBytes": 90, + "valueBytes": 260 + }, + { + "keyBytes": 91, + "valueBytes": 262 + }, + { + "keyBytes": 91, + "valueBytes": 262 + }, + { + "keyBytes": 92, + "valueBytes": 264 + } + ] + }, + "user": { + "request": { + "sender": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d", + "sequenceNumber": "1", + "maxGasAmount": "120559", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1666112097" + }, + "payload": { + "type": "TYPE_SCRIPT_PAYLOAD", + "scriptPayload": { + "code": { + "bytecode": "oRzrCwUAAAAIAQAOAg4SAyAvBE8EBVNFB5gB3gEI9gJgBtYDRwAAAAEAAgADAQQCBQIGAgcHAAQIBwAECQcAAA8HAQAAAQoAAwADCwUGAQACDAQHAAUNCAIABg4CAwAAEAIJAQAGEQoLAAYSDA0ABBMOAgABBAUHAQYMBggACgoCAwgBCAIBAAEFAQoCAQYKCQABAQEIAAMGDAgAAwELAwEJAAMFCwMBCAAIAAEIAQEGCAEBCAIEBgwIAgUDBm9wdGlvbgZzaWduZXIGc3RyaW5nBnZlY3RvcgV0b2tlbgdkb21haW5zDHRva2VuX2hlbHBlcgZTdHJpbmcLVG9rZW5EYXRhSWQHVG9rZW5JZAphZGRyZXNzX29mCGlzX2VtcHR5BHV0ZjghZm9yY2VfY3JlYXRlX29yX3NlaXplX2RvbWFpbl9uYW1lGGdldF90b2tlbl9zaWduZXJfYWRkcmVzcwZPcHRpb24Ebm9uZRJidWlsZF90b2tlbmRhdGFfaWQPbGF0ZXN0X3Rva2VuX2lkCHRyYW5zZmVyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4Z+0fa/kWFxsd4+6ShJuJeLfRueCozJgqPRnVNd/ZwMCgoCIQYFZGF2aWQEYXNoYQNtYXgFY2hyaXMDZ29kBm1hYXlhbgUgsn99Mp9tLIhn5UcpWMPPq8eBMAypZJ8kTiZ+HWuWbJQAAAEqBwAMAgoAEQAHASIMBg4COAAgAwwFJw0CRQQRAgwBCgAKAQaAM+EBAAAAABEDCgYgAxgFGQUHEQQ4AQsBEQYMBA4EEQcMBQoACwUHAQYBAAAAAAAAABEIBQcLAAEC", + "abi": { + "name": "main", + "visibility": "VISIBILITY_PUBLIC", + "isEntry": true, + "params": [ + { + "type": "MOVE_TYPES_REFERENCE", + "reference": { + "to": { + "type": "MOVE_TYPES_SIGNER" + } + } + } + ] + } + } + } + }, + "signature": { + "type": "TYPE_ED25519", + "ed25519": { + "publicKey": "wTgVguSrW0PZGqJNlIrNMTOhSasBPccfLUVGeVYvZbY=", + "signature": "Bkp6/Tpp8mjz4x3q1iOHpuXVRXXFhqVfM63Zdn5Yt32ZIij4CzMHN/tV2uOa74+lEIb+HYffoClFHwvkuMk6Bg==" + } + } + }, + "events": [ + { + "key": { + "creationNumber": "3", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "CreateTokenDataEvent" + } + }, + "typeStr": "0x3::token::CreateTokenDataEvent", + "data": "{\"description\":\"This is an official Aptos Labs Name Service Name\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"},\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"maayan.apt\",\"property_keys\":[\"creation_time_sec\",\"type\"],\"property_types\":[\"u64\",\"0x1::string::String\"],\"property_values\":[\"0x48da4e6300000000\",\"0x06646f6d61696e\"],\"royalty_payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/maayan.apt\"}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MintTokenEvent" + } + }, + "typeStr": "0x3::token::MintTokenEvent", + "data": "{\"amount\":\"1\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}}}" + }, + { + "key": { + "creationNumber": "8", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MutateTokenPropertyMapEvent" + } + }, + "typeStr": "0x3::token::MutateTokenPropertyMapEvent", + "data": "{\"keys\":[\"type\",\"expiration_time_sec\"],\"new_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}},\"old_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}},\"types\":[\"0x1::string::String\",\"u64\"],\"values\":[\"0x06646f6d61696e\",\"0xc80d306500000000\"]}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", + "module": "domains", + "name": "RegisterNameEventV1" + } + }, + "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::RegisterNameEventV1", + "data": "{\"domain_name\":\"maayan\",\"expiration_time_secs\":\"1697648072\",\"property_version\":\"1\",\"registration_fee_octas\":\"0\",\"subdomain_name\":{\"vec\":[]}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"maayan.apt\"}}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "CreateTokenDataEvent" + } + }, + "typeStr": "0x3::token::CreateTokenDataEvent", + "data": "{\"description\":\"This is an official Aptos Labs Name Service Name\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"},\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"god.apt\",\"property_keys\":[\"creation_time_sec\",\"type\"],\"property_types\":[\"u64\",\"0x1::string::String\"],\"property_values\":[\"0x48da4e6300000000\",\"0x06646f6d61696e\"],\"royalty_payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/god.apt\"}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MintTokenEvent" + } + }, + "typeStr": "0x3::token::MintTokenEvent", + "data": "{\"amount\":\"1\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}}}" + }, + { + "key": { + "creationNumber": "8", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MutateTokenPropertyMapEvent" + } + }, + "typeStr": "0x3::token::MutateTokenPropertyMapEvent", + "data": "{\"keys\":[\"type\",\"expiration_time_sec\"],\"new_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}},\"old_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}},\"types\":[\"0x1::string::String\",\"u64\"],\"values\":[\"0x06646f6d61696e\",\"0xc80d306500000000\"]}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", + "module": "domains", + "name": "RegisterNameEventV1" + } + }, + "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::RegisterNameEventV1", + "data": "{\"domain_name\":\"god\",\"expiration_time_secs\":\"1697648072\",\"property_version\":\"1\",\"registration_fee_octas\":\"0\",\"subdomain_name\":{\"vec\":[]}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"god.apt\"}}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "CreateTokenDataEvent" + } + }, + "typeStr": "0x3::token::CreateTokenDataEvent", + "data": "{\"description\":\"This is an official Aptos Labs Name Service Name\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"},\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"chris.apt\",\"property_keys\":[\"creation_time_sec\",\"type\"],\"property_types\":[\"u64\",\"0x1::string::String\"],\"property_values\":[\"0x48da4e6300000000\",\"0x06646f6d61696e\"],\"royalty_payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/chris.apt\"}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MintTokenEvent" + } + }, + "typeStr": "0x3::token::MintTokenEvent", + "data": "{\"amount\":\"1\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}}}" + }, + { + "key": { + "creationNumber": "8", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MutateTokenPropertyMapEvent" + } + }, + "typeStr": "0x3::token::MutateTokenPropertyMapEvent", + "data": "{\"keys\":[\"type\",\"expiration_time_sec\"],\"new_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}},\"old_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}},\"types\":[\"0x1::string::String\",\"u64\"],\"values\":[\"0x06646f6d61696e\",\"0xc80d306500000000\"]}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", + "module": "domains", + "name": "RegisterNameEventV1" + } + }, + "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::RegisterNameEventV1", + "data": "{\"domain_name\":\"chris\",\"expiration_time_secs\":\"1697648072\",\"property_version\":\"1\",\"registration_fee_octas\":\"0\",\"subdomain_name\":{\"vec\":[]}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94" + }, + "sequenceNumber": "2", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"chris.apt\"}}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "CreateTokenDataEvent" + } + }, + "typeStr": "0x3::token::CreateTokenDataEvent", + "data": "{\"description\":\"This is an official Aptos Labs Name Service Name\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"},\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"max.apt\",\"property_keys\":[\"creation_time_sec\",\"type\"],\"property_types\":[\"u64\",\"0x1::string::String\"],\"property_values\":[\"0x48da4e6300000000\",\"0x06646f6d61696e\"],\"royalty_payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/max.apt\"}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "6", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MintTokenEvent" + } + }, + "typeStr": "0x3::token::MintTokenEvent", + "data": "{\"amount\":\"1\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "6", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "7", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}}}" + }, + { + "key": { + "creationNumber": "8", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MutateTokenPropertyMapEvent" + } + }, + "typeStr": "0x3::token::MutateTokenPropertyMapEvent", + "data": "{\"keys\":[\"type\",\"expiration_time_sec\"],\"new_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}},\"old_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}},\"types\":[\"0x1::string::String\",\"u64\"],\"values\":[\"0x06646f6d61696e\",\"0xc80d306500000000\"]}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "7", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", + "module": "domains", + "name": "RegisterNameEventV1" + } + }, + "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::RegisterNameEventV1", + "data": "{\"domain_name\":\"max\",\"expiration_time_secs\":\"1697648072\",\"property_version\":\"1\",\"registration_fee_octas\":\"0\",\"subdomain_name\":{\"vec\":[]}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94" + }, + "sequenceNumber": "3", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"max.apt\"}}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "CreateTokenDataEvent" + } + }, + "typeStr": "0x3::token::CreateTokenDataEvent", + "data": "{\"description\":\"This is an official Aptos Labs Name Service Name\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"},\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"asha.apt\",\"property_keys\":[\"creation_time_sec\",\"type\"],\"property_types\":[\"u64\",\"0x1::string::String\"],\"property_values\":[\"0x48da4e6300000000\",\"0x06646f6d61696e\"],\"royalty_payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/asha.apt\"}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "8", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MintTokenEvent" + } + }, + "typeStr": "0x3::token::MintTokenEvent", + "data": "{\"amount\":\"1\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "8", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "9", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}}}" + }, + { + "key": { + "creationNumber": "8", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MutateTokenPropertyMapEvent" + } + }, + "typeStr": "0x3::token::MutateTokenPropertyMapEvent", + "data": "{\"keys\":[\"type\",\"expiration_time_sec\"],\"new_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}},\"old_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}},\"types\":[\"0x1::string::String\",\"u64\"],\"values\":[\"0x06646f6d61696e\",\"0xc80d306500000000\"]}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "9", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", + "module": "domains", + "name": "RegisterNameEventV1" + } + }, + "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::RegisterNameEventV1", + "data": "{\"domain_name\":\"asha\",\"expiration_time_secs\":\"1697648072\",\"property_version\":\"1\",\"registration_fee_octas\":\"0\",\"subdomain_name\":{\"vec\":[]}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94" + }, + "sequenceNumber": "4", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"asha.apt\"}}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "CreateTokenDataEvent" + } + }, + "typeStr": "0x3::token::CreateTokenDataEvent", + "data": "{\"description\":\"This is an official Aptos Labs Name Service Name\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"},\"maximum\":\"0\",\"mutability_config\":{\"description\":true,\"maximum\":false,\"properties\":true,\"royalty\":false,\"uri\":true},\"name\":\"david.apt\",\"property_keys\":[\"creation_time_sec\",\"type\"],\"property_types\":[\"u64\",\"0x1::string::String\"],\"property_values\":[\"0x48da4e6300000000\",\"0x06646f6d61696e\"],\"royalty_payee_address\":\"0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c\",\"royalty_points_denominator\":\"0\",\"royalty_points_numerator\":\"0\",\"uri\":\"https://www.aptosnames.com/api/mainnet/v1/metadata/david.apt\"}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "10", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MintTokenEvent" + } + }, + "typeStr": "0x3::token::MintTokenEvent", + "data": "{\"amount\":\"1\",\"id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "10", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "11", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}}}" + }, + { + "key": { + "creationNumber": "8", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "MutateTokenPropertyMapEvent" + } + }, + "typeStr": "0x3::token::MutateTokenPropertyMapEvent", + "data": "{\"keys\":[\"type\",\"expiration_time_sec\"],\"new_id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}},\"old_id\":{\"property_version\":\"0\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}},\"types\":[\"0x1::string::String\",\"u64\"],\"values\":[\"0x06646f6d61696e\",\"0xc80d306500000000\"]}" + }, + { + "key": { + "creationNumber": "6", + "accountAddress": "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" + }, + "sequenceNumber": "11", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c", + "module": "domains", + "name": "RegisterNameEventV1" + } + }, + "typeStr": "0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::domains::RegisterNameEventV1", + "data": "{\"domain_name\":\"david\",\"expiration_time_secs\":\"1697648072\",\"property_version\":\"1\",\"registration_fee_octas\":\"0\",\"subdomain_name\":{\"vec\":[]}}" + }, + { + "key": { + "creationNumber": "5", + "accountAddress": "0x91945b4672607a327019e768dd6045d1254d1102d882df434ca734250bb3581d" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x3::token::WithdrawEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}}}" + }, + { + "key": { + "creationNumber": "4", + "accountAddress": "0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94" + }, + "sequenceNumber": "5", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x3", + "module": "token", + "name": "DepositEvent" + } + }, + "typeStr": "0x3::token::DepositEvent", + "data": "{\"amount\":\"1\",\"id\":{\"property_version\":\"1\",\"token_data_id\":{\"collection\":\"Aptos Names V1\",\"creator\":\"0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838\",\"name\":\"david.apt\"}}}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/2175935_user_txn_multi_ed25519.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2175935_user_txn_multi_ed25519.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/2175935_user_txn_multi_ed25519.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2175935_user_txn_multi_ed25519.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2200077591_account_restoration_single_ed25519.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2200077591_account_restoration_single_ed25519.json new file mode 100644 index 0000000000000..ac60b8daacbcb --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2200077591_account_restoration_single_ed25519.json @@ -0,0 +1,266 @@ +{ + "timestamp": { + "seconds": "1736842688", + "nanos": 258451000 + }, + "version": "2200077591", + "info": { + "hash": "gNgvi81AuqOuIbYwuZWyJIP/MCgsMLFHztoLLkVFbzM=", + "stateChangeHash": "x7wNmRFflsUzJpTvO/s7LcpIRgsNJZfQqW4gqdQixcI=", + "eventRootHash": "88NfjFBBk516O8CqFZmgfAi8LRIiTalls5fSxjtOkVY=", + "gasUsed": "999", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "G0sDdTtfHO1ya0DfQTurSymWbYDcje3QXTjOzJDCxSM=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a", + "stateKeyHash": "V4b0abNN7BV/FXN58EWNodrVBj+kHjN25Y7yAthn4oE=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"99900000\"},\"deposit_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a", + "stateKeyHash": "kaVoydo3dStnBbGmVU3SWaVaZFkU12/GyfTdg4PJiAs=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2", + "stateKeyHash": "TPrhtIq8hAYE33zE2jRxFpi93BhjXCHnG7Up07iGv0o=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"100\"},\"deposit_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2", + "stateKeyHash": "ZoZlzg2NlCbag8QUp1TTw4mEVzQkkXB/XYIThcNvWKg=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"0\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"113578028364635431\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "9949", + "blockHeight": "276992782", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 268, + "eventSizeInfo": [ + { + "typeTagBytes": 60, + "totalBytes": 161 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a", + "maxGasAmount": "200000", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1736842707" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x1", + "name": "aptos_account" + }, + "name": "transfer" + }, + "arguments": [ + "\"0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2\"", + "\"100\"" + ], + "entryFunctionIdStr": "0x1::aptos_account::transfer" + } + }, + "signature": { + "type": "TYPE_SINGLE_SENDER", + "singleSender": { + "sender": { + "type": "TYPE_SINGLE_KEY", + "singleKeySignature": { + "publicKey": { + "type": "TYPE_ED25519", + "publicKey": "erVNvqw1T3X3hYntMBUSEAZsEr2PMccIcmZzI3+igaU=" + }, + "signature": { + "type": "TYPE_ED25519", + "signature": "PI+wp6BZ3t6DQle8gZLahdI1rjV6LY5kTSu0XFcL8wfOdSvmhv5Dll/T8JpCuXeDojvmM1FLb81IzPbo7ePSBA==", + "ed25519": { + "signature": "PI+wp6BZ3t6DQle8gZLahdI1rjV6LY5kTSu0XFcL8wfOdSvmhv5Dll/T8JpCuXeDojvmM1FLb81IzPbo7ePSBA==" + } + } + } + } + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "account", + "name": "CoinRegisterEvent" + } + }, + "typeStr": "0x1::account::CoinRegisterEvent", + "data": "{\"type_info\":{\"account_address\":\"0x1\",\"module_name\":\"0x6170746f735f636f696e\",\"struct_name\":\"0x4170746f73436f696e\"}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"100\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xedb6f48dc381485e1a46ec267a39c8f9769ebacf392ebdf74472173a8b95a7a2" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"100\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"6\",\"io_gas_units\":\"5\",\"storage_fee_octas\":\"98800\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"999\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2200077800_account_restoration_rotated_to_multi_key.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2200077800_account_restoration_rotated_to_multi_key.json new file mode 100644 index 0000000000000..75b3de6ad6486 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2200077800_account_restoration_rotated_to_multi_key.json @@ -0,0 +1,293 @@ +{ + "timestamp": { + "seconds": "1736842691", + "nanos": 898036000 + }, + "version": "2200077800", + "info": { + "hash": "BrHhl02M2xnIMYh56FOk2GMSE9LfbKBnJrABjaU5PIc=", + "stateChangeHash": "OchhUOgVYl9cNXoVDLoqpB7v4kRapcI5+78zv8V4dP4=", + "eventRootHash": "Wu4TISVXw4Ys5bzJ44Wx2P/oDv3Wg0e8ct9ENP8+8lo=", + "gasUsed": "999", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "Tzth2xdgW0qycy1KUYDj96wBPhhwE5GjBHmF6btNZf8=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a", + "stateKeyHash": "V4b0abNN7BV/FXN58EWNodrVBj+kHjN25Y7yAthn4oE=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"99799600\"},\"deposit_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"2\",\"guid\":{\"id\":{\"addr\":\"0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a", + "stateKeyHash": "kaVoydo3dStnBbGmVU3SWaVaZFkU12/GyfTdg4PJiAs=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xfa444eef0d28f64b1c7494a483876b353db79b96890dfa22c6f03e68c2d73f22\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"3\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2", + "stateKeyHash": "k9MrR+v/UMnO3qxH/GbcfFhYTWGifjvJ3uO33h+OSU4=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"100\"},\"deposit_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2", + "stateKeyHash": "bFLjQApu/l4eqHdRz2egSkfBF0IFu18nv/K8t3EBM9E=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"0\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"113578028361795775\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "9949", + "blockHeight": "276992799", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 443, + "eventSizeInfo": [ + { + "typeTagBytes": 60, + "totalBytes": 161 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a", + "sequenceNumber": "2", + "maxGasAmount": "200000", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1736842711" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x1", + "name": "aptos_account" + }, + "name": "transfer" + }, + "arguments": [ + "\"0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2\"", + "\"100\"" + ], + "entryFunctionIdStr": "0x1::aptos_account::transfer" + } + }, + "signature": { + "type": "TYPE_SINGLE_SENDER", + "singleSender": { + "sender": { + "type": "TYPE_MULTI_KEY", + "multiKeySignature": { + "publicKeys": [ + { + "type": "TYPE_ED25519", + "publicKey": "HqdmXS/o+xEb9231DKElbShRO1HTL/RkRwPPXT08fB4=" + }, + { + "type": "TYPE_ED25519", + "publicKey": "6ro2kifr3fxElaLNdB9cBMftCdpHrK8p7FCoBqPogtM=" + }, + { + "type": "TYPE_SECP256K1_ECDSA", + "publicKey": "BC+QQaU0E/FXd6Np1HUeINUAnvMrZiWrLNQfl/LaSdhCcKBU8bnITWlhzB89R9RhxQAFv7JqgsNYyqlnAAuBEEw=" + } + ], + "signatures": [ + { + "signature": { + "type": "TYPE_ED25519", + "signature": "e80b1nkDx8coaEKiV6olRMGc0J/pZGFhGXPiMf6qDYcTKNWR9sE0JugJUw+/uMvgxiA/IbVRxOoWO9i70gxGCQ==", + "ed25519": { + "signature": "e80b1nkDx8coaEKiV6olRMGc0J/pZGFhGXPiMf6qDYcTKNWR9sE0JugJUw+/uMvgxiA/IbVRxOoWO9i70gxGCQ==" + } + } + }, + { + "index": 2, + "signature": { + "type": "TYPE_SECP256K1_ECDSA", + "signature": "d2IE0w8+mcUrlcrkUK1vxJdElS6TtIfK0BAZ320e7bhwGnl/tKSSFUCnvU/D6iCwUDofDl6G6mWFmiB9aKkxvQ==", + "secp256k1Ecdsa": { + "signature": "d2IE0w8+mcUrlcrkUK1vxJdElS6TtIfK0BAZ320e7bhwGnl/tKSSFUCnvU/D6iCwUDofDl6G6mWFmiB9aKkxvQ==" + } + } + } + ], + "signaturesRequired": 2 + } + } + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "account", + "name": "CoinRegisterEvent" + } + }, + "typeStr": "0x1::account::CoinRegisterEvent", + "data": "{\"type_info\":{\"account_address\":\"0x1\",\"module_name\":\"0x6170746f735f636f696e\",\"struct_name\":\"0x4170746f73436f696e\"}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x21fccd4b01606fa6d094f3b99d6c4134107bf3bd72ef386316554356953e478a" + }, + "sequenceNumber": "1", + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"100\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0xbaa06bd9684eefe879615e2cd77fd3ce3881c26867ae85055a577e1f584c00d2" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"100\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"6\",\"io_gas_units\":\"5\",\"storage_fee_octas\":\"98800\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"999\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2200077877_account_restoration_rotated_to_single_secp256k1.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2200077877_account_restoration_rotated_to_single_secp256k1.json new file mode 100644 index 0000000000000..60137bb1de6e1 --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2200077877_account_restoration_rotated_to_single_secp256k1.json @@ -0,0 +1,267 @@ +{ + "timestamp": { + "seconds": "1736842693", + "nanos": 386066000 + }, + "version": "2200077877", + "info": { + "hash": "oVLSJd2GJk7E4ABeULX1gWKVMBk0rhIT7ui7XmsNMlY=", + "stateChangeHash": "LsjSOoL7T4r1GAAHRY/lTpV3tVm0ANLC+bjndtvsauk=", + "eventRootHash": "ZNtWE4bOLr09XXUhtokFCJDvfj9Oho+AnpDfCXc2m0s=", + "gasUsed": "999", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "NTrKmxxLPPTun4kPl0droPWBz/Vv37jihKjScF5Y/FU=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x19169c4c4e275aba9f20de1ee740dfc4914989e8ead71c6604cb832c99f26626", + "stateKeyHash": "lzTPc20o1i61BUkgOpRw9TeA9IWfHHDQSu83uVEA2LY=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"99899600\"},\"deposit_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x19169c4c4e275aba9f20de1ee740dfc4914989e8ead71c6604cb832c99f26626\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x19169c4c4e275aba9f20de1ee740dfc4914989e8ead71c6604cb832c99f26626\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x19169c4c4e275aba9f20de1ee740dfc4914989e8ead71c6604cb832c99f26626", + "stateKeyHash": "+cLOlzn7mFbCUToPXpGLnpo9MWtAwU2hvlvCsBjmjUc=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x229e8017b6c49a92435adb1e5f5d2b3bc0a7c17d712afaa424be61da4127b51a\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x19169c4c4e275aba9f20de1ee740dfc4914989e8ead71c6604cb832c99f26626\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x19169c4c4e275aba9f20de1ee740dfc4914989e8ead71c6604cb832c99f26626\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"2\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9", + "stateKeyHash": "UhY+3vXjfO3iNQPMEVJXbSz9Gh5Bus/mWLFIrJMqNrY=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"100\"},\"deposit_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9", + "stateKeyHash": "LSIxNf61pEzTJFgWit0y8kDByxl3ZtRSjGH54IuyU5o=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"0\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"113578028359990440\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "9949", + "blockHeight": "276992805", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 301, + "eventSizeInfo": [ + { + "typeTagBytes": 60, + "totalBytes": 161 + }, + { + "typeTagBytes": 53, + "totalBytes": 109 + }, + { + "typeTagBytes": 52, + "totalBytes": 108 + }, + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0x19169c4c4e275aba9f20de1ee740dfc4914989e8ead71c6604cb832c99f26626", + "sequenceNumber": "1", + "maxGasAmount": "200000", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1736842713" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x1", + "name": "aptos_account" + }, + "name": "transfer" + }, + "arguments": [ + "\"0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9\"", + "\"100\"" + ], + "entryFunctionIdStr": "0x1::aptos_account::transfer" + } + }, + "signature": { + "type": "TYPE_SINGLE_SENDER", + "singleSender": { + "sender": { + "type": "TYPE_SINGLE_KEY", + "singleKeySignature": { + "publicKey": { + "type": "TYPE_SECP256K1_ECDSA", + "publicKey": "BIivkAYwcmhiv7wKU3q7ifdgQLU0vb3NlsuxcrViNETJo1S44HrmTMh0U1+rWXh428shHR4y7woaEIhkP0DDX6A=" + }, + "signature": { + "type": "TYPE_SECP256K1_ECDSA", + "signature": "EaIiTEJXBnC3tc1B242PaUTOKOPGR6JHqywoAgYu2uxHjMS7jLEgWfvW1SLK6r/qPoTJm3q6jPGLlBtEhOC9Ug==", + "secp256k1Ecdsa": { + "signature": "EaIiTEJXBnC3tc1B242PaUTOKOPGR6JHqywoAgYu2uxHjMS7jLEgWfvW1SLK6r/qPoTJm3q6jPGLlBtEhOC9Ug==" + } + } + } + } + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "account", + "name": "CoinRegisterEvent" + } + }, + "typeStr": "0x1::account::CoinRegisterEvent", + "data": "{\"type_info\":{\"account_address\":\"0x1\",\"module_name\":\"0x6170746f735f636f696e\",\"struct_name\":\"0x4170746f73436f696e\"}}" + }, + { + "key": { + "creationNumber": "3", + "accountAddress": "0x19169c4c4e275aba9f20de1ee740dfc4914989e8ead71c6604cb832c99f26626" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "WithdrawEvent" + } + }, + "typeStr": "0x1::coin::WithdrawEvent", + "data": "{\"amount\":\"100\"}" + }, + { + "key": { + "creationNumber": "2", + "accountAddress": "0x1ca668c00efd5880b9d732656cac058a4eb41b18dec9435c13bc75c5b1e5eea9" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "coin", + "name": "DepositEvent" + } + }, + "typeStr": "0x1::coin::DepositEvent", + "data": "{\"amount\":\"100\"}" + }, + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"6\",\"io_gas_units\":\"5\",\"storage_fee_octas\":\"98800\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"999\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2212040150_transaction_without_events.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2212040150_transaction_without_events.json new file mode 100644 index 0000000000000..9fbef5c48d56f --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/2212040150_transaction_without_events.json @@ -0,0 +1,23 @@ +{ + "timestamp": { + "seconds": "1737050304", + "nanos": 103104000 + }, + "version": "2212040150", + "info": { + "hash": "bIIZYa623MT05mVir/kdXV0RiOWvdqv8+zuiOTkdzcM=", + "stateChangeHash": "r7bhT+R9hQ/Qpzlbz7mX/6z0cV4PiVzBYsIY5KdWS8Y=", + "eventRootHash": "QUNDVU1VTEFUT1JfUExBQ0VIT0xERVJfSEFTSAAAAAA=", + "stateCheckpointHash": "A9xQHEyJhpTuwsVvh9mJ1JKMBBDaS1EgijA0smOEe8Y=", + "success": true, + "vmStatus": "Executed successfully", + "accumulatorRootHash": "noEBayuZtH8qUETrYcBwt8XrYedMxtlAvbPuVFeHQd4=" + }, + "epoch": "9978", + "blockHeight": "277971867", + "type": "TRANSACTION_TYPE_STATE_CHECKPOINT", + "sizeInfo": { + "transactionBytes": 33 + }, + "stateCheckpoint": {} +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/303690531_ans_lookup_v2.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/303690531_ans_lookup_v2.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/303690531_ans_lookup_v2.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/303690531_ans_lookup_v2.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/308783012_fa_transfer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/308783012_fa_transfer.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/308783012_fa_transfer.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/308783012_fa_transfer.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/325355235_token_v2_unlimited_supply_mint.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/325355235_token_v2_unlimited_supply_mint.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/325355235_token_v2_unlimited_supply_mint.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/325355235_token_v2_unlimited_supply_mint.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/407418623_user_txn_single_key_secp256k1_ecdsa.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/407418623_user_txn_single_key_secp256k1_ecdsa.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/407418623_user_txn_single_key_secp256k1_ecdsa.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/407418623_user_txn_single_key_secp256k1_ecdsa.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/423176063_account_transaction_delete.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/423176063_account_transaction_delete.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/423176063_account_transaction_delete.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/423176063_account_transaction_delete.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/438536688_ans_current_ans_lookup_v2.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/438536688_ans_current_ans_lookup_v2.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/438536688_ans_current_ans_lookup_v2.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/438536688_ans_current_ans_lookup_v2.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/453498957_token_v2_mint_and_transfer_event_v1.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/453498957_token_v2_mint_and_transfer_event_v1.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/453498957_token_v2_mint_and_transfer_event_v1.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/453498957_token_v2_mint_and_transfer_event_v1.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/464961735_user_txn_single_key_ed25519.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/464961735_user_txn_single_key_ed25519.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/464961735_user_txn_single_key_ed25519.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/464961735_user_txn_single_key_ed25519.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/4827964_stake_initialize.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/4827964_stake_initialize.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/4827964_stake_initialize.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/4827964_stake_initialize.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/508365567_fa_v1_events.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/508365567_fa_v1_events.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/508365567_fa_v1_events.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/508365567_fa_v1_events.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/513424821_default_block_metadata_transactions.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/513424821_default_block_metadata_transactions.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/513424821_default_block_metadata_transactions.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/513424821_default_block_metadata_transactions.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/527013476_user_txn_single_sender_secp256k1_ecdsa.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/527013476_user_txn_single_sender_secp256k1_ecdsa.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/527013476_user_txn_single_sender_secp256k1_ecdsa.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/527013476_user_txn_single_sender_secp256k1_ecdsa.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/537250181_token_v2_fixed_supply_mint.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/537250181_token_v2_fixed_supply_mint.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/537250181_token_v2_fixed_supply_mint.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/537250181_token_v2_fixed_supply_mint.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/551057865_user_txn_single_sender_webauth.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/551057865_user_txn_single_sender_webauth.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/551057865_user_txn_single_sender_webauth.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/551057865_user_txn_single_sender_webauth.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/578318306_objects_write_resource.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/578318306_objects_write_resource.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/578318306_objects_write_resource.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/578318306_objects_write_resource.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/578366445_token_v2_burn_event_v2.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/578366445_token_v2_burn_event_v2.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/578366445_token_v2_burn_event_v2.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/578366445_token_v2_burn_event_v2.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/590098441_user_txn_single_sender_ed25519.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/590098441_user_txn_single_sender_ed25519.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/590098441_user_txn_single_sender_ed25519.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/590098441_user_txn_single_sender_ed25519.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/602320562_token_v2_aptos_token_mint.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/602320562_token_v2_aptos_token_mint.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/602320562_token_v2_aptos_token_mint.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/602320562_token_v2_aptos_token_mint.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/685_user_txn_ed25519.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/685_user_txn_ed25519.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/685_user_txn_ed25519.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/685_user_txn_ed25519.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/84023785_token_v2_claim_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/84023785_token_v2_claim_offer.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/84023785_token_v2_claim_offer.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/84023785_token_v2_claim_offer.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/967255533_token_v2_mutation_event.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/967255533_token_v2_mutation_event.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/967255533_token_v2_mutation_event.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/967255533_token_v2_mutation_event.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/976087151_user_txn_single_sender_keyless.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/976087151_user_txn_single_sender_keyless.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/976087151_user_txn_single_sender_keyless.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/976087151_user_txn_single_sender_keyless.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/97963136_token_v2_cancel_offer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/97963136_token_v2_cancel_offer.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/97963136_token_v2_cancel_offer.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/97963136_token_v2_cancel_offer.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/999929475_coin_and_fa_transfers.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/999929475_coin_and_fa_transfers.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/999929475_coin_and_fa_transfers.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/999929475_coin_and_fa_transfers.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/999930475_token_v2_concurrent_mint.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/999930475_token_v2_concurrent_mint.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_mainnet_txns/999930475_token_v2_concurrent_mint.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_mainnet_txns/999930475_token_v2_concurrent_mint.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/1200394037_fa_v2_frozen_event.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/1200394037_fa_v2_frozen_event.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/1200394037_fa_v2_frozen_event.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/1200394037_fa_v2_frozen_event.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/1255836496_v2_fa_metadata_.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/1255836496_v2_fa_metadata_.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/1255836496_v2_fa_metadata_.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/1255836496_v2_fa_metadata_.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/1_genesis.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/1_genesis.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/1_genesis.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/1_genesis.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/2646510387_concurrent_fa.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/2646510387_concurrent_fa.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/2646510387_concurrent_fa.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/2646510387_concurrent_fa.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/278556781_v1_coin_register_fa_metadata.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/278556781_v1_coin_register_fa_metadata.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/278556781_v1_coin_register_fa_metadata.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/278556781_v1_coin_register_fa_metadata.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/2_new_block_event.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/2_new_block_event.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/2_new_block_event.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/2_new_block_event.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/3_empty_txn.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/3_empty_txn.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/3_empty_txn.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/3_empty_txn.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/4462417704_secondary_store_burnt.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/4462417704_secondary_store_burnt.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/4462417704_secondary_store_burnt.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/4462417704_secondary_store_burnt.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/5523474016_validator_txn.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/5523474016_validator_txn.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/5523474016_validator_txn.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/5523474016_validator_txn.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/5979639459_coin_register.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/5979639459_coin_register.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/5979639459_coin_register.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/5979639459_coin_register.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/5992795934_fa_activities.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/5992795934_fa_activities.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/5992795934_fa_activities.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/5992795934_fa_activities.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/646928741_no_events.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/646928741_no_events.json similarity index 100% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/imported_testnet_txns/646928741_no_events.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/646928741_no_events.json diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/769222973_multisig.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/769222973_multisig.json new file mode 100644 index 0000000000000..3b299e8ae13dc --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/imported_testnet_txns/769222973_multisig.json @@ -0,0 +1,160 @@ +{ + "timestamp": { + "seconds": "1699957697", + "nanos": 493428000 + }, + "version": "769222973", + "info": { + "hash": "X04TdoGNvqzc3wPgEvATVGjTYE6xYmKulZxdlHrfxiA=", + "stateChangeHash": "7559wtCnyZkFlnY77JLA5DSx84rG+cMhLyv7W2bx0ko=", + "eventRootHash": "H9YVfMRODKfXO7Gmq1mSRx9cZx/nyhryn1p6pe+wzpQ=", + "gasUsed": "201", + "vmStatus": "Transaction Executed and Committed with Error CONSTRAINT_NOT_SATISFIED", + "accumulatorRootHash": "2dlYHrG3KeCypnnNMRsHyQ3fypFcyfXN3c9kGrTYkDw=", + "changes": [ + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf394d0ecffd4a498ab19347d0f5dff37da6d73a5ebbbeaf03d3079603f1bbeaf", + "stateKeyHash": "uUD1R7Ee2ZGkNbwIPO+xzx40rYkdk/4XWDkJiL6KX6E=", + "type": { + "address": "0x1", + "module": "coin", + "name": "CoinStore", + "genericTypeParams": [ + { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "aptos_coin", + "name": "AptosCoin" + } + } + ] + }, + "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", + "data": "{\"coin\":{\"value\":\"99979900\"},\"deposit_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xf394d0ecffd4a498ab19347d0f5dff37da6d73a5ebbbeaf03d3079603f1bbeaf\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xf394d0ecffd4a498ab19347d0f5dff37da6d73a5ebbbeaf03d3079603f1bbeaf\",\"creation_num\":\"3\"}}}}" + } + }, + { + "type": "TYPE_WRITE_RESOURCE", + "writeResource": { + "address": "0xf394d0ecffd4a498ab19347d0f5dff37da6d73a5ebbbeaf03d3079603f1bbeaf", + "stateKeyHash": "wYVMOPtA7stEkJSjQaOeQ5WSoO+GmhS0hhgb308imzQ=", + "type": { + "address": "0x1", + "module": "account", + "name": "Account" + }, + "typeStr": "0x1::account::Account", + "data": "{\"authentication_key\":\"0xf394d0ecffd4a498ab19347d0f5dff37da6d73a5ebbbeaf03d3079603f1bbeaf\",\"coin_register_events\":{\"counter\":\"1\",\"guid\":{\"id\":{\"addr\":\"0xf394d0ecffd4a498ab19347d0f5dff37da6d73a5ebbbeaf03d3079603f1bbeaf\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xf394d0ecffd4a498ab19347d0f5dff37da6d73a5ebbbeaf03d3079603f1bbeaf\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + } + }, + { + "type": "TYPE_WRITE_TABLE_ITEM", + "writeTableItem": { + "stateKeyHash": "bkso1A+YoQamUWNTCSTA3LQME0nTqpFdEItNbPwd2xk=", + "handle": "0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca", + "key": "0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935", + "data": { + "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", + "keyType": "address", + "value": "\"18625784906183727596\"", + "valueType": "u128" + } + } + } + ] + }, + "epoch": "10348", + "blockHeight": "168057583", + "type": "TRANSACTION_TYPE_USER", + "sizeInfo": { + "transactionBytes": 41718, + "eventSizeInfo": [ + { + "typeTagBytes": 63, + "totalBytes": 103 + } + ], + "writeOpSizeInfo": [ + { + "keyBytes": 138, + "valueBytes": 105 + }, + { + "keyBytes": 84, + "valueBytes": 147 + }, + { + "keyBytes": 66, + "valueBytes": 16 + } + ] + }, + "user": { + "request": { + "sender": "0xf394d0ecffd4a498ab19347d0f5dff37da6d73a5ebbbeaf03d3079603f1bbeaf", + "maxGasAmount": "200000", + "gasUnitPrice": "100", + "expirationTimestampSecs": { + "seconds": "1699957717" + }, + "payload": { + "type": "TYPE_ENTRY_FUNCTION_PAYLOAD", + "entryFunctionPayload": { + "function": { + "module": { + "address": "0x1", + "name": "code" + }, + "name": "publish_package_txn" + }, + "arguments": [ + "\"0x0a546f75726e616d656e74010000000000000000403934463731373944343132303939354332443833344544444233323037373442343144444443364136353341353045453945414534453533393844434543324599021f8b08000000000002ffbd923f4fc33010c5777f8aaa4ba6fcc3692b2331b0b02106ba55153afbce6d686347b613f8f8d8a474013a66bb67fd4eefe9fc763da8131c68cf0c74b478582cb77670693661c94672beb5263d574555d44bc676483d1924a35af2c5631fac7f7211ffb0eeb467873644383b86d0fbfbb28cf238c842d9ae8444e66790fe322aeba88840c61c8d69a983d664cc0f125b97f4847576a452ff385c76af3afb33d0d69ec8bcc87752c1cf962924d3dc4eaebf723dc795d780e756ce1028c9dc7fbbdd38d0bc97494100d191f7143f255c5b96caf536156bccff25aacf0aeb0d2181566b2e38f2a6422d8450d028109273a9f94ad702b0c17aada56e04ad3604c0112ad1dcc5ee7e01cc08800aec0200000d0a6d6973635f7574696c73f8091f8b08000000000002ffb557db6edb3618beef53701e66488b8ad8865114726c2cc0725160dd86c4774940d0126573d5692215c768fceefd494a3245d3a903b482619dbeff7c5456c4754a9128ea2a2719cd4518668c47b8162ce5e8eb3b0447cd2922a52838e6220e432e2a96af3562d601d4ab271a89a2b21eae221ba63984e1d73b9a2601ba53b7fb99252ca940a16d517d0943c132ca05c9cad73015c93989042b721c15b9a0cf62f64ec1e18e0bf4f7f5e71b7c77f3eff5edf5f29fdb3bfce7cd5f9f3e7f5adedc8648ab7d557f5ca0395a0dc270d05096f52a65116279ca728a923a47ff152cc75a7fee35e78e81366411a098a62c63825661639cdf5e342e95474a05e220b0f5462d928fde6a30f0673d485e67ad40006b496198d27c2d36deb07963d0b4080a84b42282e28a261d30402f2c407cfc6228228f56095296348fbd6156837201fa9d8f0dd6f26009f218baeaa9f51e8d7d8bdf2b3c3be7589cf787dbbdf18aababfda9804070232230c97758148d4657cb109e973b7481e2aa28171e6fdd1f20097c22694d43345c9e0a4b07c284373cbb40e9c4877c3b485b781d81a9b8db7c076fbf49b7379b0ba7abe5b8676c809613dbfab1b4756cd93ef941c64fdcd6f7b3db4137968afd6c77f132650227759aeef0ff354959c2682cd9d491f0f40997446c8c3af5da4ce99f7dbb7269795cbbd0392c1724ace202b33ca6cf065cdde3429765ab438086c0d4344e45238e2bcacd3ec1eb55e3088b7c1498e2ec581c90e7f032f5be4093a0a3301a4f8bf66d9d3985348ddf68b5c920535309cb8974a6e1a6c8237534f65c6e3deddf64bbd7042b300d084cf97e9baeea7c7979894a4eebb8785fe5ebeed17dc67260419e1f03c8e528ad397ba26682cbcc86691763f85b530fe021aa3f4c158dbaf2d5bf95b10a0c0ef000052d1ba87c306f6c4d9b620b906ede86213cc0198baa42bb857b46a84057b1611cc14f14282111836a8389830652bb22cbc11703300109e086b64c6c0a28ea0d79922d0528c0b88acaa503d8d0835057fee3d50e98c8f11ce936a2eebda163ea87e19ae67af2919ac5b8e1e0f95692a504325cb2913e69a76659947845a22fbafff484fb8870e5dc99edd65872f03ce9bb8b035b1ffda67dee20544417320666fffaf55e3a0a1779ba7bec161d733553af9bc5cba0d06099150af06ad3b3fb984702b40a50e4cbd2f84eb7345bdde8792ce370d06dd95d0f4c4f13ce69257ef1089a1fb54be031f0a17c1df095032e0c096eaac841b57452b525e874e00666d04e9577cf5dad94ded6d25b08fb7be0fdc98da8516d43d3b400adbe878305378d6ddc6360c31038dee100250539798c0eb72e6f3a562bef840968389d9c143e9d9c0c98bdceb48bead9021e34e261705a48cfe4b7487487e1552d1e34ea6170e4eaf33dad949a4edea4c074624a3ed7d74a88dbafd349dfa1bd16e5595f5fd03bfe8062f6ad3a326694fdb906b6b1357469b3be0edd4dee0ad089d4838ec6e61120737d3489694e56307d134a440dfd1b2745855d6adb5b074caab93d10e5b09ca30ffd870c1e8d66475bb36690909453c74bc5c8f1520f6f2979343a8e5a8e1673a9848a849ab87a96a629f062292a6074565bc66947b9dd30f8a2d71f69f6679931b0fa0b84da1dac0fb28349edd5cb4b433d97ce72a0958ded958926cf16ba314f01168a5d3f6b8f40570737f44066e013397b21da5b52c5fdade5e83316f464fdf567ef185ada6e773d35669a25b2ff06d07e52d74f11000000000a746f6b656e5f75726973f1021f8b08000000000002ff6d904b4f023110c7ef7c8a8683d94d08105dc014f5e6c11831113919d374b7ed52d89d253b539ee1bb5b9ee24a0f4d3a9dfcfe8fbc502ed38c0a5782cc3510e7544c3508575a649b1af3c7a166488a73a4d242caf966a833d360c3fd73db3f2f5d52728b897064333cfc9bd26a505784720932d565bfb65f4b0a406283d19bf87c7f7d1e88d1c7cb9033d78dd823bbedb48f5b33176736090ecc9019072cd5244a09aac8c5394010f2a3c96392ddc934b1dda2b06ae9a1bf3e39df8ffd95eaa0dda89808fb7f08b144bd93f084532b8ecc7d10d7c74433e4ad562ccd2ad6365946b603d3b5c913a322eca1b2aa4799c3ce18ba14ad8a345a2b5c74efe6713e95cb15a0d14d3b33d804434845e9cb696616a6ad7ac5c2c2d25880cb635d5672f812134942c2ca77210efe8293e306bb39c5bf069cccd20a6d525838423098ebc47b7a38b4fac4be2e4c34aa4d343dab1e7eff9bd7c30be193e87eb0ad6d7f0093c9e5f19102000000000b6f626a6563745f7265667380091f8b08000000000002ffed57cd6ee33610bee729a628e0950061d343d1839218e86ed31645db00896f8b05414bb4c3462255924ad608fcee1d8a9248fdd9e9a97b680eb1a8f9e1ccc7f986a352e675c1c0c85a095a3261d2546eff6299218aed34bc5e00fed59a01ad8cd464a750e945aaa74e2d4d5f1f58b14be0f68b6122bf67f8b85154e81d53cde2275630c39ac78f5268a3eacc4827fa9d0b4655a07dbc1a6d67e41313c4eda4d3b459f63b6eec2a810f18f9d0569b1cc3ab0c975ef9ae598e95cca162848b9d44bde6599e8da152b262ca1c4849ab91374c8e8b7d9a3e34bf57178d74a738e23200d83fa31341f74c5d2dabdacdcf6995d4648f257d3aa1a2a42c4f086b91b7f17efbc9306d8814c5e1f3a27ea5492db82156555fbdd9aea45c78c376c3cbcb4bd83c52030e62c825d3e29d8147facce099163c877b5b8a51462bbae505379ce918a4006ede371e325b57707bf7e1b7db8f1bf2eb8f0fe4cf3b727ffbf3430af50fdfc30d7cd7e7a698c6783246f69873454a566e998a9a05ea2dd6f85df3fb8b558b5d76ae905d648f54c3133bb464b17fac2183a5501a10a3179bb6e49d4248975e256f68e314020a215ab0930ab654f3ac454cf7465b84da99b872bf6eb9b1f67e7df9d686221107ea616da7e91f4ec3db1f1d8a55bd2d7816b9f38d61570bd8334334df0bc412632234cf550af63fd33a4ec18980667fd71c5f39d43c5a546bdcf59b887de1584ed756baeefdc4c9dcc9c657bd3562034dafba81ad544abe907d21b7b418fbf116dda9ee1946451165171f4160893b39a46fb4b24edffb938cdf8041d17434129eef2c2093cef7f56233979283267c750e9cb0b2ec96c476dbfc7a93428e92f514a4c4322a05d74a13db076a865489bf1aa05a0b34e86e1a67d88233c7b3c07ac8b41e9048599263e66dc6adc51b71adabdc9ed8ffd006d08698387457ff02de4c31eabab0b680a2e53acafc14e39ae76a38d720bd23d750929ef101983639df546c8e63c679e978af11462101e71c0d387bda95bf6ee61c79e91937f630db667fb3d466cfb888ba4b2c99bdab6274cc7710b5d3daf5661de1ab1be8d77660c27721e49debce33ba6827c93eb44e7422b8ce4b1b150e21e867586c9562155576a2ac6a133d33ebe5d3672cb6c9d3c8efd00dc709691c4812ecbb1cd400aa49787db681d29984a38e815a96ac1f27fa3342f20f1416078868f62ce37eaf23b002c7e8d7f9cd8514c1e6c1a68d607953ac029c97b05cb879a7414803d49d3cbc309c33ed94a9511727fda636a0c1d9bdcff01ce1c58ea5b6b2d001703f671da7f765ce35dd160ca7db3d229cf7dc8b56836bd21b96f219192aa341c62b4fa064201875e4e99c994c64e1be53a9a7f454d6337022993bc5a1d6d12f8364a320af1eb2b639e2bc2d4b322ac349599e1b3072fca050f2d07ea7cd0c5d8bb79ba5cf0cbce1084f86390ec7f7917009583f9b8f0ce627f240e988446eaac502757e727301443e8eb3b75c879d9d7f1b7a44c117aafb021d0fb051cbc60496d8f71f003e11cd17f2e9229e437b168eb8fda81c742a4c4251acbf15fa86992e39909fe889c70b3cae7f00e47f691b9c11000000000d746f6b656e5f6d616e61676572e20b1f8b08000000000002ffd5586d6fdb3610fede5fc1a58021038edd01c350c8495623f5d260595c242e06ac28545aa26d2d12a9915452aff07fdf91d40b45c98e8376586b0481691e8ff7f2dc7327a52cca138224cb39c529a1d2f725bb23344831c52bc2d1e767083eb92048c8c8f785e4315df9fee75b922c07e8562fb7e3a610cb64cca8f3a3885794f0f1b3ea579c49268225876b1f18bf83638bbf48282bdd33bdb4749b03c63c232b7c3f644902df1af7750aea65a57cae568fe9ce38cb08971b084666196e07cbc8069c2cc5b853c0a8cc792c0a0da3d108cdd7706318b29c4a140b44994438976bc6e37f4804c7519e4558822290e34480ba9088a13e1e322a249a5ecfe6c1e4ddfccdece6f2cfe96b1fe53fff844ed18fc51d46e87c7675353d9f5fceae83ebc9ef531fdd83a98c9fe42fcf407671a4acb800338fc6dd875e4f6fcf6f2edfaaefadb37f902464a97215cddf4cd105e847c76842514c25e11812724f0608bcbe430b2c4834402b9cc6cb18dcc334428285314e10f904f18d090d0962144d540e8668c209dab01cad18404b5db0308148309807f2024485042db0fdcb2edbdfdd5cb66c5e4b99097f3412f023607bb8626c95109cc56208be8c44864372bc8c576bf0401c6321881423309b0435c886195d1d35a23c9ffd36dd11e0b709de10de30d1487f2791d5762f959ac8c174f9bda4894216d8210f210f55b8ce198580a23516e88e6c0a32d1d1e00483d7018e22ee23f59f0831d0db5ba3ebf9fb12f9c18ab33c0b52922e08f7f40222b5933e0c6f5c28b1fe07dbac7965b6aefed2aa018aa0ce2ddb5438a0a243c6231205a08746bac00695841580c274c707f5e18ca53bb6b735159cab40108130121075a0e21a6b68c9b8ce0fdc1373b543a502804523401ef0072c45553aa35884b91070d4642e57a08921499ae4bdcab28864090364faa86758d958d5b763406425a69d80881b59df2f5c09d8d22b45fae3eaa4aa1b2e7ff09cd3a7e8551db5814b60d67975b3ae1595334008502bdc5d2657e3861414ddbcc3d1e1814c50b8a78e1b994a95a6ec4a9f5a9cb8b03df37a8e21d61529bb27d02f2a13066dd4d7d16c23be34a886cbd6525e63a0b230a7499cc61200596f7a8d0b7a96c38d8db267e772f9d2ebe6f7fe612714cb39a2a6d7fb3e65947807aa0172b6240bbf8b9ac8f24512879e619dbec6700acc57bbaa5610f88e823ba82a33cdc98192f38bf1a540bf5f4c1c279a1dcea041ff9d43d9897d8935602db721357a1f689c71ce1e8255c21638e90096550b0e6ceb24ba505d1159ec78ad2b8736ba1e2da6621432c8fa42107540a221da6a788eb0958fc381550f55262c1c7a16906df5b3d786974d0b2aa61633a8e5a3e46040d1c508957ac5c86089584227d5bcaded51c4ac161fc304c729e11f4b4c36cc4a624a300f6471bec17a56fe3bc43cdb83dad792302bd18758aeb57c878e4159559602f0661245c60f8e63294a478ce686f556e5199f4f5bcdb649869d2df6859b64b79c9bfbcdfefaeac527ebfcd6ea47515400a318e76322ec980d50cf35bf1905c5f46d0f8b60e845ab29f41c90edb9a0cc537162c9c12907636dd0b943c4e5b2a8239430018cf5401025e6496201376b4baf7f9d5b046b8815f3bb2236704ed44cc01e686b3aa8ebae6366ebd76cb93bf13b90d2e0ca20cd150137549c79f5bd1d8346c758a2edefaba1c3bd6fd881aa4786114f85d05449fd40984b5c26c3add38840aed82680e9cddcd96dbefd70e9fbea0eaf53fdb819fd42b4b4c99d48147e0e88dfee660b0f3d413b469e6344b3553ea1053f0128a5c9d6f46795ad32aae716d35746d801e041a71d3ed71ac486867bc3d9acaa9d04a8459e3032a92cdafc7868fef63cb37cdf99b31d03bdf6b2114b15bcce8e61137617035a250de2c09d8ea1ed47ac0669d86c1068033619899a38693f33b4a6adc5d1957a96bf510df5c89db42aeb861dedb77360fa6f4cac23b3c7c47dddbfdf4a99ae33edc71727ea0979326fe9feff54b981d84738df7c54be323a9ebf87b72b326034d97c70e71febe588e9d620e9b55e8ed85edbaf539c771fdb67db7f0198d9c7ab4d170000000004726f6f6de5081f8b08000000000002ffd5566d6b233710fe9e5f31a51076dba5694ae9878d133868388ee68d5c4a29a508d92bdbaad7abada4b56b82ff7b476ffb227bd3847270e70fb6b53b7ae6999967465a8ba2291968d1c88aae59a5f35c0ab186e79313c04fa318285de4b9a83517559e3f7f64e53c837bbbdc5f0c8d145f544c760f69ad85227389c05b21578832fd8bcd74876297fb7883162b561167abf2dc2ef3fcc9fc74a67dc6ce9448365711a30d3e17c8c83e3d3b3b83775ab375ad59810050085062cdf492570bb3a66063d74baaf10b216c3c68c614544283d8561668262aa5e1faeefe893cdedfdf92fbdfeeae1f73687efa112ee1fb8bd6d9434977b89fbbddbcb2a0c6451fe5d7bb5fee10803cdcbcfbbd4339ef509e9608e03128947ccd0dfd18c690b9f970fbe1e9fa674b2a00fdd006df02294c0922500327695560c8b42824532a4786cec630e5084cab190331075ae1b2e01b5e34b4840526be6380d0377c85d5034da7a535afb158126a1bbfca406f455860364db6cf37e7f0f8f0310321816d98dc898af9575aa21b9a01d3330bfff51f480dab3d636421455393355b4f994cec02231c559993d77b6396fe69a19496cd4cc323329fd44b5a690cfd3dee7bdad5ec0a9654c18aed50fbe03f9e73eef53e71729a38e08955e4d5d55566edf72ecf75332df90ce64d050ba6894798b45e9216dce48fb489f77f1c56fa1f1e81cefe6e38dadb507a844ba69d862f612aa4145bb228c59496131b724be22ae93b4f2f069cbef39cfb5161896fe90afda946322b8ebad5764fd719ea04a5c934f6a61a985505fbc7beb4dd1ca28d3346956232248df08a78b51339a0ffaa1c76f51b4f72823d9285a7e99bb34ad68d7e6d665d685f2561907245ccec494efb294fb3c346ee61181ea18d2e2120394a1190effab08b7783293c2ab10c97e0f495e7b85ae865d26d0fa6db25c7964e384ccc8eb4979521a31e9627d4763fefc1990f9f43127a14d3805315bbf91b679e45354b638fb6ea5660480ac787c7f14780dfe57da7e960eb3ea28194397c1b466d6441318a83e93cd2e8e8f5a546b701e670ea8e93ec6de2c537476780d7f06b341b72e43de0f9ea0fd7376b372e9aeb791757872fe6897d9d063977876424e6ffdb5456492f36d4b8600995f2a08b8cf3e414bf20eaa63e46d0b93407976284d635ab8aa4830d22ee6ff4d23a14cf4c32aad9e8841b130f86db1f8e39265194ed60f33797a11cba2b934d25063f5ab96199ec15c39c9c429a4b564f529ebc5b26918308c515114d898f0548fbc49ab7b8f626d7829bc581204e234ef1c0ebc6a4d14894ac58144103463f23276e128a6e6e8fbbe86dd21b347b6025de3e8f3ba8f09633e6203d3685d662c3b05f9da807b91b26049edb88f7d171dedbf5c23d252a1d8aa127c6a3832a6dff7da2a9d38ef676d4a4632d540af5f60e7ae9fef5e58fd5d0e22307a41554b4cd85da9d3b2443355f3a0dce2586341ad741d57c07170c7b54ecc27c88ed8f4bd15ab9e07be58caa08639a3c3af93eeb8a0d326612e060861c7cbef627ff025f031602b10f000000000a6d617463686d616b6572c0101f8b08000000000002ffed596d6fdb3610fe9e5fc16258266fea9a01c350288e87ac0dfa9a18685cf4c33010b24ddbac25d1a3a8ba4691ffbee39b445154ec0441b16135d0d4b2ee8ec77b79ee78ccd9bcca0812ace2459a934224499e8ad92a4fd784a32f47083e55495029e649c23682b22249be5c936c11a3b17abc396d1395745910eefdf889cc04737e4c37829558bd12e93423784bc50a67a4588a552d7f22df7c80176fd5ef373efb8283c65bc6d7a0d9f423acd068a61e6f63103c2dca7426378067ac10e4b3f0a9055b93026bc92570c8c72499c8ff1a52d7709cb13cfc460bc19c2ccad32345f1dd9f829402b322dbfda57e58704a8ab9e7085ae0aaa0024b5a6054844f9e3c41e742907c2388a447b5bfd08271943a229058a5f20f38413905cd192951c10462db420983ad97025d5c8d27f8f27cf2ece5e5f99b8b7778fce1eae25d82aadf7e4567e8e4b459f735a3052d96886a296996b12d99bb925e8f5f5dbdba7a81a5c4f3b76fc71f2e9e5b41bfd482d04bb605b58b1d9a56b3351125da12b44da5c2ccd80e958c0bb4c9d21de125a28560b1dade26e5b02ac968993bcb5ebdbfc47fbc7ff6e662720dab3d958b9dd486e6a4048bcc085e72566d704ef229e1917a00c2de50d231f442920db48b4ac1ab994097d2de97323f869b1528cd72f402b827bb0d19a1555aa235d999cc919f1c9c68f6813784631925ca247143927ede47f2515b1e1b932768ca58d6bc069b8e2194102b08620be572b165684a801a6d6996c15774cd725273544546730a21a456c3e97c0e762a1393d443f33c6a9600bf706cfc559379293aac9ec648e7fa50db6fa8f265041f25e8463b65534d333a438baa40334e524170a34e033fc3daac51ad05042ee1093ad601adb51b242832cf562ffd381a387e00133d536b29ebd4eb21b9fd9a282342fd804dc29ca9a724315aca07472ba50cc4659a956460e2cd4a7150f4cc0d9926541ad5fac3e4246e130503c523ea840a842d6993f439df027c0991624c9a24e62d668be8d8b1cd60e0c96cc58795544044460ee58d63a6b6471a83f5d8b1f189f186f38a16f0266ae9a39de399cf3234bfbb7e8b3a8bc56d93b4b67f7b40df3f9c1f06340e4b0a6961d77160dc403d2ec836f2e39b1aa03d39ad7fdeae28b4121145431790075ea007e4438445c779d5562546d4624992c86ab7f320251a0c4e5b9229a843d14fb2d084c2eda1b2727f4a3e783efa59d49f6f2a4cdd573db9f76f4a2dbdbb563e3989e4ab72a734aa7993a0b76da698edb7f3a2e9a39443c0380144542b3b712819554f225b05c665cb078cb6a7305bd28f91b7802725ca7349585b0b9b67455acb543d65539fe06118dae8283af6b4729d93b34f04da5dc8c1f6928df91cdd5a343d1838877e95b3dd7dc1aff1789d09e68bc13694cefeae28fce078d5f35e2bd3adfdade304333ee831565703c7006909e9251e4556288540903b71b8e2fe5019c4e176bbbf7fb0d167d7338e3792c169212f4911f7ee3af0215d07de8372f83088c3fda8e620176c5f05e98243037690cf06f6bc643a8d570b79c890dacd52d9f6c985505d6ae6e4b17d259b911c8e37db9a9b2e5064b10a9cad20f6b885b17e8d0b94552b000e9a1cce9ddd7ae715335563dbf5f5f01adb53673991460c965a6ff59e726aaac89e656cf6aba21df5ecd111634d63f9543df0d81a5fb670cfb21844f563e0a8079f54906213b2dfa0693f34f5aa3f659c832997199ba61986c0ba8fdacdcb9f3d1891fd28744ba77d758696df5cf9df71a53a28b77c09c0fcbe0403cb03e0ace25c0dad9ad19c1ca7ace4346849f41c4b03022a2a39c3f1a301880c6260208806ea84d2f69792778602d3bf2491ecee0b491b7906cb5218daa9738f3d996cd8064fd3d95aa3aae471590cf9f72e58f761d27c6eabec8386b15a46cb4dc2b399fac068ce8986c81c1747df9aad439aad874825572dbbf1fe848a83d3567f6bcec8c26d43648df51ddd3de397768ce170d61d90a3594f8d978d532323d424a9eec1116e0c0716d3f9b47f0d2ba9497c10e723411f7978dce128a1dec68e704f94458174b381e97da4e9629b6ffe7c02cc6119f45a8661804667ee56430d77a8c503f49cd05c8dcbf5011049cf2018d728b7978f3a1c3dd1a01cda21961f67f0095372383a7621ca4c41eddef7eda3b38c67a51ba7eb27502f0251539f203a91d38ecae091c35b4ecf77c3e06b76f663cd1ef2ac3b5571cdeb95b9c9f8f938b10f05b15737706b53565c4f404b58d82e6029535512219e85bc7799ee0085a185876b1eb82b925f6aba255c16c52006ae66d4bcdf5453b81358a9e0b484549d83e6acf801ec484042a91757912ed34047e6ef8a9e8205e146c199c6dc16087b6b950e11782153fb9652e494ac9ed1661bb9bc6ae405797b8668585c4c3067aafed4dc978bf7ba35907d6d0098dc500d8f9c5a43f8301c6daa72e57425ae4162d4cfae3a1cb57bc76c6d737419a0bc83720e83e034c726b46a4434621f776d79e774742d149be5c307cbbe7474baae059454b095458d073f43c0143edc55f5dc93fdbf465b5ffbd461674182703de981dbdde54a8e039a5190064883d0b102da359dadf558485e44ebdaeaca3b879b6c7b55cd8980a92e30cb234b2a11fbd1ed83a4be16e70e33a5fb774d8109d37d10d4f281216dde76d8fccb9bd37033886b000a7466068b6ed994331f73c585baa73bb481ed611948875bfeeae920303433107a207e3a1a4ba6113a09297a0bb23b068fbb4752b3666051adaa5453fe7deccff83c1cdd3f113cf2da5273afbba820b3dae9628dd444d7e12d6677cbfb9acd707934c5099bae3d5023cd97417767d784c83c063480ae2d95ff64f2a75cd0d46c15b6b7104d4ffe15761e18e23ff4ce35ac35f0e55f87c33da3abdf20d81e47de7de6beeb5d53b36ffe019c985f35a5260000000005726f756e64940c1f8b08000000000002ffed596d6fdb3610fe9e5fc16080670142dd6e5db7294e00a3c9b26079293c1745310c842c53b61a49f428ca8e31e4bfeff822899228cb29baa11d1a04b14591cfdd3d77bc3b32095de431419ce62cf5139272cf63344f17e8efa323043f794650c6179e47d73ca2a9e7ddc9cf93facb2c5aa6845583fe9ad30c870c10b794ddc3eaf90712f0de09006f9dc8e93d49b19a93799e7cf4bc99f8a8a69a36a8a9989130b34f487c1eac12ff5e682d278c4623345b813dd214146528a51c7118a15b314043f93015e4c805014d338e2e6eef66787af7f6f61cdfbdbbbd987a287ff5129da2e7273554b90cad7c853a272405e27cc6c902ed0837f1149640fd7d3699ce2ece0bc41715e29bd8df151a0639636051bc437e1cd32da929f7e67af25e624daeafefde5558df7569e7c78cf88b1d22e9a28ea4d49a5c4f2f26e7eff1c5ed7905f67d433113471bd9d2a9006ad8f8b282bad10e8ad2651fe2cd64f6fad79bc96f57b7975dc03ff403b74cb6c1d60c7f5581bef653e90d00418921604e42ca088ab814d5a3bbc5e93fda45ac05cfbdd8a5f71ba03fb523a993849ab76ad6ff6ca7f490b06c1add88ce17b0798a4d09f10988f03bf7b328002c0014b672023c07ab28250858905b330439629bfa68196d6083b172ab02cc2f1103c9495d51cd992b96a7cd97920afd6aad69aa2f28462bd240d024e444e9a3f228bca71b18f1e13ba82f17119681cf366002bc5a209aba684b50000e0e62027fc1a5f95aae58909880a965e619dd94796b34a534c90ab157fcdb0c6dfc385a483ee694af6a06f945d4700a81533805f92ac5659015118f12725cd14e2063ce29150a417c40a0ad0813391409e94245021e11a65214ac48708f22501c98780071a3b75712e89b3f18c920eb06042f818e354e4832276c281fc0d33d65e0524c73fe9450196779c0150be3f5ca4f394dd0252c9cedd6e44c6e817bb283b285f44f9a0b5132a6dc72d0a0044bb779d2c66a82e0086b375bdfd957f9505f5aa3558dc1fe62014c641ed25fd4a4c723cdd226225b65e63a9fc75180c21cc8ccb094a87d352e8d1dcac86a613a4a3ef283bff20806745aaf188150d241790a3319a35bbc8ce9dc8fc78ad552404382735242c8f1672649683040c7c6b0e4c71c94d41c602e843f569b037fa051fa5998ab6d6845cdc7d8a76408a7ca159f933b5b26186a2f09c7ed403e447bfded3f30a0ad9f690c64b329e1d0fa65555ac6aacd73cd3d5a0c8954a9badc719ec6511241946306c956cf383372242a672031c3e81e690aa58a49b9f0320a41d2838e6f08011027e7c3c4e71e8a9e115100b690d46a3502322a4d89446eed16a8d79c6056276a5812239b560f0db4513d59314a5baab512e7c3be29e0ee61c15ff1a939d4a4390dc70f2dcc5be976203a80bea195bf53e8b44de47adaf53c4d53055cbd345893643925c823223114bf5ed47e4cd74aad6b65d390af8f24cd3dd2d8150d0595675dabd246b90b7db0ad3eab5ef3ba26ec59afab9fe595ad042ab77a9e1ec0341c0e5ac1e0b89d744866251c70620153de3ca9ad918da76820281387425858741ada97ea715861370086f5b481ab84e49460f2b859228a8776221b343431c48866104ebac3415d947c720c0e86bd19ccbe8f3a123cd850c4e25312893dedd79b2580f4d086085bc7aaa31bcb33fbd95999357492d09374ae383bac66142e2c7ccfa976e3e1f5c3cf32c2f8f1b08082f22c0d560bdceef072dcd6d1dff491c22dfa19d1daeceb699c4684b7770d58fbb4426cc69591b9ecce2e72550bdd2ddc680b1e38deb19d0c21480dd848359f2a8c9c2f3e0c3a3b1c9ce4fc63bb9caa0b3d45904988ddd3619446d9aac32ddae15ddd9316dde56e592a64187df5f427f674a1de71fba0e5daafce7a16eb5b0ccb3dcefe539d195afbb6fdd728f817a3a03b088c5b3dbb1fdb09a25df917043a110a170ca084bc78820b9a271f28feff0e3da4edf610eeedbcf1beae1b7777dcd8de6de3be4edbe8a08164d95d868c2687935aeb6a8b60d18df221cd46b164eff9e8b0e253dc4498ad6f13ac0a4ed47927a1cfe75f4a1c5a3d217850380d35ba1afc562fda48da1d6c756fdec2ca036f281db7fd9fa84e2f3fad737e8ab6075e300a6d3bfe41512afd78f40ff51ea761381d000000000e706c617965725f70726f66696c65b6041f8b08000000000002ffc554cb6adc3014ddf72b6e09149b199a164a179aa6d05597cdaa9b10841fd7137564cbd5236e08fef74ab23db6fc180804e2cd8ccf7de8dc737c558adc70042d8cac92122b4d48cd932794b496a26036f4fc0eec631482d239218a1d2b94070f1692619507c5e37f5a26557274a92ef7fa1a1ac639a408c8f4034ad73187424850c2f05418dfe88495c76e3d07183858c4a1b60e7e6499cdd5c0b4425e781a5777126d1399213d4a616a5a6299a28cfc0bdc40526ba168212dad46c8132122fd839925fbcbfffe7469f1bd6fa5b43499ee8fbfed4f7f48149cf0a957c23d0dab1401f3f5cbfe0c71a1142e41a1692638b7c760be16b4657a82b75e2ca84dca590685a980554c47e79ace1b021f3a1bbaa278c28ca3ee936892e7d24edf6512e25e51292a8aa84b880fe72a5640f41eff31a5d5b760f6efd1a4593c3dc83da57844aa45148023cdfd020f757d5ec4476d3fed578383ca9be150ef4b699df22b196d804c546a0f4b8fa26e0762ef95c44cc87cd81c6a27593ad7db301e6b01ab21ddfc546248b2bf86d9a24df926a60f1b7303a9905234f4c8459a705a1abdeeec64beb0c5c79091ed7839be5b9f64b3bdf379d9d4a33bf8fc42a9dd77f142ad679bf7b6323b321b0afbd06e41fd423fb7226bcd3c3ed7b6bff17e336cdefad6bbba7bb42ceee737a00369384c14bed2dee8b3e3315919e815fcddb81c6734265e2f5984975e27e9ca0e84d7d220f3aaa5f3d450fc8b4bbb52da59b3f5218e056def5cfb1f1dac4b9942080000000012746f75726e616d656e745f6d616e61676572d8131f8b08000000000002ffed1bfd6fdb36f6f7fc15cc06a436e64bb3ad7738c84970b935b70fa44991b837f48641902ddad12a893e899ae705f9dff7f825911429cba9b3a6e88c20b1c4c7f7c5c7f7452623719562444955e45186731a04cdf7308bf268810b74b787e053951895340e02b2a409c983e0ee06a7f311bae28ff76313a84c16392eec97b448f2453df3863f6a33a3252565c841e97a89c3249f13f995b134dee390cf9fa3cf7fa2b8a421c9d3f5cfeaddbc48701efb64a9f284866c5229c839a0a3384b7249a3e1665ec0f08a14ef40f0e92f78461bc1f9638b7d4adee13c14b025e3011e8360c2fe34a03add825479acd1d5c7049ab0c0f3d23d5950932b552be8399adc023fb319a0a62829514e288a2a7a4b8ae477ccc4464b5ccc4991217a1bc1d08cade1219f3d237949d1f9e5d5243c7b33f9eeeafafbff9dbf0c50f58f17e8047d396e2830ca0a3759e58076ba067498f158d8a8ae7ebc3cbf5658be6ab0bc262445590560538c70b6a46bc61c7c9fa5382a706ce3397ff57af256e1f95ae746e944b1b44ca375344db18de1f5c5d9dbb37f5f9c2b242fa4d624c8e4eacdf5e5d9abf34b10ffe2fafcece5dbf06672763dd174703436d44c0dd2f32a4d0f3d08fff3e6e2a2c6f255171626c02f24c999003e6c4c981faebebfd485f9f26b2fd6dba844515ae0285e23307d1cfbf07e7776139e5fbed4047ed18994f15ad2a8a07e948c555b8b7f6fb6f3e41644861f663c625709b35c25291807b76d3e0688e7c9a22a2266ada8c49482ff00959302459a0528b4116c70b06c1409cc494ec1e6a319466019e0d6d8346a8a3303f550f69ae86435009093ca05517c73261704d073e06f240a21c7b31215b884f9335c8e1ce360e92082104e0e90b994354d31df9635a396849fffa450870bf021cb30c3d9141703fe001af6fa2f41fa5b063614ee131c7305cc34045e260580005db6c0eff05ac600f6c9a2dfc225d760c9d772648ce45516ae923c6f8fca3921336b1c5b839aa7667f02191b1a00cd4a321cc14a082f0136c0be45b59695d3ab279618ac268e8a75c8fd3bfc8e0116981371eb583e9ff209f77b8fa4d96faaa200e1ae99ab77e814a41343cf8e9e71f94050beb9f267f5de426bdc48056a06862c25f240d20828bf34e30be037cc78c837157cefdc8982f5aac0be5dc22d5f04a4cddbe531adf5869171a83511d6c69c6880a610691a5d0070c8bda03e20f520f1ff37c12b178d1959ae47282ec87204a004f473d7730b6ccb4faf9d3113a6158ad5f7ae7163205bdb4e631e7f7b940f6056041ee9d387809e4140b2984469f2bb08342c8e80a301337d2f023b92e0f1d680535856d334994186408b35243379a30c1c36b63870d9a7f40b013a10d9ff1646fcd0a0d2edd305dc50f7082e610037bd851c1b7c5dde08e6166ee41b677fcc414da6f6802692396848d40c0dc7fa56948be45d1eb7441fc15205682019522e485fbd94477b5b088e13228898c8ea383e3124f3411b7828b34e858ee7aaccdd031ea8b2008d8a3b7c029685dcc043562e8bc2a683c532851ae92cd742293abcb4ab89b187e37616763a38b0f8d4e866e457b6f4a6e11eb818d973bbbb3ad7bbdbb3bd8ed784379ab12be33b6a83746ea0cef4cd7834a6dd1bbb66777a1219405b4946549f4769e910430bef0e88dd726ce49a6d7655f877ac869504fcebe83707909161a88e4e45e7ff1c4c3ffb6cd84bb0dedbe4134a3feacf0f8455924d32b273021f57fac1b69633f110dea53b82f96b2131db11e2865041febf02a32cedad3feaf69916a3fea44290f626122d562d767be404bd58792cfd05b2b571cc1b84a70f556754421791ea52409f49f8d081c3538c3b266a0eba7b2acf2f6288cd53521464152e52328dd230aba8332877e2a2f1a119ff006dfbdd17aca3aab7015e41970a948ba3126b0ba2f5788300e21e352dca91f9083ac35d58d927e6845f313daba69cddcbf8949cf0409c910cb94b5960634b098b0b23d6b1614083fede031c8498ad6d76231766a404c460434aa0b93c277f03b3f87888af6bb875f831afdbda37f7273820235d1d38362c07183ab32073935a27337634d88d3a5b1ccf226847178d72ba3437143dac9e1ab38a3ac1bb5687291d5122c7fafbe2a6ec9fa381c207a2b1d32a431b626c848494c3a195368bd089a0fe6a9cf2bd55483a525a3b906c1f4438dff2b815f8ce498e07ae02e0d05326f924e135885314454d30be1d317472820e840aad9801260b47545cedec7ce3cabb8eaaf7dcee362b54d75c020125ea15d530c8223abbcda277e097ea1e025440b2d150e5699225d047874629c924c469d3f786634b05811884daf6c0103b66969a83415813ad2c0ee11c9563648047014a0e315ac10f3ba2004da81a989d0ec1e271ccf65ee3fdfd30c72bd1c23dfe16e49ec099f769e344d4ee7b58aec6d6c866d7d1bae900d92e291ef94a50999a29e7e2728372073afde0f8e1c9a1b1554524efcef2b870a79bd345a3fbeec4a9ebe2b40777624f49eb3bf10436a1268f961ab3813c3287a3168349cdbe0e745a2353169bad81b9d942f8615d2cfeb6e95ff90c987d4c6ac69041f9507428ac9ea9c386bded560784b56c46a7c3dd3b3cd00536b46a30abb5435886afeeaa684ad048bbe48459ced75fa8cb16ed8936f7c6b3594f5c31df05c64256bc2a64796d44e5f11eb89dfde69c941fd569a512e0e561c2556436e579699a675d67edc0750ddfb374fcd06e46dfb53bf238364a6bbd5882b2d5723171fe5ab20fb9643db61830ef6c807d8ccbf474b4ed84aedbf4aecd94407e08291c5b924d81558f74cd02995e1cde837c46aa3434af84fc88518ec56dbd98a092645811de372a84aee0b07fc2dbf8ad3a4084ed1843039f401e0f33944c9d31bcaea59d617c43a43260b545bb1f9b976f7e4df0ea6757816f601b7457a04a01b5a57b72d28d495c9f04aeaff09b455418b4b46283a0a2f9fa21e5d47855523ea566e119775aec22c72d4e97ac187b42ad36cda9f40c5daa0ce7cb12f88ec9754fe66b42b41daa817bd8b8c371abbfb55f8f8ddc9747873edfd9bb3fdf4f50d3c13f58540d4d5b586d70e4bd826b5518bc5d4343761d585671ecac5c76d845f7dfcf0e3ae633b492c60feb6457911eb5ee1f6f5a973ab68b40dece20908f13c32f6ddd1235c97552d9ae21fa279e5c3c056ff790cf7604d8bd486631fc7272f90804de4b828f7891dbc901bb717f492816d7e1a16a67976da1c369f748eb8eb3ec9ed7c90f6b3c2e2be86cb34bfaeec6eaa12b0de9e379f42484dde9efd7eedfaa236e39698d2b5f3af5c134d6dfbbfff97a330f9d9f9ceaac8b644fcce034ce9e9ce6ec02d67b0c5bab4e1d6aba2eb777e873d46e1474d4193b3a0bb36f666c68176c6c156cd3baefae86344c2e45de755df70d5cea39ecbc4c69dc30ec6a7198d3b44b87fe4e47e7856637af9d97363bfe1dc15b358edabd89fabf14361f0d58b7163b6af066debddccaf77b7f00d72f1c29033b000000000561646d696ed1041f8b08000000000002ff9d94cb6edb301045f7f98a410ab81220347b390e12a4e8d60b7757140c458d6dd692a8f251d730fcefa1285aa4fc4210af2c6a1ef79e11a716a5a910b430b2a135363acf6959f306f677607f4621285de679c1d47438a1ad168a2ca54dd80ab9b1298c09d3e5ee17582d3358f05583f295b6b4e015d7bbc38d5c51fc411652e7eef15548b4494356ac2ffc27356de80aa50f5c4a8e4d398a95826d484b5b944431ae9490d36ba1bdb070e28b7ef9a55169229a6af7fb6a975611d3704dba50e5139596866978e9682eb4f5036baa6083bb0c4a295a0fd8453a5a84d1363f2397b9a8435fb23545c559d22b4861691a50a84d4bdcc8485f2729b1adc40e650e93fe248d7a55a82121129595cfd0a76491841466308c9349a41a43b87f910ce5badfb15f363ab51f4c372a52ec2c946452dc3bbe113670a2efd3212b9d8e547a4f8edc2cc6b81ff509ca43ff43a8548b7f68873a40c9e2babee375ba2bd463b669ee1b5a467f0db7602e2b3b37500829c596ac2a51d0ea31243d25cf814984e07406dee796eb7567d67f1ec924eaf22d9ae2078c45f7486cbb3cef313aa765692daa1cfc9f603f587d78809ff3eff31c7ef0ffa0d7080556629b01d75f1514526cb0896323327da5d905ca01c3f965cff313f1de35edb64ae7f08281110e2be2452953dbd97572cfa3812b783bae258726e9b7d263584e4fcf7dc0d0e1ed13a8ad6051135fa86f34181f971f26e0de5f1ac3ad898e2eccd8d8f1c997b725bc9ed86b72e235bab331d8b355d9d3b8b2a7c85248b7306f2fac1b0b6eb8be87bb776b557c28c70600000000066576656e747383021f8b08000000000002ffbd51416e833010bcf38a957a01951710c4adeab197dcaa0ab9666950c06bad6da2aae2efdd182b0991728d2fb66766d7b3e389ba3022780a6cd484c65715ceb239f8cb40567008ca7a726dcfc29f888f49b1cba2a0e7014db769c0a48fad5516b9757a708e38695f3e63e557bc38cf417b7897a28f19f9edccd4f6a08ca709f615744c165e45468c0d1c94034df6b78c78b9c2c9e379fd489b56751da37315a44379a14f8331c8c2cca8a5b24e82e6aa18c93d162cab7f1bbec741e7ebc805f4c1004e836fe3e32443d4f7bef327192c6ea28819cb2789b37c9beebeb991dd9b2a374cf2b305570b576c2976299e25fb070a97bfc649020000000012726f636b5f70617065725f73636973736f72b4181f8b08000000000002ffed5b7d6fdbb819ffbf9f829701391913da4577571c9ca4872cf1ba6c6d5c24b91b862210648b8eb5d8a227c9f1bc26df7d0f5ff590a26435696f3760fde3ce36c987cf1b7fcf0b99254bd70b4a2ab62ef26449f36a382cd8f42e5e252b5ac4e5342b4b56904f2f08fc5b979494553a1cb25595b17c38fc744517b3908cc5d7c7437b5299dde6b4707ebca7d38ab93fce9372ee2eae8a2cbfe53b880f215957b31fd10ec9aa62653c2b80e50d2bee80a5c93f80b462c965c50c8ec587069d8addd13c96b3cae1507c85d9d7fcff6af2ab57623ed653922eb3bc268587e83dfcaff48fd59fe3659227b758470df2c3e12dad62b4846d726e17a15b909f2d15db72c04fa960eb3c6d1b62cb3636b94e0c8762ceacc8689eda5c2a05ea5fd4cc57f08f8c2e2fc797e4747c36bad23f920f8b644b0b9295246715c97252cd29b985a52fc59429cbcb8a8c3ebc3bf9fbe832fef9e2af17e3bf5d0cc9faf5f7e498fce1d025039e23e84cd9729955154d49929364caddd1a277727a7d3ebe882fc6d7f1e9f8fdfbf3ebebd199a67a50533d112b49caa824bb4caae99cdcd3229b6534f5513c1b8fae04d9f727d7a77fd624a39ae4358827ad45564959028720f3720d242694332bad6791e6e4c67ffccbe8f45ad3fbaea6f71654a5b50752af1614a4c6abdf9ebc1f69413fbc1b2141bfb7b9e2a6af39218b0c3408ecf19f31bdcbf1f8bda0f7ee1cf45653fbc1a2565043aada30b212e629a57d815b97e8f9c52f27efcecf6265e7d3f1cf1746d8d7ca850002d6d30a5b7aca56db90a4055b8530ca604f894bea7c721851ba905b299f88a5430c154e1d490c3a5afff8e64d88d703d399f61ef3bb367e2f22499a16b42c87fa433d224f937ffcd192f712d0f70307df2b89bda5b0788bf86ae9ef3e02353882531adfc2615fc54bba9cd022105f40a5ad6829f1f02d9f36b8c15c984defe856ed26b7462a97463e182a1385ce40640f1856053636361b83a2477c046db0c9723837a02ea56cc9ed918065acf6052b774db375cc37bcaa920a3b10c7a0b8e43f0e890a3a8e406da36cb56239c7e6eed57d1cc890da3559c9b35a4f16d93490b83c20b375ce5d2b56c72f2e6805b80ccc04c845795421fb1293b0839a10d3eec52290748cab7d5b2c21a60dcca05afdc63ec48067924715e3b8f7d681108f04030514c205601912c1ac6d06db464455d404e9d0a307771b8e656a51093b089df0686dd47ee43dc26f82fdc6a6a1add1502b707058db0b6246517d13e8942b2be3922d69b08fd918844d9c46343c5c6b72f45f5501be16ec2fd7f61cb45cda6b389cb122a6c9740e6e35b3f70fc903fafa802c6a6dafc484ede544a135fe4bcc66012280f6d6eb7540391694a40d77a81b6fd949d1ab8ba625b035b44a1634bfade6c1be9e4d8e21f887fef886fdc866228e800b4d72c556f12499de75b181961e3c6129873a582630de369505eb3266552ccee946293bd0bb0ec2967551e7bac859f7e8e864c9ee29ac3c4216d42785338d6479f438e83259edf4cd4fbb7c0f286384e590ea1348d608c442b8818e7848ab129850f0e70ea7a2afcadcd500c7079887e46a10f3a735da7f73081d81a3e046fad235d900bb6190d714525467aa25523df4d80c4e04e0aed80a3d4ad6152bca25ea5024237023b8a8842ce6d99d891d10080730f0cf7506735c47462e3e6145c136f1ed824d92450ca7427916deca014a1dadbbb04ace710343106b008f2df50c0c6a49f8502e144324534977cc87db70ccd23b66dcb688cdb719c24c663322247fa98ef84bc7318f5bd8f739606c65351271306dcb6ef8dc12ba28e9534846ad240f3bbd4e1c81ada6eae42a9e4cc8ef8675405607a9f6c47a8c33c69766ee1499fab47aacc522cada248ff6c9d05a08eddd0696122091925440820052064100b015e49d30b6081ba9b54ec6423799d60303acdc865a7d99e67f41c120ac14af21952bcdffc1e329e0e16390c3463ba8b8e0a1bca62778f87dbc15467a118f7a1077c4d60748f75b6c0f1878d25d1138c1729fd5bc6b732ce322ead0ea33ca5d03727228faa7fc07c163b02f48d990e1d092679504500b53830486a80babfc5f304b40dbfa147dbca93f0d1cd4b994a8d3e475c81b8c853aeddac79cf235cb17594e05ba34e4aa4b642e5f5f5431b0b01b106c08f0e99a1b1326af1715f452387faec1701d7bca72704795fb6976006e2a861501bf58dbaa5d514e0f39ed518dfc8adb9abb07f9c9577299a636ca38350c412ecb70e6aa083a8ee24903f9b2813709e75b4a5dede45e4e03e6c58767f32ea878ce8bf83d16da3e6e95c55e06863ba3fc888bb6b4985592cd3c831b920db4a9992707366d856552dc2968849dcb401d442f7786334b9596ff2c287487a17bc71991ccbfb0aa240e1fdd0149860d7986ba62841f310c19799701e5314fd14c22d146cc4e55dc5384c8065ee0315dc2fb8c6e6edc9c839f40bc41302d68028ee6a91a4a4a53ab5c3063c8ddb45308323476eb3187ba24da874f143064ad1678d16920b3b1cfce45bacdee748a70ef30d8b722b55b4a0e2c27dddfef4d2a6a21d55b4bcdb0fa9b519253413f43475e4a7663fa17d05357bfffb9bd77af1df88f32c8e29619368061eb89466869c519b29f5e781b50564af8c2db6bb2123b7f1b02a9f6f2c395548b6cfeef52b2f01d81a2cd2a055f176839c29e10a612d462554a0a8105d92da5d1c05c06342579d36a18ed9da267ec51c1a766812005c69c84cd494a72bfeba05ed1632f58d714d76560572208d0dbc0a1becbf9b208a15bbd1d7512f9c6297df4ef0f0fdd33a3975ecd3ad7de21aec3ace454f705f47511cf4e6dd80a89853d8880d30432aca0f64f4bedb67bdbc8def660e02da950a12c8d4e8eedef75896cd554f89acdb3c87075d8b07cbd843f2309267b1a8af75a2a5c3ddf2c801f8a8acfe7b66d70d29c36f09d2c970b33bbbdf46ce3c7c4db5d1ca189bd7842f3fd5cf9ee4e5d584094bd7d0635cd12ce9ee8dea93a02fabb17aa7124bfbae1b6857edd17973fb42f7b744a5d8ea61cbee49b11280839b657d0021329bb2a140146c4d7fa414459d124256c862a0c4df17a7c369628bfccfe4de5cb89c996a7fb9c2ae4cbaf78aa0c212b859200ba1a4004d5a4bba28e2e5d9352df9c057d5a72fdaae72eec5599beac8d74beafbe397575576f4d51a9efed5091e96ef1203e3cbbb2742f649e5e14b7b08d55f1dbe13ab0551dda22b82d9f1308aa1507ab5bcfd3240816e0e7c52603bff5577c40016ead4743722d1e0aa9fe517d384241af3e434ee764b7c3075fac45d4e6e43a55e8ee1386beb7599e60d52f4db19649a83a4077d95cfe4d56cde394ce12d0829dc674563836504ef6b2fc3e5964e95e5843d429b426ce49cac804108f163f791bc63563d193188b7a33e6ddde303b9dd3e99dc067315d744fc0ab6835ed6cbd19bb7fbce96c7259f39abb9f692579d21f6eb0f6d6b9ef6621224e1ed9b202b6af324a96d0431267690b2e55cdb98c567661fce6585baad9af574f0bd6d02aafdf169893ac13bdc327ac8a5a320cc7cda07e63f9ed624baaed4af4e5004ab29cf08a866c92ed4fce3317b0351ca03dde9eda7354c8bb556250f4ad9c51fdd4998fab96d69e938c2175897da0fa370e7e2cc93f4d7f513ffde9be6953e98f9fc5a912f5abdadae635eac7abb490cd2ce7ff7f83d367a9f56bba8076ed2fa5d85f9fd7679cad2fea059d4debaeebaf6fdd8ba0bed9babc68faea29ccd37a24a8197150ab8e7705ec5e444b2b0245c258c77a942a783baa6d6d596fb4fc4caa9187eaaf12b69ba10f4e0594a3d6df35a4f22a88a7d324cdd2fc5b9115e7044e460905683967eb456a85f8b68bccbab180f40e07ced59a7be0803b0a39d49a17ff3ac71572d98d80b672cebdbcf7b1e1d952a5fd075cb4922f523f44e6af3ff462bb5be53e33fea8f6ba691c0b3d14dd74f018f5e03172793c781a8f513b8f074d1e1bdc885c8f9b7bc7661dbb98d37ce37f10d08583e8a99ffd14c3bc08e280abee27da9ff7b9971d8d3b2674a8457bbbf93a0c31e47d1bd2c190f5fea8fddd91fb6e00789c30608c5f2b284acd77aac96a45f354c61db1a0f9140523c29f201ce66c13f22be8a4e0d7d0a2c9c478ddb95e0a1fddb2b59230149f37495e89196bf88fd41bf9bd9ae1e92f7a547becbc14edf50a503788853187e53cf92e8e7e781d0819074e1cf677e9fc36ddf5f0c7dbab976d3e44cbcf55ddf76e68a1f9c6d9ff675fd6b42f24a6ebbfbe063938ae74da81fea313a4176edd1e31af11f25c43abd7428dc6b90f29fbecd7b829eede10f5a3bd1999db4a577a7b7cf11f7bee4432d93a00000000106170746f735f746f75726e616d656e748c091f8b08000000000002ffbd585b6fdb36147ecfaf603b209306637187611864c768b006d91e160fa9f3b00d0341cbb4ad462635928ae7b9feef3d247521255971dbb4468058e4e1c773f9ce45def0459e52a4782e18d950a6a288648a4b5cafa0fdd919824f2e29926a11453c53096751b47f4bd3e5004dcde361e40bc964c5a8682e2a91b05571d23961af34226a97519cb0252fbe6a1d9a824b018b5b2e1e4097f93b1a83d253f3bf29a8f80365d8ca4800d48f5134d3ff46b5519ef18b4dc2469d5b82c70f3823191558c689945c542eb883ad3ff4ce5bbb216fe0cce1184cce16dd5bf577bc218cacb4ff8ce0c5c505fa93e788088a185788e46acd45f23f5dc079b4e048ad893292316752a1ebdbe90c5fddcf7e9ddefdf6d7f59b08e53ffd882ed17054a1dd334163be6206630577227db10b717f7b77fdcbf4e65603e09babdfaf4b9457955268367d338d90ccb38c0b85244dc1cf10604418328e449605461c629fc70a5de9c0cc6a72ad89440f74072443c50770aff4f945a27945d2020a160495521b0c7e1b20c9d19682edec5b8518b59e300e5dc32acd52bed3b815aa01c105485490765c3c4f8cd8c1dab5cc194a58023130b91158302a22746ecd091d651d412ca802b3c0feea4838ea01ee90afaf882a7bf7be099044702cc3d61e2bedde5749a754215708225700aca8f28f378f0578e0f0b2745a08086d8646913629212930c9291a789ba87561615081eb4fa9ebc05b2d2b43ae963f07f3978625a8a6c9cbd0177f8587c36163a9f15c5629c93734b086eaf436a660be0cce5d17840ebeeb8d2e7bc1ffaea1ef78c2c81c787282956da7765fbbe18fda99555c07adb4d97bb80d7297a633ce6810569287239615e75caa7ef3b7a25261ced2dd3f6621cbe76912b728bce4026bc91319fc44b6b81a1417827e6267ae954dd6c6244d9d0b074d2f54b425f1bf79025f7b9c48a4a4a2c02f808bdcd59f3917826ff12ae57392e24daec60da449f0baf667f8bda708648d47456fd32f108e93574f580bee2dd2fab3ad3b5a157ac30106e02c251036dd66b16e2175063443d3c3ba2a4eb550011ba14768275c8c6d6f1f9bb63db1a5fab4a0b65574586775ec2a74835283a3d1e947fe8a6ea836cb46f6e97470faef67b40ee30a9be147da8586887321f4a2231d74349c06b6999c9cb43a86eec93d819b2c51e0e90cb0e5d839ee1ceb26411836ca6fd764e852a4831a3e4506adf5be4e515febd8d9de2e6ef7379c6e80680ae352a391ccf520d79efdea53fd355a112016a35b1b83b1f6d70cdc396917eb9e14089f81c49f48e138a584c1749509fa98f05c5a3bfc59a17336ea4f838a51b5439c02fc2c1cec9c541ae13882d557097f803f47d567204dc2d28451439723de769d7d2a63f65faa52b841f2615f5ca2d7c3ff86cd407c812ae8c23f0b59aaea11450b98de04df61029695f1e8658b9f0a9e4b1aaa7692e524c2d4a431df5a6f511dc9efbc9d9d503d7490ec3987251d2f09dd8525f17e1eb96c210131eafd51474daaeff446cb8f192b1d95ac375ef8cdc5d7f1fdfb561082722a054933989efb93293a3fef30ecbbf29455bc79a8f19ad6f81dc27dd7b1113d9c7d00ad2a03c58112000000000500000000000000000000000000000000000000000000000000000000000000010e4170746f734672616d65776f726b00000000000000000000000000000000000000000000000000000000000000010b4170746f735374646c696200000000000000000000000000000000000000000000000000000000000000010a4d6f76655374646c696200000000000000000000000000000000000000000000000000000000000000030a4170746f73546f6b656e0000000000000000000000000000000000000000000000000000000000000004114170746f73546f6b656e4f626a6563747300\"", + "[\"0xa11ceb0b0600000008010008030815041d02051f18073768089f014006df01060ce5013900000101010201030004000100020503010003060304000107050601000304020303010305050a0203030300010501060900010a0201020a6d6973635f7574696c73036263730974696d657374616d70137472616e73616374696f6e5f636f6e746578740a72616e645f72616e6765106e6f775f6d6963726f7365636f6e64731567656e65726174655f617569645f6164647265737308746f5f62797465734b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a76600000000000000000000000000000000000000000000000000000000000000010a0203023a3a00010000021a0b010a0017060100000000000000160c0611010c0511020c020e0238000c030d034507340c040b050b04160b0619340b00160200\",\"0xa11ceb0b060000000a010008020804030c1a04260205283007587508cd0140068d02730c8003ad010fad0402000101020103000401050700000600010003070304000108050100020906010100010a0700000304000108000d0603080008000303030303080008000608000a0800060a08000203030103010a02010609000207080008000d746f6b656e5f6d616e616765720a746f6b656e5f7572697306737472696e670c737472696e675f7574696c730a6d6973635f7574696c7306537472696e67146765745f72616e646f6d5f746f6b656e5f7572690a72616e645f72616e6765047574663809746f5f737472696e6706617070656e644b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a76600000000000000000000000000000000000000000000000000000000000000010308fa000000000000000a025a5968747470733a2f2f6261667962656963783469356e6b7a666d6366643473377364696437746c757335686e367434796f67347a647377363376626d6b6178796e7366652e697066732e6e667473746f726167652e6c696e6b2f0a0205042e6a70670a020100000300000245060000000000000000070011010c07070111020e070c000c080b0038000c010d080b0111040b080702110240010200000000000000070311020c020c0b070311020c090e0b41010c060e0b0c0c0600000000000000000c040a0c41010c050a040a0523044105290a040a0c0a0442010c0a0c030d090b0a1411040b030a060601000000000000001723043c0d090a0211040b04060100000000000000160c0405240b0c010b0902000000\",\"0xa11ceb0b060000000d01000e020e360344910104d5011605eb01a601079103f1050882096006e2090f10f1098e010aff0a180c970bb7020dce0d060fd40d0a00050106010701080109020a020b000c0800010d0200060f0600051006000113020003160700011a0600011c0600011e060002200701000005220a000427070006290800000e00010108001102030000120204000014020500001502060000170704010200180704010201230009000124000a000125000b0001260006000428040d0100062a000f00052b111200052c130400052d001400022e0c150100022f04150100013016040001310002000232180c010001330b04000134160500013519060002361a1b010005371c04010205381d0401020b0c0b0e100f1014110f1114140f14141814190c1a0c01060801020c050105020802080300010804010c0305080509000b0b090108020b0901080308020b09010802080808060c080a08030b09010803080701080601080701080801090001080b01080c010802010805030a08050a08050a0a0201080a02060801080a010803010b0901090001060807020b090108020b0901080301070b090109000106080601060b090109000106090003060803080509000306080306080509000a6d617463686d616b657204726f6f6d05726f756e640d746f6b656e5f6d616e6167657212746f75726e616d656e745f6d616e616765720b6f626a6563745f72656673066f626a656374066f7074696f6e06737472696e6709747970655f696e666f0c70726f70657274795f6d617005746f6b656e04526566730e436f6e7374727563746f725265660b6372656174655f72656673074275726e5265660a4d757461746f725265661164657374726f795f666f725f746f6b656e0e64657374726f795f6f626a656374114c696e6561725472616e73666572526566176765745f6c696e6561725f7472616e736665725f7265660a6765745f7369676e657206537472696e671670726f70657274795f6d61705f6164645f74797065641970726f70657274795f6d61705f7570646174655f74797065640a657874656e645f72656609457874656e645265660c7472616e736665725f7265660b5472616e736665725265660a64656c6574655f7265660944656c657465526566086275726e5f726566064f7074696f6e1470726f70657274795f6d757461746f725f7265660b50726f70657274794d61701367656e65726174655f657874656e645f7265661567656e65726174655f7472616e736665725f7265661367656e65726174655f64656c6574655f7265660f67656e65726174655f7369676e65720854797065496e666f07747970655f6f6605546f6b656e1167656e65726174655f6275726e5f7265660d707265706172655f696e70757404696e69741467656e65726174655f6d757461746f725f72656604736f6d65046e6f6e651864697361626c655f756e67617465645f7472616e736665721c616464726573735f66726f6d5f636f6e7374727563746f725f72656607657874726163740664656c6574651c67656e65726174655f6c696e6561725f7472616e736665725f7265661d67656e65726174655f7369676e65725f666f725f657874656e64696e6706626f72726f77096164645f74797065640c7570646174655f74797065644b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a76600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004030800000000000000000a0a020100126170746f733a3a6d657461646174615f76317a01000000000000000013454f424a4543545f4841535f4e4f5f524546533954686174206f626a65637420646f65736e277420686176652076616c6964205265667320286361706162696c697469657329206f6e2069742e010452656673010301183078313a3a6f626a6563743a3a4f626a65637447726f7570000002051908061b08071d08081f0b09010802210b0901080300030000083b0a0011070c060a0011080c0b0a0011090c050a00110a0c07380038012104250a00110c0c0340100000000000000000401000000000000000000701110d0c080a000b08110e0a00110f0c090b0338020b0938030c020c010529380438050c020c010b010b020c0a0c040e0b11120e070b060b0b0b050b040b0a12002d000b070b001113020103000100170d0b002c0013000c020c010101010d0138060d0238070202030001000b0b0b002c00130001010c0101010b011115020303000100040b0a002900040405060700270b002b0010001116020403000100040b0a002900040405060700270b002b0010011117020503000100040e0a002900040405060700270b002b00100238080b010b023809020603000100040e0a002900040405060700270b002b00100238080e010b02380a020001000000040000000100020003000400\",\"0xa11ceb0b060000000d0100160216300346880104ce011205e001a601078603c30508c9086006a909da0210830c92010a950d0e0ca30dd3020df60f080ffe0f02000101020103010401050206020702080209000a000b000c0800000d0a000111070100010812080004130700011f020007230b000224070100000827060006280600012e0200000e000100000f020100001003010000140405000015060100001606010000170001000018000100041d070800091e0a0101020320020b0001210b0d0009220f1001080225011201000526130d0009290b1500062a160100082a170100092b0b19000a2c010800082d1a0d00092f0b1c0001301d010001310f1e01080132200b010809330a0101020909090b0c0e0d110c1b171b181b1909190b02050608010001060c02060c050305050804010b02010803020b0201080305010a020108040103030508040900010504080505050c01080501080001060805020c05010806010b0701090005060c080408040b070108060804030808080907080102080808090108090108080508050c050c0801010c06060c0804080408040b07010806080401080301080a02080a05010b020109000107080101060b02010900020507080112746f75726e616d656e745f6d616e616765720d746f6b656e5f6d616e61676572066f626a656374066f7074696f6e067369676e657206737472696e670a636f6c6c656374696f6e0c70726f70657274795f6d617007726f79616c747905746f6b656e0b6f626a6563745f726566730a746f6b656e5f7572697310436f6c6c656374696f6e436f6e6669670f546f75726e616d656e74546f6b656e146164645f746f6b656e5f70726f706572746965730b696e69745f6d6f64756c650f6d61726b5f746f6b656e5f6c6f7373064f626a65637405546f6b656e06537472696e67046d696e74107365745f726f6f6d5f61646472657373167365745f746f75726e616d656e745f616464726573730a73796e635f726f756e641773796e635f746f75726e616d656e745f616464726573730c63726561746f725f61646472136c6173745f7265636f726465645f726f756e6412746f75726e616d656e745f616464726573730c726f6f6d5f6164647265737304757466381670726f70657274795f6d61705f6164645f74797065640e436f6e7374727563746f725265660a616464726573735f6f660d6372656174655f6f626a6563740b6372656174655f7265667307526f79616c7479064f7074696f6e046e6f6e651b6372656174655f756e6c696d697465645f636f6c6c656374696f6e074275726e5265660a4d757461746f725265661164657374726f795f666f725f746f6b656e046275726e0a6765745f7369676e6572146765745f72616e646f6d5f746f6b656e5f75726906637265617465114c696e6561725472616e73666572526566176765745f6c696e6561725f7472616e736665725f726566117472616e736665725f776974685f7265661b6f626a6563745f66726f6d5f636f6e7374727563746f725f7265660e6f626a6563745f616464726573731970726f70657274795f6d61705f7570646174655f74797065644b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a766000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040a028a01880157656c636f6d6520746f205448452047414d45202d20416e20696e7465726163746976652c207269736b2062617365642c2067616d696669656420616e6420736f6369616c20657870657269656e6365206f6e204170746f732e2041726520796f7520676f696e6720746f20626520746865206c61737420706572736f6e207374616e64696e673f0a0209085468652047616d650a02494868747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f73706163652d66696768746572732d6173736574732f67616d655f636f6c6c656374696f6e2e706e67030801000000000000000a020706506c617965720a020b0a4c61737420526f756e640a020b0a546f75726e616d656e7405204b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a76605200000000000000000000000000000000000000000000000000000000000000000126170746f733a3a6d657461646174615f76317e0101000000000000000f454e4f545f415554484f52495a454436546865206163636f756e74206973206e6f7420617574686f72697a656420746f2075706461746520746865207265736f75726365732e010f546f75726e616d656e74546f6b656e010301183078313a3a6f626a6563743a3a4f626a65637447726f75700000020119050102031a031b051c0500000000010f0a00070511080a0110001438000b00070611080b01100114380102010000000c220a00110a0c020a020707210408050c0b00010703270b02110b0c010e0138020c030c040b000b0312002d000e040700110807011108380307021108110e0102020100010114190a012a010c040b00110a0b0410011421040b050d0703270a01110f0c030c020b0311100b0211110b012c0101020303000100182607072b0010021411120c040e0407011108070011080b023803111311140c030e0338040c050c060a0511150b0011160600000000000000000b01070812010c070b050e0711000e060b072d010e0338050204030001011f090e0038062a010c020b010b020f0315020503000101210f0e0038060c020a022a010c030b010a030f01150b020b032e1107020600000001080b00070511080b011000143807020700000001080b00070611080b011001143808020100010100000102000000\",\"0xa11ceb0b060000000e01000e020e1a0328800104a8011a05c201c401078603f90208ff056006df061e10fd06f9010af6080d0b8309020c8509cb020dd00b020ed20b02000001010102010301040205000600070801000101080701000105090800020e07010000011c0200000a00010100000b02030100000c04010100000d05060100000f070801000010040601000011070701000113070b010803140c070001150d0e01080216110e0100021712130100041815010100021911170100011a19070108061b070100011d071c00061e1d1e0108021f0f1f01000220011f0100062107060001220b070108070a090a0a100b100c140d1009180e180e0a110a12101310150a03060c050a0b010108020002050502030502060c0502060c01010c0105010b03010a0b0101080201070b00010900010b00010900010b0101090001060c020b01010900050101010900010a0b0101080201060b0301090001070b0301090001070900010b0101080202070a09000a0900050303060b01010802060a0b01010802070b000109000106090001080201060b01010900020b01010b0001090005040b03010a0b0101080208040b03010a0b010108020c01080401060804020c05010b0301090004726f6f6d066f626a656374066f7074696f6e067369676e657206766563746f7205746f6b656e0b6f626a6563745f7265667304526f6f6d064f626a65637405546f6b656e0b6164645f706c61796572731d6173736572745f706c617965725f696e5f6c696d697465645f726f6f6d0a636c6f73655f726f6f6d0b6372656174655f726f6f6d064f7074696f6e0b6765745f706c61796572730f6765745f726f6f6d5f7369676e6572166765745f746f75726e616d656e745f6164647265737307706c617965727311616464726573735f746f5f6f626a6563740a616464726573735f6f660869735f6f776e65720769735f736f6d650a626f72726f775f6d75740e726576657273655f617070656e6406626f72726f770e6f626a6563745f616464726573730e64657374726f795f6f626a6563740e436f6e7374727563746f725265660d6372656174655f6f626a6563740b6372656174655f7265667304736f6d65046e6f6e650a6765745f7369676e6572056f776e65724b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a76600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004030802000000000000000308000000000000000003080100000000000000126170746f733a3a6d657461646174615f7631e4010300000000000000000f454e4f545f524f4f4d5f4f574e455240417474656d7074656420746f20646f20736f6d657468696e6720746f206120726f6f6d207468617420746865207369676e657220646f6573206e6f74206f776e01000000000000000f45554e4b4e4f574e5f504c4159455219506c61796572206973206e6f7420696e2074686520726f6f6d020000000000000011454e4f545f4c494d495445445f524f4f4d1a54686973206973206e6f742061206c696d6974656420726f6f6d0104526f6f6d010301183078313a3a6f626a6563743a3a4f626a65637447726f757000000201120b03010a0b01010802000f000100010009190a0138000b0011083801040705090701270b013c000c030a033700380204160b03360038030b02380405180b030102010100010016340b003c000c060a06370038020408050c0b06010700270b06370038050c050600000000000000000c020a0541140c030a020a03230430051a0a050a0242140c040a04140a01380604290b05010b020b043807020b04010b02060100000000000000160c0205150b050107022702010001001a150b0138000c020a020b00110838010409050b0701270e0238080c030a033e003a00010b03110f02030100001b180b00110811100c030e033809010c050b01040e40140000000000000000380a0c020510380b0c020b020c040e050b0439003f000b0502040100010001050b003d003700140205010000010c0a0138000b0011083801040705090701270b011114020601000001040b003800380c020000000f00\",\"0xa11ceb0b060000000e0100140214220336d3010489023a05c302be03078106ad0508ae0b60068e0c1710a50cd6010afb0d1c0b970e020c990eef070d88160a0e92160a0000010101020103010401050106020700080009000a08010001020b07010000010c07010001070d0800041c040203010001012b0200000e00010100000f020301000010040501000011060701000012080501000013020301000014020301000015020901000016030a00011d0d0e0108031e080d00011f0f1001080120110d010802210314010002221610010002231718010004231a1b02030006241d03010009251e07010006261f200100090e0003010002271214010002281621010004290324020304042a2503020300012c0d2700082d28290108022e17120100042f1a2c0203000430240302030002311403010008320d030004332e2f02030006341d0301000535033000090c0b0c0c0c0d130e150f151019111c1212131c14121513160d171918190d0d151503120d071a0c150d0d1515071b151c191d191e152019210703060c050a0b02010803010b01010a0c02060c050003060c0303020c0b01010c02060c0b00010900010c01060c020b01010a0c0a0b0201080301020f070a0b02010803070a0b0201080302030b02010b00010900070b00010900060c030605050c0b01010a0c0a0c070b0402020a0b020108030a0b02010803010b000109000105010b02010900020b0201090005010101060b02010900010900010a0c010b01010900010b0402020a0b0201080301060b0101090001070b010109000107090002020a0b0201080302070b040209000901090001070901010b0201080302070a09000a090002060c0102070a090003010a09000106090001070b0001090003020b000109000b0402020a0b02010803010b04020900090103070b040209000901090009010208050c01080501060805020c05020b000109000c05020b02010b00010900050b01010b0402020a0b020108030b0402020a0b020108030109011a0a0b02010803070a0b02010803070a0b02010803070a0b0201080303030303070b00010900060c060c030305050c0c0a0c0a0c0a0c0a0c0a0c030a0b020108030a0b02010803070b0402020a0b0201080301060b0402090009010103010a020a6d617463686d616b6572066f626a656374066f7074696f6e067369676e6572117461626c655f776974685f6c656e677468137472616e73616374696f6e5f636f6e7465787406766563746f7205746f6b656e0b6f626a6563745f7265667304726f6f6d0a4d617463684d616b6572064f7074696f6e064f626a65637405546f6b656e0b6164645f706c61796572730d616c6c6f775f6a6f696e696e67196372656174655f6c696d697465645f6d617463686d616b6572176372656174655f6d617463686d616b65725f696e6e65721b6372656174655f756e6c696d697465645f6d617463686d616b65721264657374726f795f6d617463686d616b657210646973616c6c6f775f6a6f696e696e671266696e6973685f6d617463686d616b696e670e6765745f6275636b65745f6e756d146d696e5f706c61796572735f7065725f726f6f6d146d61785f706c61796572735f7065725f726f6f6d0f6a6f696e696e675f616c6c6f77656416756e6c696d697465645f726f6f6d5f616464726573730c757365725f6275636b6574730f5461626c65576974684c656e67746811616464726573735f746f5f6f626a6563740a616464726573735f6f660869735f6f776e65720e6f626a6563745f61646472657373046e6f6e650769735f736f6d650a626f72726f775f6d757406617070656e640b6372656174655f726f6f6d0c7472696d5f7265766572736504736f6d6506626f72726f77036e6577036164640e436f6e7374727563746f725265660d6372656174655f6f626a6563740b6372656174655f7265667307657874726163740672656d6f76650d64657374726f795f656d7074790c64657374726f795f6e6f6e650e64657374726f795f6f626a656374066c656e6774680e726576657273655f617070656e64146765745f7472616e73616374696f6e5f686173684b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a76600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004030801000000000000000308000000000000000002010a126170746f733a3a6d657461646174615f7631c10102000000000000000015454e4f545f4d415443484d414b45525f4f574e455244417474656d7074656420746f206d617463686d616b6520666f72206120746f75726e616d656e74207468617420746865207369676e657220646f6573206e6f74206f776e010000000000000014454a4f494e494e475f4e4f545f414c4c4f574544164a6f696e696e67206973206e6f7420616c6c6f776564010a4d617463684d616b6572010301183078313a3a6f626a6563743a3a4f626a65637447726f7570000002051703180319011a0b0101051b0b01010b0402020a0b02010803001200010001000b7b0b0138000c070a070a00110a38010409050d0b00010701270e0738023c000c080a083700140416051c0b00010b080107002738030c0e0a083701380404700a08360138050c1011080c050b100b0538060c030a030b0238070a032e411c0a083702142604690b000b030b083702140c0a0c040c09400700000000000000000c0f0a042e411c0a0a26046105480a090838080c0d0e0d110a0c0c0d0f0b0d44070a042e411c0c060a040b060a0a1738090c110a090b0c0b11380a05410b09010b04010b0f380b0c0e056f0b00010b08010b030105790b083703380c0c0b0b000b0b140b02380a0b0e02010100010022110a0138000b00110a3801040705090701270b013c000c02080b023600150202010000231f380d0c0531000c030a03070223041205090d050a03401c0000000000000000380e0b033101160c0305040b010b0208380f0b05381039000c040b000b04381138120203000000260d0b00110a11190c020e023813010c030e030b013f000b0302040100002a130a000938080c02060000000000000000060000000000000000080e02110a3814381539000c010b000b0138110b0238160205010001002b330b0138000c030a030b00110a38010409050b0701270e0338020c040a043e003a000c05010101010e053804042e0d0538170c0631000c020a02070223042c05230d060a023818010b023101160c02051e0b0638190b05381a0b04111f02060100010022110a0138000b00110a3801040705090701270b013c000c02090b023600150207010001002dba010a0138000a00110a38010407050b0b00010701270b013c000c0a090a0a3600150a0a3701380404b3010a0a360138050c1b0600000000000000000c06400700000000000000000c13401c00000000000000000c020a1b2e381b0c180a060a1823044705290a1b0a063338060c030a032e411c0c070a0706000000000000000024044005370d020a03451c441c0b07060100000000000000170c0705320b03010b06060100000000000000160c0605240b1b010a000d020a0a3702140c0d0c040c0b400700000000000000000c140a042e411c0a0d260473055a0a0b0838080c110e11110a0c0f0d140b1144070a042e411c0c080a040b080a0d1738090c190a0b0b0f0b19380a05530b0b010b04010b140c160d130b16381c0b000d020b0a3704140c0e0c050c0c400700000000000000000c150a052e411c0a0e2604a601058d010a0c0838080c120e12110a0c100d150b1244070a052e411c0c090a050b090a0e1738090c1a0a0c0b100b1a380a0586010b0c010b05010b150c170d130b17381c0b13380b0b02020b00010b0a013803401c00000000000000000208010000300711220c000d00450a07021902000200040001000300000012011202120312041200\",\"0xa11ceb0b060000000e01000e020e1a0328920104ba011805d2018d0107df02bf04089e076006fe076e10ec08a9060a950f0f0ba40f020ca60fa9040dcf130a0ed9130a0000010101020103020400050006000708010001020807010000010907010001040a080001210200000b00010100000c02030100000d02030100000e02040100000f05060100001007030100001107030100001207030100001302020100001407080100001502040100001602040100001707030100011e020a0108031f0b020001200c040108050b0001010005220b1001000523111001000124021200062513140108062602030005270703010005280716010006290208000d090f09010d080d100d030d0a0d110d120d1409160d170d03060c050a0b02010803010b01010a0c010500010104060c030303030c0c0b01010c02060c05010c010b00010900010b0201090001060c020b02010900050109000201060b00010900070c0b01010c08040c0b000109000c0b01010c020c0b01010c03060c030301080401060804020c0501070b00010900020b01010a0c0a0b02010803030101060b0001090005726f756e64066f626a656374066f7074696f6e067369676e657205746f6b656e0a6d617463686d616b65720b6f626a6563745f7265667305526f756e64064f7074696f6e064f626a65637405546f6b656e0b6164645f706c6179657273166173736572745f706c617965725f63616e5f6a6f696e166173736572745f706c617965725f63616e5f706c61790f63616e5f706c617965725f6a6f696e0c6372656174655f726f756e641964657374726f795f616e645f636c65616e75705f726f756e640f656e645f6d617463686d616b696e6708656e645f706c6179166765745f6d617463686d616b65725f61646472657373106765745f726f756e645f7369676e65720f69735f706c61795f616c6c6f7765640f726f756e645f69735f7061757365640a73746172745f706c6179066e756d626572116d617463686d616b696e675f656e6465640c706c61795f737461727465640a706c61795f656e64656406706175736564126d617463686d616b65725f6164647265737311616464726573735f746f5f6f626a6563740a616464726573735f6f660869735f6f776e65720e436f6e7374727563746f725265661b6372656174655f756e6c696d697465645f6d617463686d616b6572196372656174655f6c696d697465645f6d617463686d616b65720d6372656174655f6f626a6563740b6372656174655f726566730e64657374726f795f6f626a6563741264657374726f795f6d617463686d616b65721266696e6973685f6d617463686d616b696e670a6765745f7369676e65724b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a76600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004030806000000000000000308050000000000000003080a000000000000000308070000000000000003080000000000000000030809000000000000000308040000000000000003080200000000000000030808000000000000000308030000000000000003080100000000000000126170746f733a3a6d657461646174615f763194060b000000000000000010454e4f545f524f554e445f4f574e455228546865207369676e6572206973206e6f7420746865206f776e6572206f662074686520526f756e6401000000000000001245524f554e445f4e4f545f535441525445442254686520526f756e6420686173206e6f74206265656e20737461727465642079657402000000000000001145504c41595f4e4f545f414c4c4f5745441d506c6179206973206e6f742063757272656e746c7920616c6c6f77656403000000000000001445524f554e445f414c52454144595f454e4445441b54686520526f756e642068617320616c726561647920656e64656404000000000000001545504c41595f414c52454144595f5354415254454418506c61792068617320616c7265616479207374617274656405000000000000001c454d415443484d414b494e475f414c52454144595f535441525445441f4d617463686d616b696e672068617320616c7265616479207374617274656406000000000000001a454d415443484d414b494e475f414c52454144595f454e4445441d4d617463686d616b696e672068617320616c726561647920656e646564070000000000000018454d415443484d414b494e475f4e4f545f535441525445442d43616e206e6f7420656e64206d617463686d616b696e67206265666f726520697420686173207374617274656408000000000000001145504c41595f4e4f545f535441525445442643616e206e6f7420656e6420706c6179206265666f726520697420686173207374617274656409000000000000001345504c41595f414c52454144595f454e44454415506c617920697320616c726561647920656e6465640a0000000000000018454d415443484d414b494e475f4e4f545f414c4c4f574544244d617463686d616b696e67206973206e6f742063757272656e746c7920616c6c6f7765640105526f756e64010301183078313a3a6f626a6563743a3a4f626a65637447726f7570030f63616e5f706c617965725f6a6f696e0101000f69735f706c61795f616c6c6f7765640101000f726f756e645f69735f706175736564010100000206180319011a011b011c011d05000d000100010002150a0138000a00110e38010407050b0b00010704270a0138020b0138030c030b000b030b02380402010100010003070b0038050404050607022702020100010003070b003806040405060707270203010001000e140b003d000c020a0237001420040e0b02370114200c0105120b0201090c010b0102040100000f2b0a030600000000000000002104090a0038070c050c04050f0a000b020b0338080c050c040b040b050c0a0c070b01090909090e07110e39000c080b00110e11130c060e063809010c090e090b083f000b090b070b0a020501000100021a0a0138000a00110e38010407050b0b00010704270a013e003a000c0201010101010b0111150b000b02380a020601040100151a0a0138000a00110e38010407050b0b00010704270b013c000c02080a023600150b000b02370214380b0101020701040100151a0a0138000b00110e3801040705090704270b013c000c020a02370314041105150b0201070827080b0236041502080100010003050b003d003702140209010000030c0a0138000b00110e3801040705090704270b011118020a01000100171d0b003d000c030a03370314040d0a03370414200c01050f090c010b0104170b03370114200c02051b0b0301090c020b02020b0100010003050b003d00370114020c0104010015250a0138000b00110e3801040705090704270b013c000c020a0237031420041205160b02010706270a0237041420041c05200b0201070527080b023603150200010004000500020003000d010d020d030d040d00\",\"0xa11ceb0b060000000b010004020408030c190525140739b90108f2014010b202580a8a03160ca003c1010de104080fe904020001010200030800000408000005000100000602010000070201000008030400010d00030001060c000205030105010801010708000106080012746f75726e616d656e745f6d616e616765720e706c617965725f70726f66696c65067369676e65720d506c6179657250726f66696c651156696577506c6179657250726f66696c6504696e6974137265636f72645f70726f66696c655f6c6f7373127265636f72645f70726f66696c655f77696e13766965775f706c617965725f70726f66696c650477696e73066c6f737365730e6c6f6f745f636f6c6c6563746564096c6f6f745f6c6f73740a616464726573735f6f664b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a7660000000000000000000000000000000000000000000000000000000000000001126170746f733a3a6d657461646174615f76314400010d506c6179657250726f66696c65010301183078313a3a6f626a6563743a3a4f626a65637447726f75700113766965775f706c617965725f70726f66696c6501010000020409030a030b030c0301020409030a030b030c030001000001100a001104290020040d0b0006000000000000000006000000000000000006000000000000000006000000000000000012002d00050f0b000102010300010005140b002a000c020a021000140b01160a020f00150a02100114060100000000000000160b020f011502020300010005140b002a000c020a021002140b01160a020f02150a02100314060100000000000000160b020f031502030100010006110b002b000c010a011003140a011001140a011002140b011000141201020003000100020000000000\",\"0xa11ceb0b060000000d010014021428033c9f0104db011005eb019e01078903900708990a6006f90a800110f90ba3060a9c12350cd112f3050dc418140fd81802000101020103010401050106020700080009000a000b0800000c0800000d0800000e070004100700021907010000011e07010001061f080001320200000f00010000110203000012020400001302040000140204000015020200001600050000170205000018020600001a070100001b070800001c090a00001d0b010000200b0c000021000100002200010000230d01010003300f02000731020500013302120007341408010804351503000136021701080137180a01080238190a01000239191a0100093a1c0c00083b00010100083c1f200100053d01030100141316131713180219021b1e1c1e1d1e02060c050001050108040103010c01080305060c080403030b050105020c05020505010103060c050804010b0601080704060c0503030107080201060c03060800060801060802030808050c01080801080101060808010a0201060801010b06010900020b060109000501060b050109000106090002070801050305050804070c060c070800070800050c07080201090004060c030303030c0c0b05010c0561646d696e12746f75726e616d656e745f6d616e61676572066f626a656374066f7074696f6e067369676e657206737472696e6709747970655f696e666f05746f6b656e0b6f626a6563745f7265667305726f756e640d746f6b656e5f6d616e616765720c43757272656e74526f756e6412546f75726e616d656e744469726563746f720f546f75726e616d656e7453746174651356696577546f75726e616d656e7453746174650e656e645f746f75726e616d656e7406537472696e67176765745f63757272656e745f67616d655f6d6f64756c65136765745f6d61785f6e756d5f77696e6e6572730f6765745f6d61785f706c6179657273156765745f6e756d5f706c617965725f6a6f696e6564116765745f726f756e645f61646472657373156765745f746f75726e616d656e745f7369676e65721f6765745f746f75726e616d656e745f7369676e65725f61735f667269656e64146765745f746f75726e616d656e745f7374617465064f7074696f6e15696e697469616c697a655f746f75726e616d656e7421696e697469616c697a655f746f75726e616d656e745f776974685f72657475726e1069735f61646d696e5f616464726573730f6a6f696e5f746f75726e616d656e74064f626a65637405546f6b656e1b6a6f696e5f746f75726e616d656e745f776974685f72657475726e177365745f746f75726e616d656e745f6a6f696e61626c651b7365745f746f75726e616d656e745f6e6f745f6a6f696e61626c650f73746172745f6e65775f726f756e64066e756d6265720d726f756e645f616464726573730b67616d655f6d6f64756c650b6d61785f706c61796572730f6d61785f6e756d5f77696e6e6572730e706c61796572735f6a6f696e65640f746f75726e616d656e745f6e616d65177365636f6e646172795f61646d696e5f616464726573730b69735f6a6f696e61626c65096861735f656e6465641963757272656e745f726f756e645f67616d655f6d6f64756c650c726f756e645f6e756d6265720a616464726573735f6f660a6765745f7369676e65720e436f6e7374727563746f725265660d6372656174655f6f626a6563740b6372656174655f72656673047574663811616464726573735f746f5f6f626a6563740869735f6f776e65720769735f6e6f6e6506626f72726f77046d696e741964657374726f795f616e645f636c65616e75705f726f756e640c6372656174655f726f756e6409747970655f6e616d654b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a766000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040308010000000000000003080300000000000000030802000000000000000308040000000000000003080a0000000000000003080c0000000000000003080e0000000000000003080d0000000000000003080f00000000000000052000000000000000000000000000000000000000000000000000000000000000000a020100126170746f733a3a6d657461646174615f76318e060901000000000000000f454e4f545f415554484f52495a454435546865206163636f756e74206973206e6f7420617574686f72697a656420746f20706572666f726d207468617420616374696f6e2e02000000000000000a454e4f545f4f574e45521e546f6b656e206973206e6f74206f776e656420627920746865207573657203000000000000000a454e4f545f454d50545920506f6f6c206d75737420626520656d70747920746f20626520636c656172656404000000000000000d454e4f545f504c415941424c451a546f75726e616d656e74206973206e6f7420706c617961626c650a000000000000001b45544f55524e414d454e545f414c52454144595f53544152544544000c000000000000001045544f55524e414d454e545f46554c4c1754686520746f75726e616d656e742069732066756c6c2e0d000000000000001845544f55524e414d454e545f4e4f545f4a4f494e41424c451f54686520746f75726e616d656e74206973206e6f74206a6f696e61626c652e0e000000000000001545544f55524e414d454e545f4841535f454e4445442154686520746f75726e616d656e742068617320616c726561647920656e6465642e0f000000000000001745544f55524e414d454e545f4e4f545f535441525445441f54686520746f75726e616d656e7420686173206e6f7420737461727465642e030c43757272656e74526f756e64010301183078313a3a6f626a6563743a3a4f626a65637447726f75700f546f75726e616d656e745374617465010301183078313a3a6f626a6563743a3a4f626a65637447726f757012546f75726e616d656e744469726563746f72010301183078313a3a6f626a6563743a3a4f626a65637447726f7570060f6765745f6d61785f706c6179657273010100116765745f726f756e645f61646472657373010100136765745f6d61785f6e756d5f77696e6e657273010100146765745f746f75726e616d656e745f7374617465010100156765745f6e756d5f706c617965725f6a6f696e6564010100176765745f63757272656e745f67616d655f6d6f64756c65010100000203240325052608040102052703280329032a08042b0b0501050202022c012d0103020728032c012d012a08042e08042f0325050001040201020e140b0011110a01110b040605080700270b012a020c02090a020f0015080b020f011502010100010001050b002b0010021402020100010101050b002b0110031402030100010101050b002b0110041402040100010101050b002b0110051402050100010001050b002b00100614020601000101010b0b0011110a01110b040605080700270b011112020703000001030b001112020801000300010210200a002b010c020a002b020c030b002b000c010a021003140a031000140b031001140b021007140a011002140a011008140b011006141203020901040001090b000b010b020b030b04110a0101020a010000111f0b00111111130c050e0538000c060c070e070b020b030600000000000000000b010b0412012d010e07090912022d020e070600000000000000000709070a111512002d000b070b06020b0100010116180a0138010a003802040708020b012b010c020a021009380304120b020109020b02100938040e0021020c010402010201060b000b010b02110d01020d01000201021b330a012b02100114200407050b0b00010706270a010c040a042b02100014041305170b00010707270a0411040b04110323041e05220b00010705270a012a010c030a03100514060100000000000000160b030f05150b0011110b010b02111a020e01040201020e190b0011110a01110b040605080700270a012b0210011420040f05110706270b012a020c02080b020f0015020f01040201020e190b0011110a01110b040605080700270a012b0210011420040f05110706270b012a020c02090b020f001502100100030001021d550a0011110a01110b0406050a0b00010700270a012b0210011420041105150b00010706270a012a020c0a0a012a000c060b000b0111060c040e040a060c070c050a07100614070922042f0b050b07100614380505330b07010b05010e040a061008140b020b03380601010c090e0911110c0838070a060f02150a06100814060100000000000000160a060f08150b080b060f0615090b0a0f0015020200020100020101010001020001010300000104000000\",\"0xa11ceb0b060000000c01000a020a12031c3504510605572e078501ee0208f3034006b3043c0aef04060cf504500dc505020fc705040002010301040105000600070a00010d06000310080003110701000100080001000009020100000a020100000b030000010e040100040f02010003120206010803130602010802140908010001150a0b0006050705080800010c010501060c01060801010802010b03010900040a02060c08000801010a020106090002060c0a02020c0801106170746f735f746f75726e616d656e7412726f636b5f70617065725f73636973736f720561646d696e076163636f756e7403626373066f626a65637412746f75726e616d656e745f6d616e616765720a41646d696e53746f7265106765745f61646d696e5f7369676e65721b6765745f746f75726e616d656e745f6f776e65725f7369676e65722d6765745f746f75726e616d656e745f6f776e65725f7369676e65725f66726f6d5f6f626a6563745f6f776e65721273657475705f61646d696e5f7369676e65720a7369676e65725f636170105369676e65724361706162696c6974791d6372656174655f7369676e65725f776974685f6361706162696c6974791f6765745f746f75726e616d656e745f7369676e65725f61735f667269656e640a4f626a656374436f7265064f626a65637411616464726573735f746f5f6f626a656374056f776e657208746f5f6279746573176372656174655f7265736f757263655f6163636f756e744b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a766000000000000000000000000000000000000000000000000000000000000000105204b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a7660a0217166170746f7320746f75726e616d656e742061646d696e0002010c08010003000100000507002b0010001104020103000000030b001105020203000000050b00380038011101020303000007110a000c0207010c010b020e01380211090c04010b0412000c030b000b032d000200000000000100\",\"0xa11ceb0b060000000c010004020406030a0c04160205181007285e0886014010c601280aee010b0bf901020cfb01110f8c020200010102000307010601000400010106010802010106010303050a050a0500010900010b0001090012726f636b5f70617065725f73636973736f72066576656e7473056576656e740d47616d654f7665724576656e740e656d69745f67616d655f6f7665720c67616d655f616464726573730777696e6e657273066c6f7365727304656d69744b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a7660000000000000000000000000000000000000000000000000000000000000001126170746f733a3a6d657461646174615f76311400010d47616d654f7665724576656e74010400000002030505060a05070a0500020003000001060b000b010b023900380002000000\",\"0xa11ceb0b060000000d01001c021c30034cd201049e022405c202cb03078d068b0808980e6006f80e9501108d109a050aa7155b0c8216e70e0de9240c0ff52402000101020103010401050106010702080009000a000b000c000d000e000f0e0000100000001100000012070000130700001407000015070002160701000107170800031d070100000524070000180001000019020300001a040300001b050600001c070800001e080900001f080a000020080a000021080a000022080b000023080b0000250c0d0000260e0f00002710030000281011000029120300002a0813000d3a1516000b3b18190100033c1b0b0100033d1c1d0100043e1e08000a3f081f01000a400522010003411d2401000542230d0002432608000344291d010306452b0301000246082d010802472d080108024830080108034903240100084a0816000c4b1503000a4c15030100094d32030106064e34030100014f2323001217131a141a161714201717182318271b231c081d2c1e2c13231f2c202323172417253304060c05050a0b07010808010a0503060c050a0200020708030a0202050501080202050a020105010b09010806020a050a0501010106080301080a010b0701080801080304060c050a020a0203010a050a05030708030a020a0201080513070a05060c0800030303030b070108080b09010a0b070108080a0b070108080a05060c060c0b09010a0c0a0c0c060a0c060a0c060a0c02060c05010c01080403060c050a0b07010808010b09010a0c010a0c01060b0901090001070b0901090001090001060c010b09010a0b07010808010a0b07010808030708000505020305010a02010b0901090009010101060800080a060803080a060803080a0206050a02010806100101010101010a020a020608000a050a0205050a020a020a0502060b09010900090013070a05070a05050503030a050a050a050a050b070108080b070108080a050a050a050a050a050a050a0501070a0900010808010b070109000d0a050a050a050a050a050a050608000803050108030501020106080001060b070109001c070a05070a05050507080005030305050a050a050a050c060c05050a050a050b070108080a050a050a050a050a050a050a050a0503050a050a05010202070a09000a090001060800106170746f735f746f75726e616d656e7412726f636b5f70617065725f73636973736f720468617368066f626a656374066f7074696f6e067369676e657206737472696e6706766563746f7205746f6b656e0561646d696e066576656e747304726f6f6d05726f756e640d746f6b656e5f6d616e6167657212746f75726e616d656e745f6d616e616765720447616d650d47616d654f7665724576656e740947616d65537461746506506c6179657215526f636b506170657253636973736f727347616d65085669657747616d651256696577525053506c617965725374617465064f626a65637405546f6b656e156164645f706c61796572735f72657475726e696e670d636f6d6d69745f616374696f6e14636f6d6d69745f706c617965725f616374696f6e0b67616d655f737461747573106765745f67616d655f61646472657373064f7074696f6e146765745f706c617965725f7270735f73746174650b6765745f726573756c7473166765745f726573756c74735f61735f706c6179657273116765745f726573756c74735f666f7263651169735f67616d655f636f6d6d69747465641069735f67616d655f636f6d706c65746506537472696e670d706c617965725f73746174757313746f6b656e5f746f5f6e65775f706c617965720d7665726966795f616374696f6e177665726966795f616374696f6e5f72657475726e696e67147665726966795f706c617965725f616374696f6e09766965775f67616d6507706c617965723107706c61796572320777696e6e657273066c6f736572730a67616d655f73746174650c706c617965725f73746174650e6f70706f6e656e745f73746174650d706c617965725f616374696f6e0f6f70706f6e656e745f616374696f6e10636f6d6d69747465645f616374696f6e0f76657269666965645f616374696f6e07616464726573730d746f6b656e5f616464726573730b64756d6d795f6669656c640967616d655f726f6f6d156765745f746f75726e616d656e745f7369676e65720b6164645f706c61796572730769735f736f6d6507657874726163740a616464726573735f6f660b6765745f706c61796572731d6173736572745f706c617965725f696e5f6c696d697465645f726f6f6d04736f6d650475746638156372656174655f6f626a6563745f61646472657373106765745f776974685f64656661756c74077265766572736511616464726573735f746f5f6f626a656374056f776e65720e6f626a6563745f61646472657373046e6f6e652d6765745f746f75726e616d656e745f6f776e65725f7369676e65725f66726f6d5f6f626a6563745f6f776e65720f6d61726b5f746f6b656e5f6c6f73730a636c6f73655f726f6f6d0e656d69745f67616d655f6f76657206617070656e6408736861335f3235364b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a76600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004030802000000000000000308010000000000000003080400000000000000030806000000000000000308030000000000000003080000000000000000030805000000000000000a0501000a02090876657269666965640a020807737461727465640a020a09636f6d6d69747465640a020807696e76616c69640a020504526f636b0a02060550617065720a02080753636973736f72126170746f733a3a6d657461646174615f763185050700000000000000000f45504c415945525f554e4b4e4f574e1a506c61796572206973206e6f7420696e207468652067616d652e01000000000000001545414354494f4e5f4e4f545f434f4d4d495454454423506c6179657220686173206e6f7420636f6d6d697474656420616e20616374696f6e2e02000000000000001645414354494f4e5f444f45535f4e4f545f4d415443481f416374696f6e20646f6573206e6f74206d617463682076657269666965642e03000000000000000b454e4f545f4f424a45435427546865207369676e65722070617373656420696e206d75737420626520616e206f626a6563742e0400000000000000134547414d455f4e4f545f434f4d504c455445441547616d65206973206e6f7420636f6d706c6574656405000000000000001145524f4f4d5f4e4f545f4c494d495445441f54686520726f6f6d206d7573742062652061206c696d6974656420726f6f6d06000000000000001545494e56414c49445f504c415945525f434f554e54265468657265206d7573742062652074776f20706c617965727320696e207468697320726f6f6d020447616d65010301183078313a3a6f626a6563743a3a4f626a65637447726f75700d47616d654f7665724576656e740104000909766965775f67616d650101000b67616d655f7374617475730101000b6765745f726573756c7473010100106765745f67616d655f616464726573730101001069735f67616d655f636f6d706c657465010100116765745f726573756c74735f666f7263650101001169735f67616d655f636f6d6d6974746564010100146765745f706c617965725f7270735f7374617465010100166765745f726573756c74735f61735f706c61796572730101000002022b08032c08030102022d0a0b070108082e0a0b070108080202052f080a30080a31080a320b09010a02330b09010a02030204340b09010a02350b09010a023605370504020138010502022b08032c080306020239052f080500030000146e0b000b0111110c130e130b020b0338000c110e113801040d050f0706270d1138020c120e120c140600000000000000000c070a1441160c090a070a09230447051e0a140a0742160c0f0a0f111538030c0c0d0c38040c0d0e0d410e06020000000000000021042f05350b14010b0f010703270d0d450e0c0b0d0d450e110c0b0b110c12000c060b0f0b062d000b07060100000000000000160c0705190b14010e120c1507070c0e0b150c160600000000000000000c080a1641160c0a0a080a0a23046a05590a160a0842160c050d0e0c040b050c100b040b10111544080b08060100000000000000160c0805540b16010b0e020101040100211c0a012a000c030b0011150c040b010b0438050c05010a0310001001140b052104170b030f000b021102051b0b030f020b021102020200000003060b0138060b000f0315020301000100256d0b012b000c050a000a05100010041422040d080c0205140a000a051002100414220c020b020417051b0b05010705270a0510000a0510020c070c090a0510021004140b002104330b09010b07010a0510020b0510000c070c0905350b05010a09110b0c0a0a07110b0c08070811190c060a0a07091119210446080c03054b0a0807091119210c030b030450070911190c060a0a070a1119210458080c04055d0a08070a1119210c040b040462070a11190c060b060b0a0b080b091005140b071005141202020401000003040e000b01111a02050100010003060a000b0011101206380702060100010028a8010a00110a040405060702270b002b000c090a0910001005070b38080c070a0910021005070b38080c0807070c1007070c0a0a0910001001140c0c0b0910021001140c0d0a070a0821042d0d100a0c44080d100a0d4408070c0c0e070d0c0b070e0c0f0a070a0e21043c0a080a0b210c01053e090c010b0104460d100a0d44080d0a0a0c44080a070a0e21044f0a080a0f210c020551090c020b0204590d100a0c44080d0a0a0d44080a070a0b2104620a080a0e210c030564090c030b03046c0d100a0c44080d0a0a0d44080a070a0b2104750a080a0f210c040577090c040b04047f0d100a0d44080d0a0a0c44080a070a0f210488010a080b0e210c05058a01090c050b050492010d100a0d44080d0a0a0c44080b070b0f21049b010b080b0b210c06059d01090c060b0604a5010d100b0c44080d0a0b0d44080b100b0a0207010001002a530b0011060c080c0d07070c090b0d0c0e0d0e38090b0e0c0f0e0f41080c050a0506000000000000000024042505140d0f45080c030d090c010b03380a0c0b0b010b0b380b44080b05060100000000000000170c05050f0b0f460800000000000000000b090c130b080c1007070c0a0b100c110d1138090b110c120e1241080c060a0606000000000000000024044c053b0d1245080c040d0a0c020b04380a0c0c0b020b0c380b44080b06060100000000000000170c0605360b12460800000000000000000b0a0c070b130b070208010001002e490a002b000c070a071000140a071002140c0b0c080e081005380c0c0a0e0b1005380c0c0d0a0710001001140c090b0710021001140c0c0a0a0a0d1f04260b0011060c060c0505460b0a042f0b09400801000000000000000b0c400801000000000000000c040c0305420b0d04380b0c400801000000000000000b09400801000000000000000c020c01053e07070b090b0c400802000000000000000c020c010b010b020c040c030b030b040c060c050b050b060209010001002f140b002b000c020a0210001003380c040e0b0210021003380c0c0105120b0201090c010b01020a010001002f140b002b000c020a0210001005380c040e0b0210021005380c0c0105120b0201090c010b01020b00000003130a001005380c04090b000107081119020b001003380c0410070a11190207091119020c000000080a0e00380d0c01380e380e0b00380b0b011203020d0104010003090b000b010b020b03110e010101020e010001003192010a012a000c080b0011150c130a010b1338050c14010b140a0810001001142104180b080f000b020b03110f051d0b080f020b020b03110f0a01110a048e010a0111210c110e110b010c090c120a0911080c0f0c1807070c150b180c190d1938090b190c1a0e1a41080c0a0a0a06000000000000000024044c053b0d1a45080c060d150c040b06380a0c170b040b17380b44080b0a060100000000000000170c0a05360b1a460800000000000000000b150c1f0b0f0c1b07070c160b1b0c1c0d1c38090b1c0c1d0e1d41080c0b0a0b06000000000000000024047805620d1d45080c070d160c050b070c0c0a0c380a380b0c0d0a120b0c11220b050b0d44080b0b060100000000000000170c0b055d0b1d460800000000000000000b160c100a092c00010b120a09380f0b090a1f0a1038100b1f0b100c0e0c1e080b1e0b0e020907070707020f00000023280a010c030d030b0238110a00100314380e2104150a000b03112611020b0138060b000f051505270b03112638060a0010031421041e05220b00010700270b0138060b000f0515021001000100350b0b002b000c010a011000140b01100214120502000003030001030003020301000000\",\"0xa11ceb0b060000000c01001602161c0332800104b2011005c2016a07ac02ab0408d7066006b7076c10a30883010aa609080cae09e9020d970c020000010101020103010401050206000700080009000a000b0800010c07010001060d080002170701000004180700081b0700000e000100000f000200001003010000110304000012030100001303050000140601000015060101000a190508000a1a050500051c01080100081d0a0200031e030500021f0c0d010002200c0e01000711010400072103010004221008000223111201000a24130f000a250601000226011201000927060101000a15150101000a090d050e051205150516090a11170903060c050a0b0101080200010a0501060c010c010502060c050208040501080401080504060c05050a0b010108020501010b030105050101060b03010900010101060900020c05010a02010900010b0301090005060c080403030b030105040c060c050504060c050303106170746f735f746f75726e616d656e74066f626a656374066f7074696f6e067369676e657206737472696e6709747970655f696e666f05746f6b656e0561646d696e12726f636b5f70617065725f73636973736f7205726f756e6412746f75726e616d656e745f6d616e616765720f4170746f73546f75726e616d656e74064f626a65637405546f6b656e136164645f706c61796572735f746f5f67616d651d6164645f706c61796572735f746f5f67616d655f72657475726e696e670c6173736572745f61646d696e106765745f61646d696e5f7369676e65720b696e69745f6d6f64756c6515696e69745f6d6f64756c655f72657475726e696e67107365745f61646d696e5f7369676e65720f73746172745f6e65775f726f756e640d61646d696e5f61646472657373064f7074696f6e06537472696e67176765745f63757272656e745f67616d655f6d6f64756c65116765745f726f756e645f6164647265737315526f636b506170657253636973736f727347616d6509747970655f6e616d65156164645f706c61796572735f72657475726e696e670a616464726573735f6f660769735f736f6d6506626f72726f771273657475705f61646d696e5f7369676e6572047574663804736f6d6521696e697469616c697a655f746f75726e616d656e745f776974685f72657475726e177365745f746f75726e616d656e745f6a6f696e61626c65046e6f6e651964657374726f795f616e645f636c65616e75705f726f756e644b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a76600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004030800000000000000000308010000000000000005204b272129fdeabadae2d61453a1e2693de7758215a3653463e9adffddd3d3a7660a0211104170746f7320546f75726e616d656e7405200000000000000000000000000000000000000000000000000000000000000000126170746f733a3a6d657461646174615f76316f0200000000000000000f454e4f545f415554484f52495a454421596f7520617265206e6f7420617574686f72697a656420746f20646f207468617401000000000000001245554e5245434f474e495a45445f47414d4516556e7265636f676e697a65642067616d65206e616d650000000201160b030105000104010001060b000b010b0211010102010100010007170a0011020a0111080c030a0111090c040b03380021040d05110b00010701270b000b010b040b02110b0202000001000b250b00110c0c040a040702210c0507022b001000140c030b050411080c02051f0e033801041b0b040e03380214210c01051d090c010b010c020b020422052407002702030100010001040b001102110f020400000001040b0011050102050000000f180a001110110f0c010a000703111106e803000000000000060a000000000000000e01110c380311130c02010a000a0211140b00380412002d000b0202060104010001090b0011020b01380307022a000f001502070104010014300a001102110f0c020e020a010c050c030a0511090c040a04070422041f0b0511083800210415051b0b00010b03010701270b030b04380505210b030138063800210426052a0b00010701270b000b01060200000000000000060200000000000000380702000000\"]" + ], + "entryFunctionIdStr": "0x1::code::publish_package_txn" + } + }, + "signature": { + "type": "TYPE_SINGLE_SENDER", + "singleSender": { + "sender": { + "type": "TYPE_SINGLE_KEY", + "singleKeySignature": { + "publicKey": { + "type": "TYPE_ED25519", + "publicKey": "g1AFbc8cxypsbTPD789VudtJyCIxT2CpPsXMgWXmZcw=" + }, + "signature": { + "type": "TYPE_ED25519", + "signature": "ZtGZy0xz5Sp3Vu962c98EyqdHR+qKNMZu0o8a+1zCvMjSuRzt2nXpOSVaO7w5HAI2/bkIfMD5nhhyfZicqRfBw==", + "ed25519": { + "signature": "ZtGZy0xz5Sp3Vu962c98EyqdHR+qKNMZu0o8a+1zCvMjSuRzt2nXpOSVaO7w5HAI2/bkIfMD5nhhyfZicqRfBw==" + } + } + } + } + } + } + }, + "events": [ + { + "key": { + "accountAddress": "0x0" + }, + "type": { + "type": "MOVE_TYPES_STRUCT", + "struct": { + "address": "0x1", + "module": "transaction_fee", + "name": "FeeStatement" + } + }, + "typeStr": "0x1::transaction_fee::FeeStatement", + "data": "{\"execution_gas_units\":\"91\",\"io_gas_units\":\"110\",\"storage_fee_octas\":\"0\",\"storage_fee_refund_octas\":\"0\",\"total_charge_gas_units\":\"201\"}" + } + ] + } +} \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/mod.rs b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/mod.rs new file mode 100644 index 0000000000000..1c19a1b70b07e --- /dev/null +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/mod.rs @@ -0,0 +1,4 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +pub mod generated_transactions; diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/fa_double_transfer.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/fa_double_transfer.json similarity index 87% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/fa_double_transfer.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/fa_double_transfer.json index 8f6014678b39a..797d2277e3788 100644 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/fa_double_transfer.json +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/fa_double_transfer.json @@ -1,17 +1,17 @@ { "timestamp": { - "seconds": "1732752738", - "nanos": 956423000 + "seconds": "1737064521", + "nanos": 815047000 }, - "version": "69", + "version": "99", "info": { - "hash": "xrzWtoXziY00v1y/H1/5YyQO6dItOHDHooBPEiiZHH0=", - "stateChangeHash": "5d8vUR5B0jwYgif3F8vvw7l+JWzxcV/M5RQG4w+ibxk=", + "hash": "OjbUG7KkW06pvhI1BtyvKo3L+29OMZNY6Yg8h+Goo5w=", + "stateChangeHash": "FJadYIIeBuFu4+VUMly0rI7FB/kTnAHfXOcPW6Jaqls=", "eventRootHash": "FmWvL7p7CNYdF2eb/mjbz8+qRiRO70XR0GQsuHS1nuk=", "gasUsed": "2230", "success": true, "vmStatus": "Executed successfully", - "accumulatorRootHash": "BRdjZ5CQzT+6QgnKkEl0OU0WtLE5aN0F7JfdVUmg2K0=", + "accumulatorRootHash": "1oPG7Z3Mkeq4ycpqaQ5EAXhUYiwe6eavCqb+T/idMkY=", "changes": [ { "type": "TYPE_WRITE_RESOURCE", @@ -200,7 +200,7 @@ "data": { "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", "keyType": "address", - "value": "\"18446744073709012725\"", + "value": "\"18446744073709012525\"", "valueType": "u128" } } @@ -208,10 +208,10 @@ ] }, "epoch": "2", - "blockHeight": "33", + "blockHeight": "48", "type": "TRANSACTION_TYPE_USER", "sizeInfo": { - "transactionBytes": 1199, + "transactionBytes": 1279, "eventSizeInfo": [ { "typeTagBytes": 57, @@ -275,13 +275,13 @@ "maxGasAmount": "3345", "gasUnitPrice": "100", "expirationTimestampSecs": { - "seconds": "1732752769" + "seconds": "1737064552" }, "payload": { "type": "TYPE_SCRIPT_PAYLOAD", "scriptPayload": { "code": { - "bytecode": "oRzrCwcAAAoIAQAMAgwoAzRNBIEBCgWLAZIBB50C/AIImQUgBrkFjwEAAAABAAIAAwAEAAUBBgIAAAcAAAEIBwEAAQAJCAAACgsAAAsGAAAMBgACDgcBAAAFEAcAAQ0DBAABAg8CBgEAAQURBwgAAQMSCQIAAQETCwwBCAEAFAsNAAEAFQsOAAEAFg8QAAEEFwARAAEDGBITAQgBABkVAgEIAQAaFhABCAEBBQQKCQoKFAsUAQYMDAgAAwYIAAgBCwIBCAMLAgEIAwsCAQgDCAEIAQsCAQgECAUIBgACBgwKAgEIAAEEAQsHAQkAAQoCAQgIBwYIAAsHAQQICAgIAggICAgBCAQBBggAAQsCAQkAAQgFAQgGAgYIBQMBCAEBBQIFCwIBCQABCwIBCAMBCAMDBggGCwIBCQAIAQMGCAYLAgEJAAMOZnVuZ2libGVfYXNzZXQGb2JqZWN0Bm9wdGlvbhZwcmltYXJ5X2Z1bmdpYmxlX3N0b3JlBnNpZ25lcgZzdHJpbmcOQ29uc3RydWN0b3JSZWYNRnVuZ2libGVBc3NldAZPYmplY3QNRnVuZ2libGVTdG9yZQhNZXRhZGF0YQdNaW50UmVmC1RyYW5zZmVyUmVmE2NyZWF0ZV9uYW1lZF9vYmplY3QGT3B0aW9uBG5vbmUGU3RyaW5nBHV0ZjgrY3JlYXRlX3ByaW1hcnlfc3RvcmVfZW5hYmxlZF9mdW5naWJsZV9hc3NldBtvYmplY3RfZnJvbV9jb25zdHJ1Y3Rvcl9yZWYRZ2VuZXJhdGVfbWludF9yZWYVZ2VuZXJhdGVfdHJhbnNmZXJfcmVmBG1pbnQKYWRkcmVzc19vZhtlbnN1cmVfcHJpbWFyeV9zdG9yZV9leGlzdHMQZGVwb3NpdF93aXRoX3JlZhF3aXRoZHJhd193aXRoX3JlZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCgIDAkZBCgIIB0ZBIENvaW4KAiAfaHR0cHM6Ly9leGFtcGxlLmNvbS9mYXZpY29uLmljbwoCFBNodHRwczovL2V4YW1wbGUuY29tBSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADK/gUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAur4AAAFFCgAHABEADAEOAQwDCgM4AAcBEQIHABECMQgHAhECBwMRAhEDCgM4AQwKCgMRBQwLCwMRBgwMBkBCDwAAAAAADAIOCwoCEQcMBAsAEQgKCjgCDAUODAoFCwQ4Aw4MCwUKAjgEDAgHBAoKOAIMBg4MCgYLCDgDDgwLBgsCOAQMCQcFCwo4AgwHDgwLBwsJOAMC", + "bytecode": "oRzrCwcAAAoJAQAMAgwoAzRNBIEBCgWLAYcBB5ICigMInAVABtwFjwEQ6wYfAQIBBQEIAQsBDgEXAAQCAAEHBwEAAAIKBwAEDQsAABAHAQABBBIGAAQUBgAEFgAABBoIAAADAgMAAQEGAQUBAAECCQYHAAEDDAgBAAEADwoLAQgBBBEKDAABBBMKDQABBBUODwABBRgAEAABAxkREgEIAQQbFAEBCAEEHBUPAQgBAQQECQkJChMLEwEGDAACBgwKAgEIAAEEAQsBAQkAAQoCAQgCBwYIAAsBAQQIAggCAggCCAIBCAMBBggAAQsEAQkAAQgFAQgGAgYIBQMBCAcBBQIFCwQBCQABCwQBCAgBCAgDBggGCwQBCQAIBwMGCAYLBAEJAAMJCAAGCAALBAEIAwgFCAYIBwsEAQgIAwYIBgg8U0VMRj5fMARtYWluBm9iamVjdBNjcmVhdGVfbmFtZWRfb2JqZWN0DkNvbnN0cnVjdG9yUmVmBm9wdGlvbgRub25lBk9wdGlvbgZzdHJpbmcEdXRmOAZTdHJpbmcWcHJpbWFyeV9mdW5naWJsZV9zdG9yZStjcmVhdGVfcHJpbWFyeV9zdG9yZV9lbmFibGVkX2Z1bmdpYmxlX2Fzc2V0CE1ldGFkYXRhDmZ1bmdpYmxlX2Fzc2V0G29iamVjdF9mcm9tX2NvbnN0cnVjdG9yX3JlZgZPYmplY3QRZ2VuZXJhdGVfbWludF9yZWYHTWludFJlZhVnZW5lcmF0ZV90cmFuc2Zlcl9yZWYLVHJhbnNmZXJSZWYEbWludA1GdW5naWJsZUFzc2V0BnNpZ25lcgphZGRyZXNzX29mG2Vuc3VyZV9wcmltYXJ5X3N0b3JlX2V4aXN0cw1GdW5naWJsZVN0b3JlEGRlcG9zaXRfd2l0aF9yZWYRd2l0aGRyYXdfd2l0aF9yZWb//////////////////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCgIDAkZBCgIIB0ZBIENvaW4KAiAfaHR0cHM6Ly9leGFtcGxlLmNvbS9mYXZpY29uLmljbwoCFBNodHRwczovL2V4YW1wbGUuY29tBSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADK/gUgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAur4UY29tcGlsYXRpb25fbWV0YWRhdGEJAAMyLjADMi4xAAAWQwoABwARAAwBDgEMAgoCOAAHARECBwARAjEIBwIRAgcDEQIRAwoCOAEMAwoCEQUMBAsCEQYMBQ4EBkBCDwAAAAAAEQcMBgsAEQgKAzgCDAcOBQoHCwY4Aw4FCwcGQEIPAAAAAAA4BAwGBwQKAzgCDAcOBQoHCwY4Aw4FCwcGQEIPAAAAAAA4BAwGBwULAzgCDAcOBQsHCwY4AwI=", "abi": { "name": "main", "visibility": "VISIBILITY_PUBLIC", @@ -304,7 +304,7 @@ "type": "TYPE_ED25519", "ed25519": { "publicKey": "X3dtn8+5n300isDheC1WwnuA6rUEP5ShsSfvipASLUM=", - "signature": "9Y7nb69XbP7YWzpfpYhGlH2UwtlCLdBVUCZ69Xz9pbmkeZTVIP+xwHrF4buJ9QRjHiD5iV6ZNz9FYSKVcEzrCw==" + "signature": "3Dm5YP1TtKMzsyRLzwocKb4DBLwfnFWh7YlVQez9PYffhbc8wksWCaFaw7KrT/U5JCdGnaRm94F85QHhNVYhDQ==" } } }, diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/fa_mint_transfer_burn.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/fa_mint_transfer_burn.json similarity index 83% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/fa_mint_transfer_burn.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/fa_mint_transfer_burn.json index 77581c76c2ed0..98500ac7eea4b 100644 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/fa_mint_transfer_burn.json +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/fa_mint_transfer_burn.json @@ -1,17 +1,17 @@ { "timestamp": { - "seconds": "1732752725", - "nanos": 407952000 + "seconds": "1737064501", + "nanos": 903460000 }, - "version": "35", + "version": "53", "info": { - "hash": "ayRIeRnfkgKGyIpCineUBPs4ehrliH8unvneE+3Kdy4=", - "stateChangeHash": "+3sO3Xe8keMQBqigBaLQjzyIOn9q7rjFa6WfnIi9Ssg=", + "hash": "NUjEd4fE2wqjM8r3rN50izKN4rjDKNXDH16Ie5iwUPc=", + "stateChangeHash": "iJ0OTUI3wtrBSMOjR2T75iRNFjxNYUdeXK5DN949eow=", "eventRootHash": "zguCQh0yktZ64gFcK3ArJOOrDjHPVhTjf/pYU5fhJdc=", "gasUsed": "1161", "success": true, "vmStatus": "Executed successfully", - "accumulatorRootHash": "ohk3aLs2jJLjb5zxSsO3DHfJAEsWGwlOhWTLWlekMT0=", + "accumulatorRootHash": "93phBJ70b4Uamv/WYTWO4e8x8eSWpqoE5uCrkb+4y6U=", "changes": [ { "type": "TYPE_WRITE_RESOURCE", @@ -144,7 +144,7 @@ "data": { "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", "keyType": "address", - "value": "\"18446744073709335625\"", + "value": "\"18446744073709335525\"", "valueType": "u128" } } @@ -152,10 +152,10 @@ ] }, "epoch": "2", - "blockHeight": "17", + "blockHeight": "26", "type": "TRANSACTION_TYPE_USER", "sizeInfo": { - "transactionBytes": 1111, + "transactionBytes": 1198, "eventSizeInfo": [ { "typeTagBytes": 57, @@ -199,13 +199,13 @@ "maxGasAmount": "1741", "gasUnitPrice": "100", "expirationTimestampSecs": { - "seconds": "1732752755" + "seconds": "1737064531" }, "payload": { "type": "TYPE_SCRIPT_PAYLOAD", "scriptPayload": { "code": { - "bytecode": "oRzrCwcAAAoIAQAMAgwsAzhTBIsBCgWVAYkBB54CjgMIrAUgBswFSwAAAAEAAgADAAQABQEGAgAABwYAAAgAAAEJBwEAAQAKCAAACwsAAAwGAAANBgACDwcBAAAFEQcAAQ4DBAABAhACBgEAAQUSBwgAAQMTCQIAAQEUCwwBCAEAFQsNAAEAFgsOAAEAFwsPAAEAGBARAAEEGQASAAEDGhMUAQgBABsWAgEIAQAcFwIBCAEBBQQKCgoLFQwVAQYMCQgAAwgBBggACAILAwEIBAsDAQgFCAYIBwACBgwKAgEIAAEEAQsIAQkAAQoCAQgJBwYIAAsIAQQICQgJAggJCAkBCAUBBggAAQsDAQkAAQgGAQgBAQgHAgYIBgMBCAIBBQIFCwMBCQABCwMBCAQBCAQDBggHCwMBCQAIAgMGCAELAwEJAAMOZnVuZ2libGVfYXNzZXQGb2JqZWN0Bm9wdGlvbhZwcmltYXJ5X2Z1bmdpYmxlX3N0b3JlBnNpZ25lcgZzdHJpbmcOQ29uc3RydWN0b3JSZWYHQnVyblJlZg1GdW5naWJsZUFzc2V0Bk9iamVjdA1GdW5naWJsZVN0b3JlCE1ldGFkYXRhB01pbnRSZWYLVHJhbnNmZXJSZWYTY3JlYXRlX25hbWVkX29iamVjdAZPcHRpb24Ebm9uZQZTdHJpbmcEdXRmOCtjcmVhdGVfcHJpbWFyeV9zdG9yZV9lbmFibGVkX2Z1bmdpYmxlX2Fzc2V0G29iamVjdF9mcm9tX2NvbnN0cnVjdG9yX3JlZhFnZW5lcmF0ZV9taW50X3JlZhFnZW5lcmF0ZV9idXJuX3JlZhVnZW5lcmF0ZV90cmFuc2Zlcl9yZWYEbWludAphZGRyZXNzX29mG2Vuc3VyZV9wcmltYXJ5X3N0b3JlX2V4aXN0cxBkZXBvc2l0X3dpdGhfcmVmCWJ1cm5fZnJvbQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCgIDAkZBCgIIB0ZBIENvaW4KAiAfaHR0cHM6Ly9leGFtcGxlLmNvbS9mYXZpY29uLmljbwoCFBNodHRwczovL2V4YW1wbGUuY29tAAABMgoABwARAAwBDgEMBAoEOAAHARECBwARAjEIBwIRAgcDEQIRAwoEOAEMBwoEEQUMCAoEEQYMAwsEEQcMCQZAQg8AAAAAAAwCDggKAhEIDAULABEJCwc4AgwGDgkKBgsFOAMOAwsGCwI4BAI=", + "bytecode": "oRzrCwcAAAoJAQAMAgwsAzhTBIsBCgWVAYwBB6ECnAMIvQVABv0FSxDIBh8BAgEFAQgBCwEOARkABAIAAQcHAQAAAgoHAAQNCwAAEAcBAAEEEgYABBQGAAQWBgAEGAAABBwIAAADAgMAAQEGAQUBAAECCQYHAAEDDAgBAAEADwoLAQgBBBEKDAABBBMKDQABBBUKDgABBBcPEAABBRoAEQABAxsSEwEIAQQdFQEBCAEEHhYBAQgBAQQECQoJCxQMFAEGDAACBgwKAgEIAAEEAQsBAQkAAQoCAQgCBwYIAAsBAQQIAggCAggCCAIBCAMBBggAAQsEAQkAAQgFAQgGAQgHAgYIBQMBCAgBBQIFCwQBCQABCwQBCAkBCAkDBggHCwQBCQAICAMGCAYLBAEJAAMKCAAGCAALBAEIAwgFCAYIBwgICwQBCAkDBggGCDxTRUxGPl8wBG1haW4Gb2JqZWN0E2NyZWF0ZV9uYW1lZF9vYmplY3QOQ29uc3RydWN0b3JSZWYGb3B0aW9uBG5vbmUGT3B0aW9uBnN0cmluZwR1dGY4BlN0cmluZxZwcmltYXJ5X2Z1bmdpYmxlX3N0b3JlK2NyZWF0ZV9wcmltYXJ5X3N0b3JlX2VuYWJsZWRfZnVuZ2libGVfYXNzZXQITWV0YWRhdGEOZnVuZ2libGVfYXNzZXQbb2JqZWN0X2Zyb21fY29uc3RydWN0b3JfcmVmBk9iamVjdBFnZW5lcmF0ZV9taW50X3JlZgdNaW50UmVmEWdlbmVyYXRlX2J1cm5fcmVmB0J1cm5SZWYVZ2VuZXJhdGVfdHJhbnNmZXJfcmVmC1RyYW5zZmVyUmVmBG1pbnQNRnVuZ2libGVBc3NldAZzaWduZXIKYWRkcmVzc19vZhtlbnN1cmVfcHJpbWFyeV9zdG9yZV9leGlzdHMNRnVuZ2libGVTdG9yZRBkZXBvc2l0X3dpdGhfcmVmCWJ1cm5fZnJvbf//////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEKAgMCRkEKAggHRkEgQ29pbgoCIB9odHRwczovL2V4YW1wbGUuY29tL2Zhdmljb24uaWNvCgIUE2h0dHBzOi8vZXhhbXBsZS5jb20UY29tcGlsYXRpb25fbWV0YWRhdGEJAAMyLjADMi4xAAAXMAoABwARAAwBDgEMAgoCOAAHARECBwARAjEIBwIRAgcDEQIRAwoCOAEMAwoCEQUMBAoCEQYMBQsCEQcMBg4EBkBCDwAAAAAAEQgMBwsAEQkLAzgCDAgOBgoICwc4Aw4FCwgGQEIPAAAAAAA4BAI=", "abi": { "name": "main", "visibility": "VISIBILITY_PUBLIC", @@ -228,7 +228,7 @@ "type": "TYPE_ED25519", "ed25519": { "publicKey": "KU08yl94iErSCo4VhF6tGWQYqvSaK1IjTD/4i/uoPSI=", - "signature": "kr6k4+df1lIe1fYDQ89POnorMV1YGSI8hL5aYeUNvtPBODiBUvpxPGq4wyG+HNbUpNHWtwS40NfZ/kYZjOwRDQ==" + "signature": "Mk7QW4J1+RcAz61QMThGjn4sI6kbHXdvmEOPBXGhx8NtyL0jC+IFIfkiERIkK3ZYVLs5Lqiqnsw5jTIRwRApCg==" } } }, diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script3.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script1.json similarity index 87% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script3.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script1.json index b04618998c095..de02c06bbd815 100644 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script3.json +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script1.json @@ -1,17 +1,17 @@ { "timestamp": { - "seconds": "1732752746", - "nanos": 930524000 + "seconds": "1737064572", + "nanos": 758978000 }, - "version": "93", + "version": "219", "info": { - "hash": "8iRuztTGNuVflgAEWpnx1WcRfGZ0+Dau/wwjOiSH3+o=", - "stateChangeHash": "OcnKtsd6TAR4jLFPHupwOCBKrSPgj0xaZiTWnFVLBE8=", + "hash": "2bz8FjyWxds3UjlX+5c07twTfFa3/+7wPQHdc9oY6B8=", + "stateChangeHash": "5SrNqse3ohrxqjBBNUER/Jfh63zz70I2b/+Lx8VKWzY=", "eventRootHash": "J/kCueHhHqJXi8MVudrh82sOQ/pqY9TJ9VjLOdgel6I=", "gasUsed": "3", "success": true, "vmStatus": "Executed successfully", - "accumulatorRootHash": "/1sGciJhlYZDYDkbCBoJRcS3Pgksc1YfOJ1orZz8X4w=", + "accumulatorRootHash": "WKD4zhKlQROJdi6jp+Z022ZQsp81zQAfrszTIQ6ur2I=", "changes": [ { "type": "TYPE_WRITE_RESOURCE", @@ -60,18 +60,18 @@ "data": { "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", "keyType": "address", - "value": "\"18446744073809012325\"", + "value": "\"18446744074009011325\"", "valueType": "u128" } } } ] }, - "epoch": "2", - "blockHeight": "44", + "epoch": "3", + "blockHeight": "105", "type": "TRANSACTION_TYPE_USER", "sizeInfo": { - "transactionBytes": 190, + "transactionBytes": 279, "eventSizeInfo": [ { "typeTagBytes": 63, @@ -99,13 +99,13 @@ "maxGasAmount": "4", "gasUnitPrice": "100", "expirationTimestampSecs": { - "seconds": "1732752777" + "seconds": "1737064603" }, "payload": { "type": "TYPE_SCRIPT_PAYLOAD", "scriptPayload": { "code": { - "bytecode": "oRzrCwcAAAoBBQAEAQYMAAAAAQEC", + "bytecode": "oRzrCwcAAAoEBQAEBwQOCBIgEDIfAQYMAAg8U0VMRj5fMARtYWlu//////////////////////////////////////////8UY29tcGlsYXRpb25fbWV0YWRhdGEJAAMyLjADMi4xAAABAwsAAQI=", "abi": { "name": "main", "visibility": "VISIBILITY_PUBLIC", @@ -128,7 +128,7 @@ "type": "TYPE_ED25519", "ed25519": { "publicKey": "spiXXSfb/zAg5e5/27rYqWnU8qLVKG4JfR25dg0E3TE=", - "signature": "nx5JY37B7wYb/XGMQsRmniHKWAr2Em9Acw4rf2t7PaVUFri5H7a3YLuS+P8UgbWpJEQZ+8rOJheGZ/mDaovDBQ==" + "signature": "l3L1AxJogZc1uzH0uhpvydsBiXjYswlzdtU0/S90QyqDk1iq5n6PPwBhH/z/F/OI3KkovGxF8MPRxxrMf8JRBA==" } } }, diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script2.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script2.json similarity index 67% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script2.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script2.json index d07c603361eae..a3aad42caede5 100644 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script2.json +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script2.json @@ -1,23 +1,23 @@ { "timestamp": { - "seconds": "1732752767", - "nanos": 150408000 + "seconds": "1737064588", + "nanos": 849799000 }, - "version": "155", + "version": "257", "info": { - "hash": "uPvgWhILXg+hzAcjHXBQckTyTAN4kmY06MfaH8U4Ks0=", - "stateChangeHash": "ffjkaIUuvKPlWv5iB1ZEqP+eaGgZvbfWk2W3DzDyKeM=", + "hash": "n7kE3VaF1Mg+Q48JozggJzlpaxwD+xX3X+Qu4eCmyk0=", + "stateChangeHash": "o0ljf0k5tCRO1MwFkiiGVJNASqT2hgPZs6/qmXlmfi4=", "eventRootHash": "J/kCueHhHqJXi8MVudrh82sOQ/pqY9TJ9VjLOdgel6I=", "gasUsed": "3", "success": true, "vmStatus": "Executed successfully", - "accumulatorRootHash": "ouZijqZ66R3YzKg+ZlEklCxMgXAyeeLk96OLTHyxCWw=", + "accumulatorRootHash": "mCBnBBkZ0b40LUlXgbqGKYycc8IiFTZtlGjjslFRHbQ=", "changes": [ { "type": "TYPE_WRITE_RESOURCE", "writeResource": { - "address": "0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16", - "stateKeyHash": "7O4BxwtA1aq/JOeivJLrjvBzZqjcmxgfMf8zWfxlkTg=", + "address": "0x765d8c8d4d5859f43a56e2756fbf5f3d2483dbaa14f3fb62872df820d6e64eff", + "stateKeyHash": "ceneJQEOEzV92WirHTGbXnLP+TvF5K6btYiyF5HdKKg=", "type": { "address": "0x1", "module": "coin", @@ -34,21 +34,21 @@ ] }, "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"199999400\"},\"deposit_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"creation_num\":\"3\"}}}}" + "data": "{\"coin\":{\"value\":\"199999400\"},\"deposit_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x765d8c8d4d5859f43a56e2756fbf5f3d2483dbaa14f3fb62872df820d6e64eff\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x765d8c8d4d5859f43a56e2756fbf5f3d2483dbaa14f3fb62872df820d6e64eff\",\"creation_num\":\"3\"}}}}" } }, { "type": "TYPE_WRITE_RESOURCE", "writeResource": { - "address": "0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16", - "stateKeyHash": "kTyDSe1B56OkH/TKEWlIkXJHwn7giS1ZRbpSKU2H6xA=", + "address": "0x765d8c8d4d5859f43a56e2756fbf5f3d2483dbaa14f3fb62872df820d6e64eff", + "stateKeyHash": "fosKvq2RB9fkmTNvrdzHt/qGGmluI1R/CwhAP58GB3o=", "type": { "address": "0x1", "module": "account", "name": "Account" }, "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"coin_register_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"2\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + "data": "{\"authentication_key\":\"0x765d8c8d4d5859f43a56e2756fbf5f3d2483dbaa14f3fb62872df820d6e64eff\",\"coin_register_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x765d8c8d4d5859f43a56e2756fbf5f3d2483dbaa14f3fb62872df820d6e64eff\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x765d8c8d4d5859f43a56e2756fbf5f3d2483dbaa14f3fb62872df820d6e64eff\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"2\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" } }, { @@ -60,18 +60,18 @@ "data": { "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", "keyType": "address", - "value": "\"18446744074109109925\"", + "value": "\"18446744074109109725\"", "valueType": "u128" } } } ] }, - "epoch": "2", - "blockHeight": "72", + "epoch": "3", + "blockHeight": "123", "type": "TRANSACTION_TYPE_USER", "sizeInfo": { - "transactionBytes": 190, + "transactionBytes": 279, "eventSizeInfo": [ { "typeTagBytes": 63, @@ -95,18 +95,18 @@ }, "user": { "request": { - "sender": "0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16", + "sender": "0x765d8c8d4d5859f43a56e2756fbf5f3d2483dbaa14f3fb62872df820d6e64eff", "sequenceNumber": "1", "maxGasAmount": "4", "gasUnitPrice": "100", "expirationTimestampSecs": { - "seconds": "1732752797" + "seconds": "1737064619" }, "payload": { "type": "TYPE_SCRIPT_PAYLOAD", "scriptPayload": { "code": { - "bytecode": "oRzrCwcAAAoBBQAEAQYMAAAAAQEC", + "bytecode": "oRzrCwcAAAoEBQAEBwQOCBIgEDIfAQYMAAg8U0VMRj5fMARtYWlu//////////////////////////////////////////8UY29tcGlsYXRpb25fbWV0YWRhdGEJAAMyLjADMi4xAAABAwsAAQI=", "abi": { "name": "main", "visibility": "VISIBILITY_PUBLIC", @@ -128,8 +128,8 @@ "signature": { "type": "TYPE_ED25519", "ed25519": { - "publicKey": "ObSsyF4CbcBWRkpeoAuY+FgmDqrSt03TC4auDU2U3fU=", - "signature": "gXBGQFT6fL1EP2YWq4O+GqIKWQUCQkgUGrrVszrEHX1rP1xuq04/eFq4GOVcCjQs7f2QlAC8OSGq+kxBfTmNCg==" + "publicKey": "spiXXSfb/zAg5e5/27rYqWnU8qLVKG4JfR25dg0E3TE=", + "signature": "2Dxk9+YIK0w8UuF0Wf5g1hxt9atJeR8u4BecNBPSj/Mf02o560g+4eFJpOkS5Tsqs/WEc2ZM5yxVgcAcFJBYCQ==" } } }, diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script1.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script3.json similarity index 68% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script1.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script3.json index 1cff569455b9e..9114d2eb82aef 100644 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script1.json +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script3.json @@ -1,23 +1,23 @@ { "timestamp": { - "seconds": "1732752760", - "nanos": 733718000 + "seconds": "1737064539", + "nanos": 789509000 }, - "version": "135", + "version": "141", "info": { - "hash": "RQzeD2EQM+QpZiLInBzM9l4Z5t0BWPGf33k40KrvmkM=", - "stateChangeHash": "UieS5RIQtmLQQfs+NnTlQVgBiPBaq0hVAuCorH9MmQs=", + "hash": "dnofXFDUunfWKjUKzjJSQYmMblCRSYfT42h03gjkWrs=", + "stateChangeHash": "Jb2ck2h6PXF3nlU4lOqv9GDInP2100rC3YayI3vxAI4=", "eventRootHash": "J/kCueHhHqJXi8MVudrh82sOQ/pqY9TJ9VjLOdgel6I=", "gasUsed": "3", "success": true, "vmStatus": "Executed successfully", - "accumulatorRootHash": "TI595vYByB/07beHZjlqhEKIp0oiAeA1wYzi3rkqOkI=", + "accumulatorRootHash": "/s+cU+SLKtmRA/sHuS4t9qHIsoF+rL7BIhboxRq+AOI=", "changes": [ { "type": "TYPE_WRITE_RESOURCE", "writeResource": { - "address": "0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16", - "stateKeyHash": "7O4BxwtA1aq/JOeivJLrjvBzZqjcmxgfMf8zWfxlkTg=", + "address": "0x501b015c58f2a1a62a330a6da80dfee723f528f719d25a4232751986f9a9f43f", + "stateKeyHash": "mblV8kItKhzWpJyNZcf9X5l3EmRe3m4NrXTdtzITQ6k=", "type": { "address": "0x1", "module": "coin", @@ -34,21 +34,21 @@ ] }, "typeStr": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - "data": "{\"coin\":{\"value\":\"99999700\"},\"deposit_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"creation_num\":\"3\"}}}}" + "data": "{\"coin\":{\"value\":\"99999700\"},\"deposit_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x501b015c58f2a1a62a330a6da80dfee723f528f719d25a4232751986f9a9f43f\",\"creation_num\":\"2\"}}},\"frozen\":false,\"withdraw_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x501b015c58f2a1a62a330a6da80dfee723f528f719d25a4232751986f9a9f43f\",\"creation_num\":\"3\"}}}}" } }, { "type": "TYPE_WRITE_RESOURCE", "writeResource": { - "address": "0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16", - "stateKeyHash": "kTyDSe1B56OkH/TKEWlIkXJHwn7giS1ZRbpSKU2H6xA=", + "address": "0x501b015c58f2a1a62a330a6da80dfee723f528f719d25a4232751986f9a9f43f", + "stateKeyHash": "+VS7DLwWFCETA4QQAND9ZVqc3IugzikHe1YU0T9rVo0=", "type": { "address": "0x1", "module": "account", "name": "Account" }, "typeStr": "0x1::account::Account", - "data": "{\"authentication_key\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"coin_register_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" + "data": "{\"authentication_key\":\"0x501b015c58f2a1a62a330a6da80dfee723f528f719d25a4232751986f9a9f43f\",\"coin_register_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x501b015c58f2a1a62a330a6da80dfee723f528f719d25a4232751986f9a9f43f\",\"creation_num\":\"0\"}}},\"guid_creation_num\":\"4\",\"key_rotation_events\":{\"counter\":\"0\",\"guid\":{\"id\":{\"addr\":\"0x501b015c58f2a1a62a330a6da80dfee723f528f719d25a4232751986f9a9f43f\",\"creation_num\":\"1\"}}},\"rotation_capability_offer\":{\"for\":{\"vec\":[]}},\"sequence_number\":\"1\",\"signer_capability_offer\":{\"for\":{\"vec\":[]}}}" } }, { @@ -60,7 +60,7 @@ "data": { "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", "keyType": "address", - "value": "\"18446744074009011525\"", + "value": "\"18446744073809012125\"", "valueType": "u128" } } @@ -68,10 +68,10 @@ ] }, "epoch": "2", - "blockHeight": "63", + "blockHeight": "68", "type": "TRANSACTION_TYPE_USER", "sizeInfo": { - "transactionBytes": 190, + "transactionBytes": 279, "eventSizeInfo": [ { "typeTagBytes": 63, @@ -95,17 +95,17 @@ }, "user": { "request": { - "sender": "0xa531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16", + "sender": "0x501b015c58f2a1a62a330a6da80dfee723f528f719d25a4232751986f9a9f43f", "maxGasAmount": "4", "gasUnitPrice": "100", "expirationTimestampSecs": { - "seconds": "1732752791" + "seconds": "1737064569" }, "payload": { "type": "TYPE_SCRIPT_PAYLOAD", "scriptPayload": { "code": { - "bytecode": "oRzrCwcAAAoBBQAEAQYMAAAAAQEC", + "bytecode": "oRzrCwcAAAoEBQAEBwQOCBIgEDIfAQYMAAg8U0VMRj5fMARtYWlu//////////////////////////////////////////8UY29tcGlsYXRpb25fbWV0YWRhdGEJAAMyLjADMi4xAAABAwsAAQI=", "abi": { "name": "main", "visibility": "VISIBILITY_PUBLIC", @@ -127,8 +127,8 @@ "signature": { "type": "TYPE_ED25519", "ed25519": { - "publicKey": "ObSsyF4CbcBWRkpeoAuY+FgmDqrSt03TC4auDU2U3fU=", - "signature": "cQVhPPiCjuBaiGb5VmdZB7I546Ys7Ye2/zuUlNDHhFF/33O1wgy/fG/5G37EgnnP2J8ePfyIXeC9kEZUe6a8BQ==" + "publicKey": "ySyOe0Rn5inKjNIBohVk3jnup8vkW1m/038QtW4Kcow=", + "signature": "Rmu0epS1Vzlix74H7OTOfitI03m+H0AipkkE8le4iZrzlxJDb0E6cSANOeniRUAx/DoWUrHbtXNZdAI9AUkfBw==" } } }, diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script4.json b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script4.json similarity index 87% rename from ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script4.json rename to ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script4.json index 8de6a80f7d7b9..829f5ab10fcd4 100644 --- a/ecosystem/indexer-grpc/indexer-test-transactions/json_transactions/scripted_transactions/simple_user_script4.json +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/json_transactions/scripted_transactions/simple_user_script4.json @@ -1,17 +1,17 @@ { "timestamp": { - "seconds": "1732752753", - "nanos": 464510000 + "seconds": "1737064556", + "nanos": 708247000 }, - "version": "113", + "version": "181", "info": { - "hash": "oYa+TMnfLyFeH3H2XEZgiBMLJ+DxSy6YcVcNy5J4JfY=", - "stateChangeHash": "OyOxxEbPllBNm8lOrnwFFsgBmXnX4HwKJQZTaJi9fkQ=", + "hash": "ub+aovjUFlh7ax9fj8RiGrz+KAnuOqqifHYq5IrdFiw=", + "stateChangeHash": "A00hAZ/Z/BIj28eNt1WXBu4zQ7tl8vHcYWox2neYVOA=", "eventRootHash": "J/kCueHhHqJXi8MVudrh82sOQ/pqY9TJ9VjLOdgel6I=", "gasUsed": "3", "success": true, "vmStatus": "Executed successfully", - "accumulatorRootHash": "88fXEFMqQhOcsrc6PVA33fJjASWpk2eaQIba6mXjoTw=", + "accumulatorRootHash": "aS6o0R209AyKHCNL1/2xEDynsQ224RfYKDIFGZ4NwNw=", "changes": [ { "type": "TYPE_WRITE_RESOURCE", @@ -60,18 +60,18 @@ "data": { "key": "\"0x619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935\"", "keyType": "address", - "value": "\"18446744073909011925\"", + "value": "\"18446744073909011725\"", "valueType": "u128" } } } ] }, - "epoch": "2", - "blockHeight": "53", + "epoch": "3", + "blockHeight": "87", "type": "TRANSACTION_TYPE_USER", "sizeInfo": { - "transactionBytes": 190, + "transactionBytes": 279, "eventSizeInfo": [ { "typeTagBytes": 63, @@ -99,13 +99,13 @@ "maxGasAmount": "4", "gasUnitPrice": "100", "expirationTimestampSecs": { - "seconds": "1732752784" + "seconds": "1737064587" }, "payload": { "type": "TYPE_SCRIPT_PAYLOAD", "scriptPayload": { "code": { - "bytecode": "oRzrCwcAAAoBBQAEAQYMAAAAAQEC", + "bytecode": "oRzrCwcAAAoEBQAEBwQOCBIgEDIfAQYMAAg8U0VMRj5fMARtYWlu//////////////////////////////////////////8UY29tcGlsYXRpb25fbWV0YWRhdGEJAAMyLjADMi4xAAABAwsAAQI=", "abi": { "name": "main", "visibility": "VISIBILITY_PUBLIC", @@ -128,7 +128,7 @@ "type": "TYPE_ED25519", "ed25519": { "publicKey": "7wW+3hX0IuFsAALjzui01DQVGNmcRpU1KhhpsHeYZPs=", - "signature": "X0k4xVGiytAI2CVRyLPIo2BHY7BG2q8+KXgSGIHfVucE0c6EXbrTDYUoba2cq0lVZukXNAxpgCInvDD/6gCmCw==" + "signature": "S3ZH56GcKPRlWec79GmC/SsXuwnicPmT7R4J/cqBkHoeAlfTIrr6HjzQ+ts0tZT6Fhzvlcn+jWZMcf9xC0hjAw==" } } }, diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/src/lib.rs b/ecosystem/indexer-grpc/indexer-test-transactions/src/lib.rs index e00d486bf15ce..d100e61f4fb7a 100644 --- a/ecosystem/indexer-grpc/indexer-test-transactions/src/lib.rs +++ b/ecosystem/indexer-grpc/indexer-test-transactions/src/lib.rs @@ -1,13 +1,13 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -include!(concat!(env!("OUT_DIR"), "/generate_transactions.rs")); +pub mod json_transactions; #[cfg(test)] mod tests { use super::*; use aptos_protos::transaction::v1::Transaction; - + use json_transactions::generated_transactions::IMPORTED_TESTNET_TXNS_5979639459_COIN_REGISTER; #[test] fn test_generate_transactions() { let json_bytes = IMPORTED_TESTNET_TXNS_5979639459_COIN_REGISTER; diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/README.md b/ecosystem/indexer-grpc/indexer-transaction-generator/README.md index 597850b618fff..dd3964f5c0be0 100644 --- a/ecosystem/indexer-grpc/indexer-transaction-generator/README.md +++ b/ecosystem/indexer-grpc/indexer-transaction-generator/README.md @@ -8,8 +8,8 @@ Under root folder, i.e., `aptos-core`, run ```bash cargo run -p aptos-indexer-transaction-generator -- \ - --testing-folder ecosystem/indexer-grpc/indexer-transaction-generator/example_tests \ - --output-folder ecosystem/indexer-grpc/indexer-transaction-generator/example_tests + --testing-folder ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions \ + --output-folder ecosystem/indexer-grpc/indexer-test-transactions/src ``` **You can also use absolute path, run(using binary as an example)** @@ -26,10 +26,10 @@ cargo run -p aptos-indexer-transaction-generator -- \ * One file called `testing_accounts.yaml`, which contains testing accounts used. ```yaml accounts: - - private_key: "0x99978d48e7b2d50d0a7a3273db0929447ae59635e71118fa256af654c0ce56c9" + a531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16: + private_key: "0x99978d48e7b2d50d0a7a3273db0929447ae59635e71118fa256af654c0ce56c9" public_key: "0x39b4acc85e026dc056464a5ea00b98f858260eaad2b74dd30b86ae0d4d94ddf5" account: a531b7fdd7917f73ca216d89a8d9ce0cf7e7cfb9086ca6f6cbf9521532748d16 - - ... ``` * One file called `imported_transactions.yaml`, which is used for importing transactions. @@ -47,15 +47,12 @@ cargo run -p aptos-indexer-transaction-generator -- \ ``` * One folder called `move_fixtures`, which contains move scripts and configs. * An example script transaction config looks like: - ```yaml + ```yaml transactions: - - output_name: simple_user_script1 - script_path: simple_user_script - sender_address: __ACCOUNT_A__ - - output_name: simple_user_script2 - script_path: simple_user_script2 - sender_address: __ACCOUNT_A__ - ``` + - output_name: fa_mint_transfer_burn + script_path: fa_mint_transfer_burn + sender_address: REPLACE_WITH_ACCOUNT_ADDRESS + ``` You can check the example [here](imported_transactions). @@ -66,7 +63,7 @@ Each sender_address specified in script transaction config is a place holder str the actual account address will be allocated by account manager. The accounts in `testing_accounts.yaml` will be used to run scripted transaction. -They are persistedin config so each scripted transaction's generated output stays consistent between +They are persisted in config so each scripted transaction's generated output stays consistent between `aptos-indexer-transaction-generator` runs. You can generate more testing accounts using Aptos CLI by running `aptos init --profile local`. diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/imported_transactions.yaml b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/imported_transactions.yaml index e01864698e7a7..6c55e14c83470 100644 --- a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/imported_transactions.yaml +++ b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/imported_transactions.yaml @@ -14,11 +14,13 @@ testnet: 5979639459: 5979639459_coin_register 5992795934: 5992795934_fa_activities 5523474016: 5523474016_validator_txn + 1200394037: 1200394037_fa_v2_frozen_event + 2646510387: 2646510387_concurrent_fa # fungible asset processor 4462417704: 4462417704_secondary_store_burnt 646928741: 646928741_no_events - + 769222973: 769222973_multisig mainnet: transaction_stream_endpoint: https://grpc.mainnet.aptoslabs.com:443 @@ -27,6 +29,8 @@ mainnet: # fungible asset processor 308783012: 308783012_fa_transfer 152449628: 152449628_coin_info_write + 999929475: 999929475_coin_and_fa_transfers + 508365567: 508365567_fa_v1_events # token v2 processor 1058723093: 1058723093_token_v1_mint_withdraw_deposit_events @@ -52,11 +56,13 @@ mainnet: # account processor 145959468: 145959468_account_transaction 423176063: 423176063_account_transaction_delete + 2212040150: 2212040150_transaction_without_events # ans processor 438536688: 438536688_ans_current_ans_lookup_v2 303690531: 303690531_ans_lookup_v2 1056780409: 1056780409_ans_current_ans_primary_name_v2 + 2080538: 2080538_ans_lookup_v1 # objects processor 578318306: 578318306_objects_write_resource @@ -68,6 +74,9 @@ mainnet: 1830706009: 1830706009_staker_governance_record 125600867: 125600867_stake_delegation_pool 4827964: 4827964_stake_initialize + 1831971037: 1831971037_stake_delegation_pool + 118489: 118489_proposal_vote + 124094774: 124094774_delegated_pool_balance # user transactions processor 685: 685_user_txn_ed25519 @@ -78,4 +87,10 @@ mainnet: 407418623: 407418623_user_txn_single_key_secp256k1_ecdsa 527013476: 527013476_user_txn_single_sender_secp256k1_ecdsa 2175935: 2175935_user_txn_multi_ed25519 - 976087151: 976087151_user_txn_single_sender_keyless \ No newline at end of file + 976087151: 976087151_user_txn_single_sender_keyless + 103958588: 103958588_multi_agents + + # account restoration processor + 2200077591: 2200077591_account_restoration_single_ed25519 + 2200077877: 2200077877_account_restoration_rotated_to_single_secp256k1 + 2200077800: 2200077800_account_restoration_rotated_to_multi_key \ No newline at end of file diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/fa_double_transfer/script.mv b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/fa_double_transfer/script.mv index 28c804ec247b2..62b6d0db00bac 100644 Binary files a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/fa_double_transfer/script.mv and b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/fa_double_transfer/script.mv differ diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/fa_mint_transfer_burn/script.mv b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/fa_mint_transfer_burn/script.mv index 41a1861767303..fb2f037eb8ce5 100644 Binary files a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/fa_mint_transfer_burn/script.mv and b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/fa_mint_transfer_burn/script.mv differ diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/simple_user_script/script.mv b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/simple_user_script/script.mv index fcc6c86488245..cc73966e1019f 100644 Binary files a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/simple_user_script/script.mv and b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/simple_user_script/script.mv differ diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/simple_user_script2/script.mv b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/simple_user_script2/script.mv index fcc6c86488245..cc73966e1019f 100644 Binary files a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/simple_user_script2/script.mv and b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/move_fixtures/simple_user_script2/script.mv differ diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/testing_accounts.yaml b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/testing_accounts.yaml index 1908d54c85c0b..e45407c369ce5 100644 --- a/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/testing_accounts.yaml +++ b/ecosystem/indexer-grpc/indexer-transaction-generator/imported_transactions/testing_accounts.yaml @@ -25,3 +25,7 @@ accounts: private_key: "0x9a2a409701f7ca41251cc2a4a0442ec44a450133b0d23564fc09191e763fd551" public_key: "0x294d3cca5f78884ad20a8e15845ead196418aaf49a2b52234c3ff88bfba83d22" account: d857c1f1dc5303ffcdc47205ebddc02d485c9dce619fd4d00055d86b58143363 + 213f9a82d31c2941281b98820c17d1bc40b23dd5f7917b98f30424b21f280d59: + private_key: "0xadb6a855124dc31943fe36ce99d254c3e03d598e6527f4cb487796baec576ea3" + public_key: "0xaeeac66dba7aa238f48a09b44f6a574b27aa51b29ec7366d2e8801802818def9" + account: 213f9a82d31c2941281b98820c17d1bc40b23dd5f7917b98f30424b21f280d59 diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/src/config.rs b/ecosystem/indexer-grpc/indexer-transaction-generator/src/config.rs index b674de63ccfbf..11137691336a7 100644 --- a/ecosystem/indexer-grpc/indexer-transaction-generator/src/config.rs +++ b/ecosystem/indexer-grpc/indexer-transaction-generator/src/config.rs @@ -1,12 +1,20 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{accont_manager::AccountManager, managed_node::ManagedNode}; +use crate::{ + accont_manager::AccountManager, + managed_node::ManagedNode, + transaction_code_builder::{ + TransactionCodeBuilder, IMPORTED_DEVNET_TXNS, IMPORTED_MAINNET_TXNS, IMPORTED_TESTNET_TXNS, + SCRIPTED_TRANSACTIONS_TXNS, + }, +}; use anyhow::Context; use clap::Parser; use serde::{Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, + fs, path::{Path, PathBuf}, }; use url::Url; @@ -32,7 +40,11 @@ pub struct IndexerCliArgs { impl IndexerCliArgs { pub async fn run(&self) -> anyhow::Result<()> { - let output_folder = convert_relative_path_to_absolute_path(&self.output_folder); + let output_folder = + convert_relative_path_to_absolute_path(&self.output_folder).join("json_transactions"); + if !output_folder.exists() { + tokio::fs::create_dir_all(&output_folder).await?; + } let testing_folder = convert_relative_path_to_absolute_path(&self.testing_folder); // Run the transaction importer. @@ -140,7 +152,47 @@ impl IndexerCliArgs { ))?; } // Stop the localnet. - managed_node.stop().await + managed_node.stop().await?; + + // Using the builder pattern to construct the code + let code = TransactionCodeBuilder::new() + .add_license_in_comments() + .add_directory( + output_folder.join(IMPORTED_MAINNET_TXNS).as_path(), + IMPORTED_MAINNET_TXNS, + false, + ) + .add_directory( + output_folder.join(IMPORTED_TESTNET_TXNS).as_path(), + IMPORTED_TESTNET_TXNS, + false, + ) + .add_directory( + output_folder.join(IMPORTED_DEVNET_TXNS).as_path(), + IMPORTED_DEVNET_TXNS, + false, + ) + .add_directory( + output_folder.join(SCRIPTED_TRANSACTIONS_TXNS).as_path(), + SCRIPTED_TRANSACTIONS_TXNS, + true, + ) + .add_transaction_name_function() + .build(); + + let dest_path = output_folder.join("generated_transactions.rs"); + + match fs::write(dest_path.clone(), code) { + Ok(_) => { + println!("Successfully generated the transactions code."); + Ok(()) + }, + Err(e) => Err(anyhow::anyhow!( + "Failed to generate the transactions code for dest_path:{:?}, {:?}", + dest_path, + e + )), + } } } @@ -177,9 +229,9 @@ impl TransactionImporterConfig { for (network_name, network_config) in self.configs.iter() { // Modify the output path by appending the network name to the base path let modified_output_path = match network_name.as_str() { - "mainnet" => output_path.join("imported_mainnet_txns"), - "testnet" => output_path.join("imported_testnet_txns"), - "devnet" => output_path.join("imported_devnet_txns"), + "mainnet" => output_path.join(IMPORTED_MAINNET_TXNS), + "testnet" => output_path.join(IMPORTED_TESTNET_TXNS), + "devnet" => output_path.join(IMPORTED_DEVNET_TXNS), _ => { return Err(anyhow::anyhow!( "[Transaction Importer] Unknown network: {}", diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/src/lib.rs b/ecosystem/indexer-grpc/indexer-transaction-generator/src/lib.rs index b30a5b2879f0b..1d00f0249352c 100644 --- a/ecosystem/indexer-grpc/indexer-transaction-generator/src/lib.rs +++ b/ecosystem/indexer-grpc/indexer-transaction-generator/src/lib.rs @@ -5,4 +5,5 @@ pub mod accont_manager; pub mod config; pub mod managed_node; pub mod script_transaction_generator; +pub mod transaction_code_builder; pub mod transaction_importer; diff --git a/ecosystem/indexer-grpc/indexer-transaction-generator/src/script_transaction_generator.rs b/ecosystem/indexer-grpc/indexer-transaction-generator/src/script_transaction_generator.rs index 7a8431236ca34..71f6fd7046fc7 100644 --- a/ecosystem/indexer-grpc/indexer-transaction-generator/src/script_transaction_generator.rs +++ b/ecosystem/indexer-grpc/indexer-transaction-generator/src/script_transaction_generator.rs @@ -118,7 +118,7 @@ impl ScriptTransactions { .join("build") .join(package_name) .join("bytecode_scripts") - .join("main.mv"); + .join("main_0.mv"); let cmd = create_run_script_cmd(compiled_build_path); let transaction_summary = cmd.execute().await.context(format!( diff --git a/ecosystem/indexer-grpc/indexer-test-transactions/build.rs b/ecosystem/indexer-grpc/indexer-transaction-generator/src/transaction_code_builder.rs similarity index 65% rename from ecosystem/indexer-grpc/indexer-test-transactions/build.rs rename to ecosystem/indexer-grpc/indexer-transaction-generator/src/transaction_code_builder.rs index ede1ca06eabbc..a3cb6d637fff7 100644 --- a/ecosystem/indexer-grpc/indexer-test-transactions/build.rs +++ b/ecosystem/indexer-grpc/indexer-transaction-generator/src/transaction_code_builder.rs @@ -1,12 +1,13 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use std::{env, fs, path::Path}; +use std::{fs, path::Path}; + +pub const IMPORTED_MAINNET_TXNS: &str = "imported_mainnet_txns"; +pub const IMPORTED_TESTNET_TXNS: &str = "imported_testnet_txns"; +pub const IMPORTED_DEVNET_TXNS: &str = "imported_devnet_txns"; +pub const SCRIPTED_TRANSACTIONS_TXNS: &str = "scripted_transactions"; -const IMPORTED_MAINNET_TXNS: &str = "imported_mainnet_txns"; -const IMPORTED_TESTNET_TXNS: &str = "imported_testnet_txns"; -const IMPORTED_DEVNET_TXNS: &str = "imported_devnet_txns"; -const SCRIPTED_TRANSACTIONS_TXNS: &str = "scripted_transactions"; #[derive(Default)] pub struct TransactionCodeBuilder { // Holds the generated Rust code for transaction constants @@ -20,16 +21,26 @@ impl TransactionCodeBuilder { Self::default() } + /** + * Adds a directory of JSON files to the transaction code builder. + * + * @param src_dir: The source directory containing the JSON files + * @param dir_name: The name of the directory to be created in the `json_transactions` directory + * @param module_name: The name of the module to be used in the constant names + * @param generate_name_function: Whether to generate a transaction name lookup function + */ pub fn add_directory( mut self, - dir_name: &str, + json_dir: &Path, module_name: &str, generate_name_function: bool, ) -> Self { - let json_dir = Path::new("json_transactions").join(dir_name); let mut all_constants = String::new(); - // Iterates over all files in the directory + if !json_dir.exists() { + let _ = fs::create_dir_all(json_dir); + } + for entry in fs::read_dir(json_dir).expect("Failed to read directory") { let entry = entry.expect("Failed to get directory entry"); let path = entry.path(); @@ -46,10 +57,10 @@ impl TransactionCodeBuilder { // Generates a constant for the JSON file and appends it to the `transactions_code` string self.transactions_code.push_str(&format!( r#" - pub const {const_name}: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/json_transactions/{dir_name}/{file_name}.json")); + pub const {const_name}: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/json_transactions/{dir_name}/{file_name}.json")); "#, const_name = const_name, - dir_name = dir_name, + dir_name = module_name, file_name = file_name, )); @@ -79,6 +90,18 @@ impl TransactionCodeBuilder { self } + pub fn add_license_in_comments(mut self) -> Self { + self.transactions_code.push_str( + r#" + // Copyright (c) Aptos Foundation + // SPDX-License-Identifier: Apache-2.0 + #![allow(dead_code)] + #![allow(unused_variables)] + "#, + ); + self + } + // Adds the transaction name lookup function if any name match arms were created pub fn add_transaction_name_function(mut self) -> Self { if !self.name_function_code.is_empty() { @@ -106,33 +129,3 @@ impl TransactionCodeBuilder { self.transactions_code } } - -fn main() { - let out_dir = env::var("OUT_DIR").unwrap(); - let dest_path = Path::new(&out_dir).join("generate_transactions.rs"); - - // Create necessary directories if missing - create_directory_if_missing(&format!("json_transactions/{}", IMPORTED_MAINNET_TXNS)); - create_directory_if_missing(&format!("json_transactions/{}", IMPORTED_TESTNET_TXNS)); - create_directory_if_missing(&format!("json_transactions/{}", IMPORTED_DEVNET_TXNS)); - create_directory_if_missing(&format!("json_transactions/{}", SCRIPTED_TRANSACTIONS_TXNS)); - - // Using the builder pattern to construct the code - let code = TransactionCodeBuilder::new() - .add_directory(IMPORTED_MAINNET_TXNS, IMPORTED_MAINNET_TXNS, false) - .add_directory(IMPORTED_TESTNET_TXNS, IMPORTED_TESTNET_TXNS, false) - .add_directory(IMPORTED_DEVNET_TXNS, IMPORTED_DEVNET_TXNS, false) - .add_directory(SCRIPTED_TRANSACTIONS_TXNS, SCRIPTED_TRANSACTIONS_TXNS, true) - .add_transaction_name_function() - .build(); - - fs::write(dest_path, code).unwrap(); -} - -// Helper function to create directories if they are missing -fn create_directory_if_missing(dir: &str) { - let path = Path::new(dir); - if !path.exists() { - fs::create_dir_all(path).expect("Failed to create directory"); - } -} diff --git a/execution/executor-benchmark/src/db_generator.rs b/execution/executor-benchmark/src/db_generator.rs index fff814fec00a3..13abbe247aa0e 100644 --- a/execution/executor-benchmark/src/db_generator.rs +++ b/execution/executor-benchmark/src/db_generator.rs @@ -81,7 +81,7 @@ pub(crate) fn bootstrap_with_genesis( issuer: get_sample_iss(), jwk: JWK::RSA(get_sample_jwk()), }]; - config.keyless_groth16_vk_override = Some(Groth16VerificationKey::from( + config.keyless_groth16_vk = Some(Groth16VerificationKey::from( &TEST_GROTH16_SETUP.prepared_vk, )); }))); diff --git a/execution/executor-benchmark/src/lib.rs b/execution/executor-benchmark/src/lib.rs index 4f39ba8cc7e53..3bdfd2a62a332 100644 --- a/execution/executor-benchmark/src/lib.rs +++ b/execution/executor-benchmark/src/lib.rs @@ -1032,7 +1032,7 @@ mod tests { let parent_block_id = vm_executor.committed_block_id(); let block_id = HashValue::random(); vm_executor - .execute_and_state_checkpoint( + .execute_and_update_state( (block_id, vec![txn.clone()]).into(), parent_block_id, BENCHMARKS_BLOCK_EXECUTOR_ONCHAIN_CONFIG, @@ -1053,7 +1053,7 @@ mod tests { let parent_block_id = other_executor.committed_block_id(); let block_id = HashValue::random(); other_executor - .execute_and_state_checkpoint( + .execute_and_update_state( (block_id, vec![txn]).into(), parent_block_id, BENCHMARKS_BLOCK_EXECUTOR_ONCHAIN_CONFIG, diff --git a/execution/executor-benchmark/src/transaction_executor.rs b/execution/executor-benchmark/src/transaction_executor.rs index 36b5c4bb6c95d..7012439617801 100644 --- a/execution/executor-benchmark/src/transaction_executor.rs +++ b/execution/executor-benchmark/src/transaction_executor.rs @@ -64,7 +64,7 @@ where { let _timer = TIMER.with_label_values(&["execute"]).start_timer(); self.executor - .execute_and_state_checkpoint( + .execute_and_update_state( executable_block, self.parent_block_id, BENCHMARKS_BLOCK_EXECUTOR_ONCHAIN_CONFIG, diff --git a/execution/executor-types/src/execution_output.rs b/execution/executor-types/src/execution_output.rs index 0708274f60c98..b500dfe5a818d 100644 --- a/execution/executor-types/src/execution_output.rs +++ b/execution/executor-types/src/execution_output.rs @@ -10,7 +10,7 @@ use crate::{ }; use aptos_drop_helper::DropHelper; use aptos_storage_interface::state_store::{ - state_delta::StateDelta, state_view::cached_state_view::StateCache, + state::LedgerState, state_view::cached_state_view::ShardedStateCache, }; use aptos_types::{ contract_event::ContractEvent, @@ -36,14 +36,18 @@ impl ExecutionOutput { to_commit: TransactionsToKeep, to_discard: TransactionsWithOutput, to_retry: TransactionsWithOutput, - state_cache: StateCache, + result_state: LedgerState, + state_reads: ShardedStateCache, block_end_info: Option, next_epoch_state: Option, subscribable_events: Planned>, ) -> Self { + let next_version = first_version + to_commit.len() as Version; + assert_eq!(next_version, result_state.latest().next_version()); if is_block { // If it's a block, ensure it ends with state checkpoint. assert!(to_commit.is_empty() || to_commit.ends_with_sole_checkpoint()); + assert!(result_state.is_checkpoint()); } else { // If it's not, there shouldn't be any transaction to be discarded or retried. assert!(to_discard.is_empty() && to_retry.is_empty()); @@ -56,14 +60,15 @@ impl ExecutionOutput { to_commit, to_discard, to_retry, - state_cache, + result_state, + state_reads, block_end_info, next_epoch_state, subscribable_events, }) } - pub fn new_empty(state: Arc) -> Self { + pub fn new_empty(state: LedgerState) -> Self { Self::new_impl(Inner { is_block: false, first_version: state.next_version(), @@ -71,7 +76,8 @@ impl ExecutionOutput { to_commit: TransactionsToKeep::new_empty(), to_discard: TransactionsWithOutput::new_empty(), to_retry: TransactionsWithOutput::new_empty(), - state_cache: StateCache::new_empty(state.current.clone()), + state_reads: ShardedStateCache::new_empty(state.version()), + result_state: state, block_end_info: None, next_epoch_state: None, subscribable_events: Planned::ready(vec![]), @@ -88,7 +94,8 @@ impl ExecutionOutput { to_commit: TransactionsToKeep::new_dummy_success(txns), to_discard: TransactionsWithOutput::new_empty(), to_retry: TransactionsWithOutput::new_empty(), - state_cache: StateCache::new_dummy(), + result_state: LedgerState::new_empty(), + state_reads: ShardedStateCache::new_empty(None), block_end_info: None, next_epoch_state: None, subscribable_events: Planned::ready(vec![]), @@ -107,7 +114,8 @@ impl ExecutionOutput { to_commit: TransactionsToKeep::new_empty(), to_discard: TransactionsWithOutput::new_empty(), to_retry: TransactionsWithOutput::new_empty(), - state_cache: StateCache::new_dummy(), + result_state: self.result_state.clone(), + state_reads: ShardedStateCache::new_empty(self.next_version().checked_sub(1)), block_end_info: None, next_epoch_state: self.next_epoch_state.clone(), subscribable_events: Planned::ready(vec![]), @@ -146,10 +154,11 @@ pub struct Inner { pub to_discard: TransactionsWithOutput, pub to_retry: TransactionsWithOutput, - /// Carries the frozen base state view, so all in-mem nodes involved won't drop before the - /// execution result is processed; as well as all the accounts touched during execution, together - /// with their proofs. - pub state_cache: StateCache, + pub result_state: LedgerState, + /// State items read during execution, useful for calculating the state storge usage and + /// indices used by the db pruner. + pub state_reads: ShardedStateCache, + /// Optional StateCheckpoint payload pub block_end_info: Option, /// Optional EpochState payload. diff --git a/execution/executor-types/src/lib.rs b/execution/executor-types/src/lib.rs index fab455b1c7c77..36125e0c86ca5 100644 --- a/execution/executor-types/src/lib.rs +++ b/execution/executor-types/src/lib.rs @@ -5,7 +5,7 @@ use anyhow::Result; use aptos_crypto::HashValue; -use aptos_scratchpad::{ProofRead, SparseMerkleTree}; +use aptos_scratchpad::SparseMerkleTree; use aptos_types::{ account_config::{NEW_EPOCH_EVENT_MOVE_TYPE_TAG, NEW_EPOCH_EVENT_V2_MOVE_TYPE_TAG}, block_executor::{config::BlockExecutorConfigFromOnchain, partitioner::ExecutableBlock}, @@ -13,7 +13,6 @@ use aptos_types::{ dkg::DKG_START_EVENT_MOVE_TYPE_TAG, jwks::OBSERVED_JWK_UPDATED_MOVE_TYPE_TAG, ledger_info::LedgerInfoWithSignatures, - proof::SparseMerkleProofExt, state_store::{state_key::StateKey, state_value::StateValue}, transaction::{ Transaction, TransactionInfo, TransactionListWithProof, TransactionOutputListWithProof, @@ -25,7 +24,7 @@ pub use error::{ExecutorError, ExecutorResult}; pub use ledger_update_output::LedgerUpdateOutput; use state_compute_result::StateComputeResult; use std::{ - collections::{BTreeSet, HashMap}, + collections::BTreeSet, ops::Deref, sync::{ atomic::{AtomicBool, Ordering}, @@ -135,12 +134,12 @@ pub trait BlockExecutorTrait: Send + Sync { onchain_config: BlockExecutorConfigFromOnchain, ) -> ExecutorResult { let block_id = block.block_id; - self.execute_and_state_checkpoint(block, parent_block_id, onchain_config)?; + self.execute_and_update_state(block, parent_block_id, onchain_config)?; self.ledger_update(block_id, parent_block_id) } /// Executes a block and returns the state checkpoint output. - fn execute_and_state_checkpoint( + fn execute_and_update_state( &self, block: ExecutableBlock, parent_block_id: HashValue, @@ -266,28 +265,6 @@ pub struct ChunkCommitNotification { pub reconfiguration_occurred: bool, } -pub struct ProofReader<'a> { - proofs: Option<&'a HashMap>, -} - -impl<'a> ProofReader<'a> { - pub fn new(proofs: &'a HashMap) -> Self { - Self { - proofs: Some(proofs), - } - } - - pub fn new_empty() -> Self { - Self { proofs: None } - } -} - -impl<'a> ProofRead for ProofReader<'a> { - fn get_proof(&self, key: HashValue) -> Option<&SparseMerkleProofExt> { - self.proofs.and_then(|proofs| proofs.get(&key)) - } -} - /// Used in both state sync and consensus to filter the txn events that should be subscribable by node components. pub fn should_forward_to_subscription_service(event: &ContractEvent) -> bool { let type_tag = event.type_tag(); diff --git a/execution/executor-types/src/state_checkpoint_output.rs b/execution/executor-types/src/state_checkpoint_output.rs index 61f5bb597a8d2..2e1b49201e3d1 100644 --- a/execution/executor-types/src/state_checkpoint_output.rs +++ b/execution/executor-types/src/state_checkpoint_output.rs @@ -5,13 +5,11 @@ use aptos_crypto::HashValue; use aptos_drop_helper::DropHelper; -use aptos_storage_interface::state_store::{ - sharded_state_updates::ShardedStateUpdates, state_delta::StateDelta, -}; +use aptos_storage_interface::state_store::state_summary::LedgerStateSummary; use derive_more::Deref; use std::sync::Arc; -#[derive(Clone, Debug, Default, Deref)] +#[derive(Clone, Debug, Deref)] pub struct StateCheckpointOutput { #[deref] inner: Arc>, @@ -19,30 +17,24 @@ pub struct StateCheckpointOutput { impl StateCheckpointOutput { pub fn new( - parent_state: Arc, - result_state: Arc, - state_updates_before_last_checkpoint: Option, + state_summary: LedgerStateSummary, state_checkpoint_hashes: Vec>, ) -> Self { Self::new_impl(Inner { - parent_state, - result_state, - state_updates_before_last_checkpoint, + state_summary, state_checkpoint_hashes, }) } - pub fn new_empty(state: Arc) -> Self { + pub fn new_empty(parent_state_summary: LedgerStateSummary) -> Self { Self::new_impl(Inner { - parent_state: state.clone(), - result_state: state, - state_updates_before_last_checkpoint: None, + state_summary: parent_state_summary, state_checkpoint_hashes: vec![], }) } pub fn new_dummy() -> Self { - Self::new_empty(Arc::new(StateDelta::new_empty())) + Self::new_empty(LedgerStateSummary::new_empty()) } fn new_impl(inner: Inner) -> Self { @@ -52,14 +44,12 @@ impl StateCheckpointOutput { } pub fn reconfig_suffix(&self) -> Self { - Self::new_empty(self.result_state.clone()) + Self::new_empty(self.state_summary.clone()) } } -#[derive(Debug, Default)] +#[derive(Debug)] pub struct Inner { - pub parent_state: Arc, - pub result_state: Arc, - pub state_updates_before_last_checkpoint: Option, + pub state_summary: LedgerStateSummary, pub state_checkpoint_hashes: Vec>, } diff --git a/execution/executor-types/src/state_compute_result.rs b/execution/executor-types/src/state_compute_result.rs index 5b350ccbfbe6e..ec370fd5ecfb8 100644 --- a/execution/executor-types/src/state_compute_result.rs +++ b/execution/executor-types/src/state_compute_result.rs @@ -161,14 +161,10 @@ impl StateComputeResult { transactions: &self.execution_output.to_commit.transactions, transaction_outputs: &self.execution_output.to_commit.transaction_outputs, transaction_infos: &self.ledger_update_output.transaction_infos, - base_state_version: self.state_checkpoint_output.parent_state.base_version, - latest_in_memory_state: &self.state_checkpoint_output.result_state, + state: &self.execution_output.result_state, + state_summary: &self.state_checkpoint_output.state_summary, state_update_refs: self.execution_output.to_commit.state_update_refs(), - state_updates_until_last_checkpoint: self - .state_checkpoint_output - .state_updates_before_last_checkpoint - .as_ref(), - sharded_state_cache: Some(&self.execution_output.state_cache.sharded_state_cache), + state_reads: &self.execution_output.state_reads, is_reconfig: self.execution_output.next_epoch_state.is_some(), } } diff --git a/execution/executor-types/src/transactions_with_output.rs b/execution/executor-types/src/transactions_with_output.rs index f69bcef083453..051c8f21b64a5 100644 --- a/execution/executor-types/src/transactions_with_output.rs +++ b/execution/executor-types/src/transactions_with_output.rs @@ -2,9 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::metrics::TIMER; +use anyhow::{ensure, Result}; use aptos_metrics_core::TimerHelper; -use aptos_storage_interface::state_store::sharded_state_update_refs::ShardedStateUpdateRefs; -use aptos_types::transaction::{Transaction, TransactionOutput}; +use aptos_storage_interface::state_store::state_update_refs::StateUpdateRefs; +use aptos_types::transaction::{Transaction, TransactionOutput, Version}; use itertools::izip; use std::{ fmt::{Debug, Formatter}, @@ -54,63 +55,68 @@ impl TransactionsWithOutput { #[ouroboros::self_referencing] pub struct TransactionsToKeep { transactions_with_output: TransactionsWithOutput, - last_checkpoint_index: Option, is_reconfig: bool, #[borrows(transactions_with_output)] #[covariant] - state_update_refs: ShardedStateUpdateRefs<'this>, + state_update_refs: StateUpdateRefs<'this>, } impl TransactionsToKeep { - pub fn index(transactions_with_output: TransactionsWithOutput, is_reconfig: bool) -> Self { + pub fn index( + first_version: Version, + transactions_with_output: TransactionsWithOutput, + is_reconfig: bool, + ) -> Self { let _timer = TIMER.timer_with(&["transactions_to_keep__index"]); - let num_write_sets = transactions_with_output.len(); - let last_checkpoint_index = - Self::get_last_checkpoint_index(is_reconfig, &transactions_with_output.transactions); TransactionsToKeepBuilder { transactions_with_output, is_reconfig, - last_checkpoint_index, state_update_refs_builder: |transactions_with_output| { let write_sets = transactions_with_output .transaction_outputs .iter() .map(TransactionOutput::write_set); - ShardedStateUpdateRefs::index_write_sets(write_sets, num_write_sets) + let last_checkpoint_index = Self::get_last_checkpoint_index( + is_reconfig, + &transactions_with_output.transactions, + ); + StateUpdateRefs::index_write_sets( + first_version, + write_sets, + transactions_with_output.len(), + last_checkpoint_index, + ) }, } .build() } pub fn make( + first_version: Version, transactions: Vec, transaction_outputs: Vec, is_reconfig: bool, ) -> Self { let txns_with_output = TransactionsWithOutput::new(transactions, transaction_outputs); - Self::index(txns_with_output, is_reconfig) + Self::index(first_version, txns_with_output, is_reconfig) } pub fn new_empty() -> Self { - Self::make(vec![], vec![], false) + Self::make(0, vec![], vec![], false) } pub fn new_dummy_success(txns: Vec) -> Self { let txn_outputs = vec![TransactionOutput::new_empty_success(); txns.len()]; - Self::make(txns, txn_outputs, false) - } - - pub fn state_update_refs(&self) -> &ShardedStateUpdateRefs { - self.borrow_state_update_refs() + Self::make(0, txns, txn_outputs, false) } pub fn is_reconfig(&self) -> bool { *self.borrow_is_reconfig() } - pub fn last_checkpoint_index(&self) -> Option { - *self.borrow_last_checkpoint_index() + pub fn state_update_refs(&self) -> &StateUpdateRefs { + self.borrow_state_update_refs() } pub fn ends_with_sole_checkpoint(&self) -> bool { @@ -140,6 +146,29 @@ impl TransactionsToKeep { .iter() .rposition(Transaction::is_non_reconfig_block_ending) } + + pub fn ensure_at_most_one_checkpoint(&self) -> Result<()> { + let _timer = TIMER.timer_with(&["unexpected__ensure_at_most_one_checkpoint"]); + + let mut total = self + .transactions + .iter() + .filter(|t| t.is_non_reconfig_block_ending()) + .count(); + if self.is_reconfig() { + total += self + .transactions + .last() + .map_or(0, |t| !t.is_non_reconfig_block_ending() as usize); + } + + ensure!( + total <= 1, + "Expecting at most one checkpoint, found {}", + total, + ); + Ok(()) + } } impl Deref for TransactionsToKeep { diff --git a/execution/executor/Cargo.toml b/execution/executor/Cargo.toml index 2b8a176beb2fb..8a980cf73715a 100644 --- a/execution/executor/Cargo.toml +++ b/execution/executor/Cargo.toml @@ -25,14 +25,12 @@ aptos-indexer-grpc-table-info = { workspace = true } aptos-infallible = { workspace = true } aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } -aptos-scratchpad = { workspace = true } aptos-sdk = { workspace = true } aptos-storage-interface = { workspace = true } aptos-types = { workspace = true } aptos-vm = { workspace = true } bcs = { workspace = true } bytes = { workspace = true } -dashmap = { workspace = true } fail = { workspace = true } itertools = { workspace = true } move-core-types = { workspace = true } @@ -45,9 +43,7 @@ aptos-cached-packages = { workspace = true } aptos-config = { workspace = true } aptos-db = { workspace = true } aptos-db-indexer = { workspace = true, features = ["fuzzing"] } -aptos-db-indexer-schemas = { workspace = true, features = ["fuzzing"] } aptos-executor-test-helpers = { workspace = true } -aptos-genesis = { workspace = true } aptos-storage-interface = { workspace = true } aptos-temppath = { workspace = true } aptos-types = { workspace = true, features = ["testing"] } diff --git a/execution/executor/src/block_executor/block_tree/mod.rs b/execution/executor/src/block_executor/block_tree/mod.rs index 6c13788fd51ff..a71c890204635 100644 --- a/execution/executor/src/block_executor/block_tree/mod.rs +++ b/execution/executor/src/block_executor/block_tree/mod.rs @@ -222,10 +222,7 @@ impl BlockTree { ledger_info.consensus_block_id() }; - let output = PartialStateComputeResult::new_empty( - ledger_summary.state().clone(), - ledger_summary.txn_accumulator().clone(), - ); + let output = PartialStateComputeResult::new_empty(ledger_summary); block_lookup.fetch_or_add_block(id, output, None) } @@ -260,8 +257,9 @@ impl BlockTree { last_committed_block }; root.output - .expect_result_state() - .current + .expect_state_checkpoint_output() + .state_summary + .global_state_summary .log_generation("block_tree_base"); let old_root = std::mem::replace(&mut *self.root.lock(), root); diff --git a/execution/executor/src/block_executor/block_tree/test.rs b/execution/executor/src/block_executor/block_tree/test.rs index 060cab8dd228e..0411533f677d5 100644 --- a/execution/executor/src/block_executor/block_tree/test.rs +++ b/execution/executor/src/block_executor/block_tree/test.rs @@ -39,11 +39,7 @@ fn id(index: u64) -> HashValue { } fn empty_block() -> PartialStateComputeResult { - let result_view = LedgerSummary::new_empty(); - PartialStateComputeResult::new_empty( - result_view.state().clone(), - result_view.transaction_accumulator.clone(), - ) + PartialStateComputeResult::new_empty(LedgerSummary::new_empty()) } fn gen_ledger_info(block_id: HashValue, reconfig: bool) -> LedgerInfo { diff --git a/execution/executor/src/block_executor/mod.rs b/execution/executor/src/block_executor/mod.rs index 40c90751bcec7..e622daaa0063b 100644 --- a/execution/executor/src/block_executor/mod.rs +++ b/execution/executor/src/block_executor/mod.rs @@ -27,8 +27,8 @@ use aptos_infallible::RwLock; use aptos_logger::prelude::*; use aptos_metrics_core::{IntGaugeHelper, TimerHelper}; use aptos_storage_interface::{ - state_store::state_view::{ - async_proof_fetcher::AsyncProofFetcher, cached_state_view::CachedStateView, + state_store::{ + state_summary::ProvableStateSummary, state_view::cached_state_view::CachedStateView, }, DbReaderWriter, }; @@ -93,7 +93,7 @@ where Ok(()) } - fn execute_and_state_checkpoint( + fn execute_and_update_state( &self, block: ExecutableBlock, parent_block_id: HashValue, @@ -106,7 +106,7 @@ where .read() .as_ref() .expect("BlockExecutor is not reset") - .execute_and_state_checkpoint(block, parent_block_id, onchain_config) + .execute_and_update_state(block, parent_block_id, onchain_config) } fn ledger_update( @@ -179,7 +179,7 @@ where self.block_tree.root_block().id } - fn execute_and_state_checkpoint( + fn execute_and_update_state( &self, block: ExecutableBlock, parent_block_id: HashValue, @@ -204,66 +204,42 @@ where "execute_block" ); let committed_block_id = self.committed_block_id(); - let (execution_output, state_checkpoint_output) = + let execution_output = if parent_block_id != committed_block_id && parent_output.has_reconfiguration() { // ignore reconfiguration suffix, even if the block is non-empty info!( LogSchema::new(LogEntry::BlockExecutor).block_id(block_id), "reconfig_descendant_block_received" ); - ( - parent_output.execution_output.reconfig_suffix(), - parent_output - .expect_state_checkpoint_output() - .reconfig_suffix(), - ) + parent_output.execution_output.reconfig_suffix() } else { let state_view = { - let _timer = OTHER_TIMERS.timer_with(&["verified_state_view"]); - + let _timer = OTHER_TIMERS.timer_with(&["get_state_view"]); CachedStateView::new( StateViewId::BlockExecution { block_id }, Arc::clone(&self.db.reader), - parent_output.execution_output.next_version(), - parent_output.expect_result_state().current.clone(), - Arc::new(AsyncProofFetcher::new(self.db.reader.clone())), + parent_output.result_state().latest().clone(), )? }; - let execution_output = { - let _timer = GET_BLOCK_EXECUTION_OUTPUT_BY_EXECUTING.start_timer(); - fail_point!("executor::block_executor_execute_block", |_| { - Err(ExecutorError::from(anyhow::anyhow!( - "Injected error in block_executor_execute_block" - ))) - }); - - DoGetExecutionOutput::by_transaction_execution( - &self.block_executor, - transactions, - state_view, - onchain_config.clone(), - TransactionSliceMetadata::block(parent_block_id, block_id), - )? - }; - - let _timer = OTHER_TIMERS.timer_with(&["state_checkpoint"]); - - let state_checkpoint_output = THREAD_MANAGER.get_exe_cpu_pool().install(|| { - fail_point!("executor::block_state_checkpoint", |_| { - Err(anyhow::anyhow!("Injected error in block state checkpoint.")) - }); - DoStateCheckpoint::run( - &execution_output, - parent_output.expect_result_state(), - Option::>::None, - ) - })?; - (execution_output, state_checkpoint_output) + let _timer = GET_BLOCK_EXECUTION_OUTPUT_BY_EXECUTING.start_timer(); + fail_point!("executor::block_executor_execute_block", |_| { + Err(ExecutorError::from(anyhow::anyhow!( + "Injected error in block_executor_execute_block" + ))) + }); + + DoGetExecutionOutput::by_transaction_execution( + &self.block_executor, + transactions, + parent_output.result_state(), + state_view, + onchain_config.clone(), + TransactionSliceMetadata::block(parent_block_id, block_id), + )? }; - let output = PartialStateComputeResult::new(execution_output); - output.set_state_checkpoint_output(state_checkpoint_output); + let output = PartialStateComputeResult::new(execution_output); let _ = self .block_tree .add_block(parent_block_id, block_id, output)?; @@ -291,33 +267,53 @@ where // At this point of time two things must happen // 1. The block tree must also have the current block id with or without the ledger update output. // 2. We must have the ledger update output of the parent block. - let parent_output = parent_block.output.expect_ledger_update_output(); - let parent_accumulator = parent_output.txn_accumulator(); let block = block_vec.pop().expect("Must exist").unwrap(); - let output = &block.output; parent_block.ensure_has_child(block_id)?; + let output = &block.output; + let parent_out = &parent_block.output; + + // TODO(aldenhu): remove, assuming no retries. if let Some(complete_result) = block.output.get_complete_result() { + info!(block_id = block_id, "ledger_update already done."); return Ok(complete_result); } - let output = - if parent_block_id != committed_block_id && parent_block.output.has_reconfiguration() { - info!( - LogSchema::new(LogEntry::BlockExecutor).block_id(block_id), - "reconfig_descendant_block_received" - ); - parent_output.reconfig_suffix() - } else { - THREAD_MANAGER.get_non_exe_cpu_pool().install(|| { - DoLedgerUpdate::run( - &output.execution_output, - output.expect_state_checkpoint_output(), - parent_accumulator.clone(), - ) - })? - }; - - block.output.set_ledger_update_output(output); + if parent_block_id != committed_block_id && parent_out.has_reconfiguration() { + info!(block_id = block_id, "ledger_update for reconfig suffix."); + + // Parent must have done all state checkpoint and ledger update since this method + // is being called. + output.set_state_checkpoint_output( + parent_out + .expect_state_checkpoint_output() + .reconfig_suffix(), + ); + output.set_ledger_update_output( + parent_out.expect_ledger_update_output().reconfig_suffix(), + ); + } else { + THREAD_MANAGER.get_non_exe_cpu_pool().install(|| { + // TODO(aldenhu): remove? no known strategy to recover from this failure + fail_point!("executor::block_state_checkpoint", |_| { + Err(anyhow::anyhow!("Injected error in block state checkpoint.")) + }); + output.set_state_checkpoint_output(DoStateCheckpoint::run( + &output.execution_output, + parent_block.output.expect_result_state_summary(), + &ProvableStateSummary::new_persisted(self.db.reader.as_ref())?, + None, + )?); + output.set_ledger_update_output(DoLedgerUpdate::run( + &output.execution_output, + output.expect_state_checkpoint_output(), + parent_out + .expect_ledger_update_output() + .transaction_accumulator + .clone(), + )?); + Result::<_>::Ok(()) + })?; + } Ok(block.output.expect_complete_result()) } diff --git a/execution/executor/src/chunk_executor/chunk_commit_queue.rs b/execution/executor/src/chunk_executor/chunk_commit_queue.rs index 14586ce250721..e12f9ace5f051 100644 --- a/execution/executor/src/chunk_executor/chunk_commit_queue.rs +++ b/execution/executor/src/chunk_executor/chunk_commit_queue.rs @@ -6,12 +6,17 @@ use crate::{ chunk_executor::chunk_result_verifier::ChunkResultVerifier, + metrics::CHUNK_OTHER_TIMERS, types::{ executed_chunk::ExecutedChunk, partial_state_compute_result::PartialStateComputeResult, }, }; use anyhow::{anyhow, ensure, Result}; -use aptos_storage_interface::{state_store::state_delta::StateDelta, DbReader, LedgerSummary}; +use aptos_metrics_core::TimerHelper; +use aptos_storage_interface::{ + state_store::{state::LedgerState, state_summary::LedgerStateSummary}, + DbReader, LedgerSummary, +}; use aptos_types::{proof::accumulator::InMemoryTransactionAccumulator, transaction::Version}; use std::{collections::VecDeque, sync::Arc}; @@ -29,11 +34,13 @@ pub(crate) struct ChunkToUpdateLedger { /// ... | to_commit | to_update_ledger | ---> (txn version increases) /// \ \ /// \ latest_state +/// latest_state_summary /// latest_txn_accumulator /// pub struct ChunkCommitQueue { /// Notice that latest_state and latest_txn_accumulator are at different versions. - latest_state: Arc, + latest_state: LedgerState, + latest_state_summary: LedgerStateSummary, latest_txn_accumulator: Arc, to_commit: VecDeque>, to_update_ledger: VecDeque>, @@ -43,18 +50,21 @@ impl ChunkCommitQueue { pub(crate) fn new_from_db(db: &Arc) -> Result { let LedgerSummary { state, + state_summary, transaction_accumulator, } = db.get_pre_committed_ledger_summary()?; + Ok(Self { latest_state: state, + latest_state_summary: state_summary, latest_txn_accumulator: transaction_accumulator, to_commit: VecDeque::new(), to_update_ledger: VecDeque::new(), }) } - pub(crate) fn latest_state(&self) -> Arc { - self.latest_state.clone() + pub(crate) fn latest_state(&self) -> &LedgerState { + &self.latest_state } pub(crate) fn expecting_version(&self) -> Version { @@ -65,7 +75,9 @@ impl ChunkCommitQueue { &mut self, chunk_to_update_ledger: ChunkToUpdateLedger, ) -> Result<()> { - self.latest_state = chunk_to_update_ledger.output.expect_result_state().clone(); + let _timer = CHUNK_OTHER_TIMERS.timer_with(&["enqueue_for_ledger_update"]); + + self.latest_state = chunk_to_update_ledger.output.result_state().clone(); self.to_update_ledger .push_back(Some(chunk_to_update_ledger)); Ok(()) @@ -73,7 +85,11 @@ impl ChunkCommitQueue { pub(crate) fn next_chunk_to_update_ledger( &mut self, - ) -> Result<(Arc, ChunkToUpdateLedger)> { + ) -> Result<( + LedgerStateSummary, + Arc, + ChunkToUpdateLedger, + )> { let chunk_opt = self .to_update_ledger .front_mut() @@ -81,10 +97,16 @@ impl ChunkCommitQueue { let chunk = chunk_opt .take() .ok_or_else(|| anyhow!("Next chunk to update ledger has already been processed."))?; - Ok((self.latest_txn_accumulator.clone(), chunk)) + Ok(( + self.latest_state_summary.clone(), + self.latest_txn_accumulator.clone(), + chunk, + )) } pub(crate) fn save_ledger_update_output(&mut self, chunk: ExecutedChunk) -> Result<()> { + let _timer = CHUNK_OTHER_TIMERS.timer_with(&["save_ledger_update_output"]); + ensure!( !self.to_update_ledger.is_empty(), "to_update_ledger is empty." @@ -93,6 +115,11 @@ impl ChunkCommitQueue { self.to_update_ledger.front().unwrap().is_none(), "Head of to_update_ledger has not been processed." ); + self.latest_state_summary = chunk + .output + .expect_state_checkpoint_output() + .state_summary + .clone(); self.latest_txn_accumulator = chunk .output .expect_ledger_update_output() diff --git a/execution/executor/src/chunk_executor/mod.rs b/execution/executor/src/chunk_executor/mod.rs index 290e630757cf8..b0ca02943edb1 100644 --- a/execution/executor/src/chunk_executor/mod.rs +++ b/execution/executor/src/chunk_executor/mod.rs @@ -25,8 +25,8 @@ use aptos_logger::prelude::*; use aptos_metrics_core::{IntGaugeHelper, TimerHelper}; use aptos_storage_interface::{ state_store::{ - state_delta::StateDelta, - state_view::{async_proof_fetcher::AsyncProofFetcher, cached_state_view::CachedStateView}, + state::State, state_summary::ProvableStateSummary, + state_view::cached_state_view::CachedStateView, }, DbReaderWriter, }; @@ -49,7 +49,7 @@ use aptos_vm::VMBlockExecutor; use chunk_commit_queue::{ChunkCommitQueue, ChunkToUpdateLedger}; use chunk_result_verifier::{ChunkResultVerifier, ReplayChunkVerifier, StateSyncChunkVerifier}; use fail::fail_point; -use itertools::multizip; +use itertools::{multizip, Itertools}; use std::{ iter::once, marker::PhantomData, @@ -243,14 +243,12 @@ impl ChunkExecutorInner { }) } - fn latest_state_view(&self, latest_state: &StateDelta) -> Result { - let first_version = latest_state.next_version(); + fn state_view(&self, state: &State) -> Result { + let first_version = state.next_version(); Ok(CachedStateView::new( StateViewId::ChunkExecution { first_version }, self.db.reader.clone(), - first_version, - latest_state.current.clone(), - Arc::new(AsyncProofFetcher::new(self.db.reader.clone())), + state.clone(), )?) } @@ -266,10 +264,10 @@ impl ChunkExecutorInner { let num_txns = output.num_transactions_to_commit(); if chunk.ledger_info_opt.is_some() || num_txns != 0 { let _timer = CHUNK_OTHER_TIMERS.timer_with(&["commit_chunk_impl__save_txns"]); + // TODO(aldenhu): remove since there's no practical strategy to recover from this error. fail_point!("executor::commit_chunk", |_| { Err(anyhow::anyhow!("Injected error in commit_chunk")) }); - let output = chunk.output.expect_complete_result(); self.db.writer.save_transactions( output.as_chunk_to_commit(), chunk.ledger_info_opt.as_ref(), @@ -294,7 +292,7 @@ impl ChunkExecutorInner { chunk_verifier: Arc, mode_for_log: &'static str, ) -> Result<()> { - let parent_state = self.commit_queue.lock().latest_state(); + let parent_state = self.commit_queue.lock().latest_state().clone(); let first_version = parent_state.next_version(); ensure!( @@ -306,22 +304,9 @@ impl ChunkExecutorInner { let num_txns = chunk.len(); - let state_view = self.latest_state_view(&parent_state)?; - let execution_output = chunk.into_output::(state_view)?; - - // Calculate state snapshot - let state_checkpoint_output = DoStateCheckpoint::run( - &execution_output, - &self.commit_queue.lock().latest_state(), - Some( - chunk_verifier - .transaction_infos() - .iter() - .map(|t| t.state_checkpoint_hash()), - ), - )?; + let state_view = self.state_view(parent_state.latest())?; + let execution_output = chunk.into_output::(&parent_state, state_view)?; let output = PartialStateComputeResult::new(execution_output); - output.set_state_checkpoint_output(state_checkpoint_output); // Enqueue for next stage. self.commit_queue @@ -345,24 +330,31 @@ impl ChunkExecutorInner { pub fn update_ledger(&self) -> Result<()> { let _timer = CHUNK_OTHER_TIMERS.timer_with(&["chunk_update_ledger_total"]); - let (parent_accumulator, chunk) = { - let _timer = CHUNK_OTHER_TIMERS.timer_with(&["chunk_update_ledger__next_chunk"]); - self.commit_queue.lock().next_chunk_to_update_ledger()? - }; + let (parent_state_summary, parent_accumulator, chunk) = + self.commit_queue.lock().next_chunk_to_update_ledger()?; let ChunkToUpdateLedger { output, chunk_verifier, } = chunk; - let first_version = parent_accumulator.num_leaves(); - let ledger_update_output = { - let _timer = CHUNK_OTHER_TIMERS.timer_with(&["chunk_update_ledger__calculate"]); - DoLedgerUpdate::run( - &output.execution_output, - output.expect_state_checkpoint_output(), - parent_accumulator.clone(), - )? - }; + let state_checkpoint_output = DoStateCheckpoint::run( + &output.execution_output, + &parent_state_summary, + &ProvableStateSummary::new_persisted(self.db.reader.as_ref())?, + Some( + chunk_verifier + .transaction_infos() + .iter() + .map(|t| t.state_checkpoint_hash()) + .collect_vec(), + ), + )?; + + let ledger_update_output = DoLedgerUpdate::run( + &output.execution_output, + &state_checkpoint_output, + parent_accumulator.clone(), + )?; chunk_verifier.verify_chunk_result(&parent_accumulator, &ledger_update_output)?; @@ -370,21 +362,20 @@ impl ChunkExecutorInner { &ledger_update_output, output.execution_output.next_epoch_state.as_ref(), )?; + output.set_state_checkpoint_output(state_checkpoint_output); output.set_ledger_update_output(ledger_update_output); + let first_version = output.execution_output.first_version; + let num_txns = output.execution_output.num_transactions_to_commit(); let executed_chunk = ExecutedChunk { output, ledger_info_opt, }; - let num_txns = executed_chunk - .output - .expect_complete_result() - .num_transactions_to_commit(); - let _timer = CHUNK_OTHER_TIMERS.timer_with(&["chunk_update_ledger__save"]); self.commit_queue .lock() .save_ledger_update_output(executed_chunk)?; + info!( LogSchema::new(LogEntry::ChunkExecutor) .first_version_in_request(Some(first_version)) @@ -595,7 +586,8 @@ impl ChunkExecutorInner { verify_execution_mode: &VerifyExecutionMode, ) -> Result { // Execute transactions. - let state_view = self.latest_state_view(&self.commit_queue.lock().latest_state())?; + let parent_state = self.commit_queue.lock().latest_state().clone(); + let state_view = self.state_view(parent_state.latest())?; let txns = transactions .iter() .take((end_version - begin_version) as usize) @@ -607,6 +599,7 @@ impl ChunkExecutorInner { let execution_output = DoGetExecutionOutput::by_transaction_execution::( &V::new(), txns.into(), + &parent_state, state_view, BlockExecutorConfigFromOnchain::new_no_block_limit(), TransactionSliceMetadata::chunk(begin_version, end_version), diff --git a/execution/executor/src/chunk_executor/transaction_chunk.rs b/execution/executor/src/chunk_executor/transaction_chunk.rs index c1958bfb66647..eb749734dd919 100644 --- a/execution/executor/src/chunk_executor/transaction_chunk.rs +++ b/execution/executor/src/chunk_executor/transaction_chunk.rs @@ -9,7 +9,9 @@ use anyhow::Result; use aptos_executor_types::execution_output::ExecutionOutput; use aptos_experimental_runtimes::thread_manager::optimal_min_len; use aptos_metrics_core::TimerHelper; -use aptos_storage_interface::state_store::state_view::cached_state_view::CachedStateView; +use aptos_storage_interface::state_store::{ + state::LedgerState, state_view::cached_state_view::CachedStateView, +}; use aptos_types::{ block_executor::{ config::BlockExecutorConfigFromOnchain, @@ -43,6 +45,7 @@ pub trait TransactionChunk { fn into_output( self, + parent_state: &LedgerState, state_view: CachedStateView, ) -> Result; } @@ -63,6 +66,7 @@ impl TransactionChunk for ChunkToExecute { fn into_output( self, + parent_state: &LedgerState, state_view: CachedStateView, ) -> Result { let ChunkToExecute { @@ -89,6 +93,7 @@ impl TransactionChunk for ChunkToExecute { DoGetExecutionOutput::by_transaction_execution::( &V::new(), sig_verified_txns.into(), + parent_state, state_view, BlockExecutorConfigFromOnchain::new_no_block_limit(), TransactionSliceMetadata::unknown(), @@ -113,6 +118,7 @@ impl TransactionChunk for ChunkToApply { fn into_output( self, + parent_state: &LedgerState, state_view: CachedStateView, ) -> Result { let Self { @@ -121,6 +127,11 @@ impl TransactionChunk for ChunkToApply { first_version: _, } = self; - DoGetExecutionOutput::by_transaction_output(transactions, transaction_outputs, state_view) + DoGetExecutionOutput::by_transaction_output( + transactions, + transaction_outputs, + parent_state, + state_view, + ) } } diff --git a/execution/executor/src/db_bootstrapper/mod.rs b/execution/executor/src/db_bootstrapper/mod.rs index 577d9b5997f5b..511e5b3d1efd1 100644 --- a/execution/executor/src/db_bootstrapper/mod.rs +++ b/execution/executor/src/db_bootstrapper/mod.rs @@ -12,10 +12,8 @@ use anyhow::{anyhow, ensure, format_err, Result}; use aptos_crypto::HashValue; use aptos_logger::prelude::*; use aptos_storage_interface::{ - state_store::state_view::{ - async_proof_fetcher::AsyncProofFetcher, cached_state_view::CachedStateView, - }, - DbReaderWriter, DbWriter, LedgerSummary, + state_store::state_view::cached_state_view::CachedStateView, DbReaderWriter, DbWriter, + LedgerSummary, }; use aptos_types::{ account_config::CORE_CODE_ADDRESS, @@ -124,10 +122,10 @@ pub fn calculate_genesis( // In the very extreme and sad situation of losing quorum among validators, we refer to the // second use case said above. let genesis_version = ledger_summary.version().map_or(0, |v| v + 1); - let base_state_view = ledger_summary.verified_state_view( + let base_state_view = CachedStateView::new( StateViewId::Miscellaneous, Arc::clone(&db.reader), - Arc::new(AsyncProofFetcher::new(db.reader.clone())), + ledger_summary.state.latest().clone(), )?; let epoch = if genesis_version == 0 { @@ -139,6 +137,7 @@ pub fn calculate_genesis( let execution_output = DoGetExecutionOutput::by_transaction_execution::( &V::new(), vec![genesis_txn.clone().into()].into(), + &ledger_summary.state, base_state_view, BlockExecutorConfigFromOnchain::new_no_block_limit(), TransactionSliceMetadata::unknown(), @@ -152,7 +151,7 @@ pub fn calculate_genesis( "Genesis txn didn't output reconfig event." ); - let output = ApplyExecutionOutput::run(execution_output, &ledger_summary)?; + let output = ApplyExecutionOutput::run(execution_output, ledger_summary, db.reader.as_ref())?; let timestamp_usecs = if genesis_version == 0 { // TODO(aldenhu): fix existing tests before using real timestamp and check on-chain epoch. GENESIS_TIMESTAMP_USECS @@ -160,9 +159,7 @@ pub fn calculate_genesis( let state_view = CachedStateView::new( StateViewId::Miscellaneous, Arc::clone(&db.reader), - output.execution_output.next_version(), - output.expect_result_state().current.clone(), - Arc::new(AsyncProofFetcher::new(db.reader.clone())), + output.result_state().latest().clone(), )?; let next_epoch = epoch .checked_add(1) diff --git a/execution/executor/src/metrics.rs b/execution/executor/src/metrics.rs index c47a31967bc8c..587e0f9612550 100644 --- a/execution/executor/src/metrics.rs +++ b/execution/executor/src/metrics.rs @@ -417,6 +417,11 @@ pub fn update_counters_for_processed_chunk( .with_label_values(&[process_type, "NoAccountAuthenticator"]) .inc(); }, + AccountAuthenticator::Abstraction { .. } => { + PROCESSED_TXNS_AUTHENTICATOR + .with_label_values(&[process_type, "AbstractionAuthenticator"]) + .inc(); + }, }; } diff --git a/execution/executor/src/tests/chunk_executor_tests.rs b/execution/executor/src/tests/chunk_executor_tests.rs index 9dc2583c09f63..854a3d7ff0f88 100644 --- a/execution/executor/src/tests/chunk_executor_tests.rs +++ b/execution/executor/src/tests/chunk_executor_tests.rs @@ -171,7 +171,7 @@ fn test_executor_execute_and_commit_chunk_restart() { let (chunks, ledger_info) = { let first_batch_start = 1; let second_batch_start = first_batch_start + first_batch_size; - tests::create_transaction_chunks(vec![ + create_transaction_chunks(vec![ first_batch_start..=first_batch_start + first_batch_size - 1, second_batch_start..=second_batch_start + second_batch_size - 1, ]) diff --git a/execution/executor/src/tests/mod.rs b/execution/executor/src/tests/mod.rs index d27c2fed3629d..41bb1e83fc5ec 100644 --- a/execution/executor/src/tests/mod.rs +++ b/execution/executor/src/tests/mod.rs @@ -13,7 +13,7 @@ use aptos_executor_types::{ BlockExecutorTrait, ChunkExecutorTrait, TransactionReplayer, VerifyExecutionMode, }; use aptos_storage_interface::{ - state_store::state_view::async_proof_fetcher::AsyncProofFetcher, DbReaderWriter, LedgerSummary, + state_store::state_view::cached_state_view::CachedStateView, DbReaderWriter, LedgerSummary, Result, }; use aptos_types::{ @@ -44,7 +44,7 @@ use mock_vm::{ MockVM, DISCARD_STATUS, KEEP_STATUS, }; use proptest::prelude::*; -use std::{iter::once, sync::Arc}; +use std::iter::once; mod chunk_executor_tests; #[cfg(test)] @@ -485,18 +485,22 @@ fn apply_transaction_by_writeset( ))) .unzip(); - let state_view = ledger_summary - .verified_state_view( - StateViewId::Miscellaneous, - Arc::clone(&db.reader), - Arc::new(AsyncProofFetcher::new(db.reader.clone())), - ) - .unwrap(); - - let chunk_output = - DoGetExecutionOutput::by_transaction_output(txns, txn_outs, state_view).unwrap(); + let state_view = CachedStateView::new( + StateViewId::Miscellaneous, + db.reader.clone(), + ledger_summary.state.latest().clone(), + ) + .unwrap(); + let chunk_output = DoGetExecutionOutput::by_transaction_output( + txns, + txn_outs, + &ledger_summary.state, + state_view, + ) + .unwrap(); - let output = ApplyExecutionOutput::run(chunk_output, &ledger_summary).unwrap(); + let output = + ApplyExecutionOutput::run(chunk_output, ledger_summary, db.reader.as_ref()).unwrap(); db.writer .save_transactions( @@ -681,22 +685,23 @@ fn run_transactions_naive( let db = &executor.db; for txn in transactions { - let ledger_summary: LedgerSummary = db.reader.get_pre_committed_ledger_summary().unwrap(); + let ledger_summary = db.reader.get_pre_committed_ledger_summary().unwrap(); + let state_view = CachedStateView::new( + StateViewId::Miscellaneous, + db.reader.clone(), + ledger_summary.state.latest().clone(), + ) + .unwrap(); let out = DoGetExecutionOutput::by_transaction_execution( &MockVM::new(), vec![txn].into(), - ledger_summary - .verified_state_view( - StateViewId::Miscellaneous, - Arc::clone(&db.reader), - Arc::new(AsyncProofFetcher::new(db.reader.clone())), - ) - .unwrap(), + &ledger_summary.state, + state_view, block_executor_onchain_config.clone(), TransactionSliceMetadata::unknown(), ) .unwrap(); - let output = ApplyExecutionOutput::run(out, &ledger_summary).unwrap(); + let output = ApplyExecutionOutput::run(out, ledger_summary, db.reader.as_ref()).unwrap(); db.writer .save_transactions( output.expect_complete_result().as_chunk_to_commit(), @@ -866,6 +871,7 @@ proptest! { txns.push(SignatureVerifiedTransaction::Valid(Transaction::StateCheckpoint(block_b.id))); txns }, TEST_BLOCK_EXECUTOR_ONCHAIN_CONFIG); + prop_assert_eq!(root_hash, expected_root_hash); } } diff --git a/execution/executor/src/types/in_memory_state_calculator_v2.rs b/execution/executor/src/types/in_memory_state_calculator_v2.rs deleted file mode 100644 index 95bb07bfcd1b5..0000000000000 --- a/execution/executor/src/types/in_memory_state_calculator_v2.rs +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::metrics::OTHER_TIMERS; -use anyhow::{ensure, Result}; -use aptos_crypto::{hash::CryptoHash, HashValue}; -use aptos_drop_helper::DropHelper; -use aptos_executor_types::{ - execution_output::ExecutionOutput, state_checkpoint_output::StateCheckpointOutput, - transactions_with_output::TransactionsWithOutput, ProofReader, -}; -use aptos_logger::info; -use aptos_metrics_core::TimerHelper; -use aptos_scratchpad::FrozenSparseMerkleTree; -use aptos_storage_interface::state_store::{ - sharded_state_update_refs::ShardedStateUpdateRefs, - sharded_state_updates::ShardedStateUpdates, - state_delta::StateDelta, - state_view::cached_state_view::{ShardedStateCache, StateCache}, -}; -use aptos_types::{ - state_store::{ - state_key::StateKey, state_storage_usage::StateStorageUsage, state_value::StateValue, - }, - transaction::Version, - write_set::WriteSet, -}; -use dashmap::DashMap; -use itertools::{zip_eq, Itertools}; -use rayon::prelude::*; -use std::{ops::Deref, sync::Arc}; - -/// Helper class for calculating state changes after a block of transactions are executed. -pub struct InMemoryStateCalculatorV2 {} - -impl InMemoryStateCalculatorV2 { - pub fn calculate_for_transactions( - execution_output: &ExecutionOutput, - parent_state: &Arc, - known_state_checkpoints: Option>>, - ) -> Result { - if execution_output.is_block { - Self::validate_input_for_block(parent_state, &execution_output.to_commit)?; - } - - Self::calculate_impl( - parent_state, - &execution_output.state_cache, - execution_output.to_commit.state_update_refs(), - execution_output.to_commit.last_checkpoint_index(), - execution_output.is_block, - known_state_checkpoints, - ) - } - - pub fn calculate_for_write_sets_after_snapshot( - parent_state: &Arc, - state_cache: &StateCache, - last_checkpoint_index: Option, - write_sets: &[WriteSet], - ) -> Result { - let state_update_refs = - ShardedStateUpdateRefs::index_write_sets(write_sets, write_sets.len()); - - Self::calculate_impl( - parent_state, - state_cache, - &state_update_refs, - last_checkpoint_index, - false, - Option::>::None, - ) - } - - fn calculate_impl( - parent_state: &Arc, - state_cache: &StateCache, - state_update_refs: &ShardedStateUpdateRefs, - last_checkpoint_index: Option, - is_block: bool, - known_state_checkpoints: Option>>, - ) -> Result { - let StateCache { - // This makes sure all in-mem nodes seen while proofs were fetched stays in mem during the - // calculation - frozen_base, - sharded_state_cache, - proofs, - } = state_cache; - assert!(frozen_base.smt.is_the_same(&parent_state.current)); - - // TODO(aldenhu): use maps of refs instead of cloning the state kvs - let (updates_before_last_checkpoint, updates_after_last_checkpoint) = - Self::calculate_updates(state_update_refs, last_checkpoint_index); - // TODO(aldenhu): calculate on the checkpoint as well, and don't need to combine - let mut _all_updates_owned: Option> = None; - let all_updates = if updates_after_last_checkpoint.all_shards_empty() { - &updates_before_last_checkpoint - } else if updates_before_last_checkpoint.all_shards_empty() { - &updates_after_last_checkpoint - } else { - let _timer = OTHER_TIMERS.timer_with(&["calculate_all_updates"]); - let mut all_updates = updates_before_last_checkpoint.clone(); - all_updates.clone_merge(&updates_after_last_checkpoint); - _all_updates_owned = Some(DropHelper::new(all_updates)); - _all_updates_owned.as_ref().expect("Just set").deref() - }; - - let usage = Self::calculate_usage( - parent_state.current.usage(), - sharded_state_cache, - all_updates, - ); - - let first_version = parent_state.current_version.map_or(0, |v| v + 1); - let num_txns = state_update_refs.num_versions; - let proof_reader = ProofReader::new(proofs); - let latest_checkpoint = if let Some(index) = last_checkpoint_index { - Self::make_checkpoint( - parent_state.current.freeze(&frozen_base.base_smt), - &updates_before_last_checkpoint, - if index == num_txns - 1 { - usage - } else { - StateStorageUsage::new_untracked() - }, - &proof_reader, - )? - } else { - // If there is no checkpoint in this chunk, the latest checkpoint will be the existing - // one. - parent_state.base.freeze(&frozen_base.base_smt) - }; - - let mut latest_checkpoint_version = parent_state.base_version; - let mut state_checkpoint_hashes = known_state_checkpoints - .map_or_else(|| vec![None; num_txns], |v| v.into_iter().collect()); - ensure!( - state_checkpoint_hashes.len() == num_txns, - "Bad number of known hashes." - ); - if let Some(index) = last_checkpoint_index { - if let Some(h) = state_checkpoint_hashes[index] { - ensure!( - h == latest_checkpoint.root_hash(), - "Last checkpoint not expected." - ); - } else { - state_checkpoint_hashes[index] = Some(latest_checkpoint.root_hash()); - } - latest_checkpoint_version = Some(first_version + index as u64); - } - - let current_version = first_version + num_txns as u64 - 1; - // We need to calculate the SMT at the end of the chunk, if it is not already calculated. - let current_tree = if last_checkpoint_index == Some(num_txns - 1) { - latest_checkpoint.smt.clone() - } else { - ensure!(!is_block, "Block must have the checkpoint at the end."); - // The latest tree is either the last checkpoint in current chunk, or the tree at the - // end of previous chunk if there is no checkpoint in the current chunk. - let latest_tree = if last_checkpoint_index.is_some() { - latest_checkpoint.clone() - } else { - parent_state.current.freeze(&frozen_base.base_smt) - }; - Self::make_checkpoint( - latest_tree, - &updates_after_last_checkpoint, - usage, - &proof_reader, - )? - .smt - }; - - let updates_since_latest_checkpoint = if last_checkpoint_index.is_some() { - updates_after_last_checkpoint - } else { - let mut updates_since_latest_checkpoint = - parent_state.updates_since_base.deref().clone(); - zip_eq( - updates_since_latest_checkpoint.shards.iter_mut(), - updates_after_last_checkpoint.shards, - ) - .for_each(|(base, delta)| base.extend(delta)); - updates_since_latest_checkpoint - }; - - info!( - "last_checkpoint_index {last_checkpoint_index:?}, result_state: {latest_checkpoint_version:?} {:?} {:?} {current_version} {:?} {:?}", - latest_checkpoint.root_hash(), - latest_checkpoint.usage(), - current_tree.root_hash(), - current_tree.usage(), - ); - - let result_state = StateDelta::new( - latest_checkpoint.smt, - latest_checkpoint_version, - current_tree, - Some(current_version), - updates_since_latest_checkpoint, - ); - - Ok(StateCheckpointOutput::new( - parent_state.clone(), - Arc::new(result_state), - last_checkpoint_index.map(|_| updates_before_last_checkpoint), - state_checkpoint_hashes, - )) - } - - fn calculate_updates( - state_update_refs: &ShardedStateUpdateRefs, - last_checkpoint_index: Option, - ) -> (ShardedStateUpdates, ShardedStateUpdates) { - let _timer = OTHER_TIMERS.timer_with(&["calculate_updates"]); - - let mut shard_iters = state_update_refs - .shards - .iter() - .map(|shard| shard.iter()) - .collect::>(); - let mut before_last_checkpoint = ShardedStateUpdates::new_empty(); - let mut after_last_checkpoint = ShardedStateUpdates::new_empty(); - - // TODO(aldenhu): no need to par_iter() if no need to clone. - if let Some(last_checkpoint_index) = last_checkpoint_index { - shard_iters - .par_iter_mut() - .zip_eq(before_last_checkpoint.shards.par_iter_mut()) - .for_each(|(shard_iter, shard_updates)| { - shard_updates.extend( - shard_iter - // n.b. take_while_ref so that in the next step we can process the rest of the entries from the iters. - .take_while_ref(|(idx, _k, _v)| *idx <= last_checkpoint_index) - .map(|(_idx, k, v)| ((*k).clone(), v.cloned())), - ) - }); - } - - let num_txns = state_update_refs.num_versions; - if num_txns != 0 && last_checkpoint_index != Some(num_txns - 1) { - shard_iters - .par_iter_mut() - .zip_eq(after_last_checkpoint.shards.par_iter_mut()) - .for_each(|(shard_iter, shard_updates)| { - shard_updates.extend(shard_iter.map(|(_idx, k, v)| ((*k).clone(), v.cloned()))) - }); - } - - (before_last_checkpoint, after_last_checkpoint) - } - - fn add_to_delta( - k: &StateKey, - v: &Option<&StateValue>, - state_cache: &DashMap, Option)>, - items_delta: &mut i64, - bytes_delta: &mut i64, - ) { - let key_size = k.size(); - if let Some(value) = v { - *items_delta += 1; - *bytes_delta += (key_size + value.size()) as i64; - } - - // n.b. all updated state items must be read and recorded in the state cache, - // otherwise we can't calculate the correct usage. - let old_entry = state_cache.get(k).expect("Must cache read"); - if let (_, Some(old_v)) = old_entry.value() { - *items_delta -= 1; - *bytes_delta -= (key_size + old_v.size()) as i64; - } - } - - fn calculate_usage( - old_usage: StateStorageUsage, - sharded_state_cache: &ShardedStateCache, - updates: &ShardedStateUpdates, - ) -> StateStorageUsage { - let _timer = OTHER_TIMERS.timer_with(&["calculate_usage"]); - - if old_usage.is_untracked() { - return StateStorageUsage::new_untracked(); - } - - let (items_delta, bytes_delta) = sharded_state_cache - .par_iter() - .zip_eq(updates.shards.par_iter()) - .map(|(cache, updates)| { - let mut items_delta = 0; - let mut bytes_delta = 0; - updates.iter().for_each(|(key, value)| { - Self::add_to_delta( - key, - &value.as_ref(), - cache, - &mut items_delta, - &mut bytes_delta, - ) - }); - (items_delta, bytes_delta) - }) - .reduce(|| (0, 0), |(i1, b1), (i2, b2)| (i1 + i2, b1 + b2)); - - StateStorageUsage::new( - (old_usage.items() as i64 + items_delta) as usize, - (old_usage.bytes() as i64 + bytes_delta) as usize, - ) - } - - fn make_checkpoint( - latest_checkpoint: FrozenSparseMerkleTree, - updates: &ShardedStateUpdates, - usage: StateStorageUsage, - proof_reader: &ProofReader, - ) -> Result> { - let _timer = OTHER_TIMERS.timer_with(&["make_checkpoint"]); - - // Update SMT. - // - // TODO(aldenhu): avoid collecting into vec - let smt_updates: Vec<_> = { - let _timer = OTHER_TIMERS.timer_with(&["make_smt_updates"]); - updates - .shards - .iter() - .flatten() - .map(|(key, value)| (key.hash(), value.as_ref())) - .collect() - }; - let new_checkpoint = { - let _timer = OTHER_TIMERS.timer_with(&["smt_batch_update"]); - latest_checkpoint.batch_update(smt_updates, usage, proof_reader)? - }; - Ok(new_checkpoint) - } - - fn validate_input_for_block( - base: &StateDelta, - to_commit: &TransactionsWithOutput, - ) -> Result<()> { - let num_txns = to_commit.len(); - ensure!(num_txns != 0, "Empty block is not allowed."); - ensure!( - base.base_version == base.current_version, - "Block base state is not a checkpoint. base_version {:?}, current_version {:?}", - base.base_version, - base.current_version, - ); - ensure!( - base.updates_since_base.all_shards_empty(), - "Base state is corrupted, updates_since_base is not empty at a checkpoint." - ); - - Ok(()) - } -} diff --git a/execution/executor/src/types/mod.rs b/execution/executor/src/types/mod.rs index 604b6b0cfb2f4..a784416e75fa0 100644 --- a/execution/executor/src/types/mod.rs +++ b/execution/executor/src/types/mod.rs @@ -4,7 +4,6 @@ #![forbid(unsafe_code)] -pub mod in_memory_state_calculator_v2; - pub mod executed_chunk; + pub mod partial_state_compute_result; diff --git a/execution/executor/src/types/partial_state_compute_result.rs b/execution/executor/src/types/partial_state_compute_result.rs index 2a62efdab6d0c..a0fcf67811e7f 100644 --- a/execution/executor/src/types/partial_state_compute_result.rs +++ b/execution/executor/src/types/partial_state_compute_result.rs @@ -7,10 +7,11 @@ use aptos_executor_types::{ execution_output::ExecutionOutput, state_checkpoint_output::StateCheckpointOutput, state_compute_result::StateComputeResult, LedgerUpdateOutput, }; -use aptos_storage_interface::state_store::state_delta::StateDelta; -use aptos_types::proof::accumulator::InMemoryTransactionAccumulator; +use aptos_storage_interface::{ + state_store::{state::LedgerState, state_summary::LedgerStateSummary}, + LedgerSummary, +}; use once_cell::sync::OnceCell; -use std::sync::Arc; #[derive(Clone, Debug)] pub struct PartialStateComputeResult { @@ -28,18 +29,21 @@ impl PartialStateComputeResult { } } - pub fn new_empty( - state: Arc, - txn_accumulator: Arc, - ) -> Self { - let execution_output = ExecutionOutput::new_empty(state.clone()); + pub fn new_empty(ledger_summary: LedgerSummary) -> Self { + // Deliberately not reusing Self::new() here to make sure we don't leave + // any OnceCell unset. + let execution_output = ExecutionOutput::new_empty(ledger_summary.state); let ledger_update_output = OnceCell::new(); ledger_update_output - .set(LedgerUpdateOutput::new_empty(txn_accumulator)) + .set(LedgerUpdateOutput::new_empty( + ledger_summary.transaction_accumulator, + )) .expect("First set."); let state_checkpoint_output = OnceCell::new(); state_checkpoint_output - .set(StateCheckpointOutput::new_empty(state)) + .set(StateCheckpointOutput::new_empty( + ledger_summary.state_summary, + )) .expect("First set."); Self { @@ -63,8 +67,12 @@ impl PartialStateComputeResult { .expect("StateCheckpointOutput not set") } - pub fn expect_result_state(&self) -> &Arc { - &self.expect_state_checkpoint_output().result_state + pub fn result_state(&self) -> &LedgerState { + &self.execution_output.result_state + } + + pub fn expect_result_state_summary(&self) -> &LedgerStateSummary { + &self.expect_state_checkpoint_output().state_summary } pub fn set_state_checkpoint_output(&self, state_checkpoint_output: StateCheckpointOutput) { @@ -93,6 +101,7 @@ impl PartialStateComputeResult { self.ledger_update_output.get().map(|ledger_update_output| { StateComputeResult::new( self.execution_output.clone(), + // ledger_update_output is set in a later stage, so it's safe to `expect` here. self.expect_state_checkpoint_output().clone(), ledger_update_output.clone(), ) diff --git a/execution/executor/src/workflow/do_get_execution_output.rs b/execution/executor/src/workflow/do_get_execution_output.rs index 99be96683f624..e2357093666ca 100644 --- a/execution/executor/src/workflow/do_get_execution_output.rs +++ b/execution/executor/src/workflow/do_get_execution_output.rs @@ -23,8 +23,8 @@ use aptos_executor_types::{ use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_logger::prelude::*; use aptos_metrics_core::TimerHelper; -use aptos_storage_interface::state_store::state_view::cached_state_view::{ - CachedStateView, StateCache, +use aptos_storage_interface::state_store::{ + state::LedgerState, state_view::cached_state_view::CachedStateView, }; #[cfg(feature = "consensus-only-perf-test")] use aptos_types::transaction::ExecutionStatus; @@ -57,6 +57,7 @@ impl DoGetExecutionOutput { pub fn by_transaction_execution( executor: &V, transactions: ExecutableTransactions, + parent_state: &LedgerState, state_view: CachedStateView, onchain_config: BlockExecutorConfigFromOnchain, transaction_slice_metadata: TransactionSliceMetadata, @@ -66,6 +67,7 @@ impl DoGetExecutionOutput { Self::by_transaction_execution_unsharded::( executor, txns, + parent_state, state_view, onchain_config, transaction_slice_metadata, @@ -73,6 +75,7 @@ impl DoGetExecutionOutput { }, ExecutableTransactions::Sharded(txns) => Self::by_transaction_execution_sharded::( txns, + parent_state, state_view, onchain_config, transaction_slice_metadata.append_state_checkpoint_to_block(), @@ -97,6 +100,7 @@ impl DoGetExecutionOutput { fn by_transaction_execution_unsharded( executor: &V, transactions: Vec, + parent_state: &LedgerState, state_view: CachedStateView, onchain_config: BlockExecutorConfigFromOnchain, transaction_slice_metadata: TransactionSliceMetadata, @@ -121,14 +125,17 @@ impl DoGetExecutionOutput { .map(|t| t.into_inner()) .collect(), transaction_outputs, - state_view.into_state_cache(), + parent_state, + state_view, block_end_info, append_state_checkpoint_to_block, + false, // prime_state_cache ) } pub fn by_transaction_execution_sharded( transactions: PartitionedTransactions, + parent_state: &LedgerState, state_view: CachedStateView, onchain_config: BlockExecutorConfigFromOnchain, append_state_checkpoint_to_block: Option, @@ -152,33 +159,29 @@ impl DoGetExecutionOutput { .map(|t| t.into_txn().into_inner()) .collect(), transaction_outputs, - state_view.into_state_cache(), + parent_state, + state_view, None, // block end info append_state_checkpoint_to_block, + false, // prime_state_cache ) } pub fn by_transaction_output( transactions: Vec, transaction_outputs: Vec, + parent_state: &LedgerState, state_view: CachedStateView, ) -> Result { - // collect all accounts touched and dedup - let write_set = transaction_outputs - .iter() - .map(|o| o.write_set()) - .collect::>(); - - // prime the state cache by fetching all touched accounts - state_view.prime_cache_by_write_set(write_set)?; - let out = Parser::parse( state_view.next_version(), transactions, transaction_outputs, - state_view.into_state_cache(), + parent_state, + state_view, None, // block end info None, // append state checkpoint to block + true, // prime state cache )?; let ret = out.clone(); @@ -287,9 +290,11 @@ impl Parser { first_version: Version, mut transactions: Vec, mut transaction_outputs: Vec, - state_cache: StateCache, + parent_state: &LedgerState, + base_state_view: CachedStateView, block_end_info: Option, append_state_checkpoint_to_block: Option, + prime_state_cache: bool, ) -> Result { let _timer = OTHER_TIMERS.timer_with(&["parse_raw_output"]); @@ -317,6 +322,7 @@ impl Parser { let _timer = OTHER_TIMERS.timer_with(&["parse_raw_output__to_commit"]); let to_commit = TransactionsWithOutput::new(transactions, transaction_outputs); TransactionsToKeep::index( + first_version, Self::maybe_add_block_epilogue( to_commit, has_reconfig, @@ -333,6 +339,17 @@ impl Parser { .transpose()? }; + if prime_state_cache { + base_state_view.prime_cache(to_commit.state_update_refs())?; + } + + let result_state = parent_state.update_with_memorized_reads( + base_state_view.persisted_state(), + to_commit.state_update_refs(), + base_state_view.memorized_reads(), + ); + let state_reads = base_state_view.into_memorized_reads(); + let out = ExecutionOutput::new( is_block, first_version, @@ -340,7 +357,8 @@ impl Parser { to_commit, to_discard, to_retry, - state_cache, + result_state, + state_reads, block_end_info, next_epoch_state, Planned::place_holder(), @@ -502,7 +520,9 @@ impl<'a> TStateView for WriteSetStateView<'a> { #[cfg(test)] mod tests { use super::Parser; - use aptos_storage_interface::state_store::state_view::cached_state_view::StateCache; + use aptos_storage_interface::state_store::{ + state::LedgerState, state_view::cached_state_view::CachedStateView, + }; use aptos_types::{ contract_event::ContractEvent, transaction::{ @@ -540,8 +560,18 @@ mod tests { TransactionAuxiliaryData::default(), ), ]; - let execution_output = - Parser::parse(0, txns, txn_outs, StateCache::new_dummy(), None, None).unwrap(); + let state = LedgerState::new_empty(); + let execution_output = Parser::parse( + 0, + txns, + txn_outs, + &state, + CachedStateView::new_dummy(&state), + None, + None, + false, + ) + .unwrap(); assert_eq!( vec![event_0, event_2], *execution_output.subscribable_events diff --git a/execution/executor/src/workflow/do_state_checkpoint.rs b/execution/executor/src/workflow/do_state_checkpoint.rs index 1d4cfae66ec3a..ab3fbfe28a188 100644 --- a/execution/executor/src/workflow/do_state_checkpoint.rs +++ b/execution/executor/src/workflow/do_state_checkpoint.rs @@ -1,28 +1,88 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::types::in_memory_state_calculator_v2::InMemoryStateCalculatorV2; -use anyhow::Result; +use crate::metrics::OTHER_TIMERS; +use anyhow::{ensure, Result}; use aptos_crypto::HashValue; use aptos_executor_types::{ execution_output::ExecutionOutput, state_checkpoint_output::StateCheckpointOutput, }; -use aptos_storage_interface::state_store::state_delta::StateDelta; -use std::sync::Arc; +use aptos_metrics_core::TimerHelper; +use aptos_storage_interface::state_store::state_summary::{ + LedgerStateSummary, ProvableStateSummary, +}; pub struct DoStateCheckpoint; impl DoStateCheckpoint { pub fn run( execution_output: &ExecutionOutput, - parent_state: &Arc, - known_state_checkpoints: Option>>, + parent_state_summary: &LedgerStateSummary, + persisted_state_summary: &ProvableStateSummary, + known_state_checkpoints: Option>>, ) -> Result { - // Apply the write set, get the latest state. - InMemoryStateCalculatorV2::calculate_for_transactions( + let _timer = OTHER_TIMERS.timer_with(&["do_state_checkpoint"]); + + let state_summary = parent_state_summary.update( + persisted_state_summary, + execution_output.to_commit.state_update_refs(), + )?; + + let state_checkpoint_hashes = Self::get_state_checkpoint_hashes( execution_output, - parent_state, known_state_checkpoints, - ) + &state_summary, + )?; + + Ok(StateCheckpointOutput::new( + state_summary, + state_checkpoint_hashes, + )) + } + + fn get_state_checkpoint_hashes( + execution_output: &ExecutionOutput, + known_state_checkpoints: Option>>, + state_summary: &LedgerStateSummary, + ) -> Result>> { + let _timer = OTHER_TIMERS.timer_with(&["get_state_checkpoint_hashes"]); + + let num_txns = execution_output.to_commit.len(); + let last_checkpoint_index = execution_output + .to_commit + .state_update_refs() + .last_inner_checkpoint_index(); + + if let Some(known) = known_state_checkpoints { + ensure!( + known.len() == num_txns, + "Bad number of known hashes. {} vs {}", + known.len(), + num_txns + ); + if let Some(idx) = last_checkpoint_index { + ensure!( + known[idx] == Some(state_summary.last_checkpoint().root_hash()), + "Root hash mismatch with known hashes passed in. {:?} vs {:?}", + known[idx], + Some(&state_summary.last_checkpoint().root_hash()), + ); + } + + Ok(known) + } else { + if !execution_output.is_block { + // We should enter this branch only in test. + execution_output.to_commit.ensure_at_most_one_checkpoint()?; + } + + let mut out = vec![None; num_txns]; + + if let Some(index) = last_checkpoint_index { + out[index] = Some(state_summary.last_checkpoint().root_hash()); + } + + Ok(out) + } } } diff --git a/execution/executor/src/workflow/mod.rs b/execution/executor/src/workflow/mod.rs index 9ea524d1eb8b7..2413e3b97df4a 100644 --- a/execution/executor/src/workflow/mod.rs +++ b/execution/executor/src/workflow/mod.rs @@ -7,7 +7,9 @@ use crate::types::partial_state_compute_result::PartialStateComputeResult; use anyhow::Result; use aptos_executor_types::execution_output::ExecutionOutput; -use aptos_storage_interface::LedgerSummary; +use aptos_storage_interface::{ + state_store::state_summary::ProvableStateSummary, DbReader, LedgerSummary, +}; use do_ledger_update::DoLedgerUpdate; use do_state_checkpoint::DoStateCheckpoint; @@ -20,17 +22,19 @@ pub struct ApplyExecutionOutput; impl ApplyExecutionOutput { pub fn run( execution_output: ExecutionOutput, - base_view: &LedgerSummary, + base_view: LedgerSummary, + reader: &(dyn DbReader + Sync), ) -> Result { let state_checkpoint_output = DoStateCheckpoint::run( &execution_output, - base_view.state(), - Option::>::None, // known_state_checkpoint_hashes + &base_view.state_summary, + &ProvableStateSummary::new_persisted(reader)?, + None, )?; let ledger_update_output = DoLedgerUpdate::run( &execution_output, &state_checkpoint_output, - base_view.txn_accumulator().clone(), + base_view.transaction_accumulator, )?; let output = PartialStateComputeResult::new(execution_output); output.set_state_checkpoint_output(state_checkpoint_output); diff --git a/execution/executor/tests/internal_indexer_test.rs b/execution/executor/tests/internal_indexer_test.rs index 4092dd014a63c..31a0371b0ed1e 100644 --- a/execution/executor/tests/internal_indexer_test.rs +++ b/execution/executor/tests/internal_indexer_test.rs @@ -237,12 +237,14 @@ fn test_db_indexer_data() { ident_str!("features"), ident_str!("from_bcs"), ident_str!("pool_u64"), + ident_str!("auth_data"), ident_str!("secp256k1"), ident_str!("timestamp"), ident_str!("type_info"), ident_str!("aggregator"), ident_str!("aptos_coin"), ident_str!("aptos_hash"), + ident_str!("bcs_stream"), ident_str!("big_vector"), ident_str!("bit_vector"), ident_str!("capability"), @@ -292,8 +294,10 @@ fn test_db_indexer_data() { ident_str!("randomness_config"), ident_str!("table_with_length"), ident_str!("aggregator_factory"), + ident_str!("account_abstraction"), ident_str!("governance_proposal"), ident_str!("optional_aggregator"), + ident_str!("permissioned_signer"), ident_str!("transaction_context"), ident_str!("jwk_consensus_config"), ident_str!("ristretto255_elgamal"), diff --git a/experimental/storage/layered-map/src/layer.rs b/experimental/storage/layered-map/src/layer.rs index 8806ef10bec1c..b41b7ae049af1 100644 --- a/experimental/storage/layered-map/src/layer.rs +++ b/experimental/storage/layered-map/src/layer.rs @@ -135,6 +135,10 @@ impl MapLayer { Arc::ptr_eq(&self.inner, &other.inner) } + pub fn is_descendant_of(&self, other: &Self) -> bool { + self.is_family(other) && self.inner.layer >= other.inner.layer + } + pub(crate) fn layer(&self) -> u64 { self.inner.layer } diff --git a/experimental/storage/layered-map/src/map/mod.rs b/experimental/storage/layered-map/src/map/mod.rs index 62605dfed47ab..7d2eeb30490b1 100644 --- a/experimental/storage/layered-map/src/map/mod.rs +++ b/experimental/storage/layered-map/src/map/mod.rs @@ -107,6 +107,7 @@ where self.get_with_hasher(key, &Default::default()) } + // TODO(aldenhu): make `Item = (&K, &V)` pub fn iter(&self) -> impl Iterator + '_ { self.top_layer .peak() diff --git a/keyless/pepper/example-client-rust/src/main.rs b/keyless/pepper/example-client-rust/src/main.rs index a1c7e416b8e45..d9bd0820964ba 100644 --- a/keyless/pepper/example-client-rust/src/main.rs +++ b/keyless/pepper/example-client-rust/src/main.rs @@ -66,6 +66,9 @@ fn get_jwt_or_path() -> String { #[tokio::main] async fn main() { + // if let Ok(x) = std::env::var("V0_VERIFY") { + // test_v0_verify(); + // } println!(); println!("Starting an interaction with aptos-oidb-pepper-service."); let url = get_pepper_service_url(); diff --git a/keyless/pepper/readme.md b/keyless/pepper/readme.md index 493650962e0c7..8538641414841 100644 --- a/keyless/pepper/readme.md +++ b/keyless/pepper/readme.md @@ -58,3 +58,32 @@ Follow the instruction to manually complete a session with the pepper service. Sorry for the missing examples in other programming languages. For now please read through `example-client-rust/src/main.rs` implementation and output: that is what your frontend needs to do. + +## Extra: manual testing for endpoint `v0/verify`. +NOTE: API `v0/verify` now depends on on-chain resources +`0x1::keyless_account::Groth16VerificationKey` and `0x1::keyless_account::Configuration`, +which need to be fetched via HTTP requests. + +In terminal 0, run the pepper service. +```bash +export VUF_KEY_SEED_HEX=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +export ONCHAIN_GROTH16_VK_URL=http://localhost:4444/groth16_vk.json +export ONCHAIN_KEYLESS_CONFIG_URL=http://localhost:4444/keyless_config.json +cargo run -p aptos-keyless-pepper-service +``` + +In terminal 1, peek the cached resources, they should currently give 404. +``` +curl -v http://localhost:8000/cached/groth16-vk +curl -v http://localhost:8000/cached/keyless-config +``` + +In terminal 2, mock the full node with a naive HTTP server. +```bash +cd keyless/pepper/service/resources +python3 -m http.server 4444 +``` + +Wait for 10 secs then go back to terminal 1 to retry the curl cmds. The cached data should be available. + +TODO: how to generate sample request and interact with `v0/verify` endpoint? diff --git a/keyless/pepper/service/Cargo.toml b/keyless/pepper/service/Cargo.toml index 3dc8adf9044b9..a5a321d5faae1 100644 --- a/keyless/pepper/service/Cargo.toml +++ b/keyless/pepper/service/Cargo.toml @@ -23,8 +23,10 @@ aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } aptos-types = { workspace = true } ark-bls12-381 = { workspace = true } +ark-bn254 = { workspace = true } ark-ec = { workspace = true } ark-ff = { workspace = true } +ark-groth16 = { workspace = true } ark-serialize = { workspace = true } bcs = { workspace = true } dashmap = { workspace = true } diff --git a/keyless/pepper/service/resources/groth16_vk.json b/keyless/pepper/service/resources/groth16_vk.json new file mode 100644 index 0000000000000..705f734f75374 --- /dev/null +++ b/keyless/pepper/service/resources/groth16_vk.json @@ -0,0 +1,13 @@ +{ + "type": "0x1::keyless_account::Groth16VerificationKey", + "data": { + "alpha_g1": "0xe2f26dbea299f5223b646cb1fb33eadb059d9407559d7441dfd902e3a79a4d2d", + "beta_g2": "0xabb73dc17fbc13021e2471e0c08bd67d8401f52b73d6d07483794cad4778180e0c06f33bbc4c79a9cadef253a68084d382f17788f885c9afd176f7cb2f036789", + "delta_g2": "0xb106619932d0ef372c46909a2492e246d5de739aa140e27f2c71c0470662f125219049cfe15e4d140d7e4bb911284aad1cad19880efb86f2d9dd4b1bb344ef8f", + "gamma_abc_g1": [ + "0x6123b6fea40de2a7e3595f9c35210da8a45a7e8c2f7da9eb4548e9210cfea81a", + "0x32a9b8347c512483812ee922dc75952842f8f3083edb6fe8d5c3c07e1340b683" + ], + "gamma_g2": "0xedf692d95cbdde46ddda5ef7d422436779445c5e66006a42761e1f12efde0018c212f3aeb785e49712e7a9353349aaf1255dfb31b7bf60723a480d9293938e19" + } +} \ No newline at end of file diff --git a/keyless/pepper/service/resources/keyless_config.json b/keyless/pepper/service/resources/keyless_config.json new file mode 100644 index 0000000000000..da097c690effe --- /dev/null +++ b/keyless/pepper/service/resources/keyless_config.json @@ -0,0 +1,17 @@ +{ + "type": "0x1::keyless_account::Configuration", + "data": { + "max_commited_epk_bytes": 93, + "max_exp_horizon_secs": "10000000", + "max_extra_field_bytes": 350, + "max_iss_val_bytes": 120, + "max_jwt_header_b64_bytes": 300, + "max_signatures_per_txn": 3, + "override_aud_vals": [], + "training_wheels_pubkey": { + "vec": [ + "0x5cd926a700e3997a3b319bfd003127ec7278eff14973c8cdcfbea54f3ea3669f" + ] + } + } +} diff --git a/keyless/pepper/service/src/groth16_vk.rs b/keyless/pepper/service/src/groth16_vk.rs new file mode 100644 index 0000000000000..d0be02a16c533 --- /dev/null +++ b/keyless/pepper/service/src/groth16_vk.rs @@ -0,0 +1,120 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::watcher::{unhexlify_api_bytes, ExternalResource}; +use anyhow::{anyhow, Result}; +use aptos_infallible::RwLock; +use ark_bn254::{Bn254, G1Affine, G2Affine}; +use ark_groth16::{PreparedVerifyingKey, VerifyingKey}; +use ark_serialize::CanonicalDeserialize; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; + +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct VKeyData { + pub alpha_g1: String, + pub beta_g2: String, + pub delta_g2: String, + pub gamma_abc_g1: Vec, + pub gamma_g2: String, +} + +/// On-chain representation of a VK. +/// +/// https://fullnode.testnet.aptoslabs.com/v1/accounts/0x1/resource/0x1::keyless_account::Groth16VerificationKey +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct OnChainGroth16VerificationKey { + /// Some type info returned by node API. + pub r#type: String, + pub data: VKeyData, +} + +impl OnChainGroth16VerificationKey { + pub fn to_ark_pvk(&self) -> Result> { + let mut gamma_abc_g1 = Vec::with_capacity(self.data.gamma_abc_g1.len()); + for (idx, onchain_ele) in self.data.gamma_abc_g1.iter().enumerate() { + let ark_ele = g1_from_api_repr(onchain_ele).map_err(|e| { + anyhow!("to_ark_pvk() failed with gamma_abc_g1[{idx}] convert err: {e}") + })?; + gamma_abc_g1.push(ark_ele); + } + let ark_vk = VerifyingKey { + alpha_g1: g1_from_api_repr(&self.data.alpha_g1) + .map_err(|e| anyhow!("to_ark_pvk() failed with alpha_g1 convert err: {e}"))?, + beta_g2: g2_from_api_repr(&self.data.beta_g2) + .map_err(|e| anyhow!("to_ark_pvk() failed with beta_g2 convert err: {e}"))?, + gamma_g2: g2_from_api_repr(&self.data.gamma_g2) + .map_err(|e| anyhow!("to_ark_pvk() failed with gamma_g2 convert err: {e}"))?, + delta_g2: g2_from_api_repr(&self.data.delta_g2) + .map_err(|e| anyhow!("to_ark_pvk() failed with delta_g2 convert err: {e}"))?, + gamma_abc_g1, + }; + Ok(PreparedVerifyingKey::from(ark_vk)) + } +} + +/// This variable holds the cached on-chain VK. A refresh loop exists to update it periodically. +pub static ONCHAIN_GROTH16_VK: Lazy>>> = + Lazy::new(|| Arc::new(RwLock::new(None))); + +fn g1_from_api_repr(api_repr: &str) -> Result { + let bytes = unhexlify_api_bytes(api_repr) + .map_err(|e| anyhow!("g1_from_api_repr() failed with unhex err: {e}"))?; + let ret = G1Affine::deserialize_compressed(bytes.as_slice()) + .map_err(|e| anyhow!("g1_from_api_repr() failed with g1 deser err: {e}"))?; + Ok(ret) +} + +fn g2_from_api_repr(api_repr: &str) -> Result { + let bytes = unhexlify_api_bytes(api_repr) + .map_err(|e| anyhow!("g2_from_api_repr() failed with unhex err: {e}"))?; + let ret = G2Affine::deserialize_compressed(bytes.as_slice()) + .map_err(|e| anyhow!("g2_from_api_repr() failed with g2 deser err: {e}"))?; + Ok(ret) +} + +impl ExternalResource for OnChainGroth16VerificationKey { + fn resource_name() -> String { + "OnChainGroth16VerificationKey".to_string() + } +} + +#[cfg(test)] +mod tests { + use crate::groth16_vk::{OnChainGroth16VerificationKey, VKeyData}; + use ark_bn254::{Bn254, Fr, G1Affine, G2Affine}; + use ark_groth16::Groth16; + use ark_serialize::CanonicalDeserialize; + + #[test] + fn test_to_ark_pvk() { + let api_repr = OnChainGroth16VerificationKey { + r#type: "0x1::keyless_account::Groth16VerificationKey".to_string(), + data: VKeyData { + alpha_g1: "0xe39cb24154872dbdbbdbc8056c6eb3e6cab3ad82f80ded72ed4c9301c5b3da15".to_string(), + beta_g2: "0x9a732e38644f89ad2c7bd629b84d6b81f2e83ca4b3cddfd99c0254e49332861e2fcec4f74545abdd42c8857ff8df6d3f6b3670f930d1d5ba961655ea38ded315".to_string(), + delta_g2: "0x04c7b3a2734731369a281424c2bd7af229b92496527fd0a01bfe4a5c01e0a92f256921817b6d6cf040ccd483d81738ac88571b57009f182946e8a88cced03a01".to_string(), + gamma_abc_g1: vec![ + "0x2f4f4bc4acbea0c3bae9e676fb59537e2e46994d5896e286e6fcccc7e14b1b2d".to_string(), + "0x979308443fbac05f6d22a16525c26246e965a9be68e163154f44b20d6b2ddf18".to_string(), + ], + gamma_g2: "0xedf692d95cbdde46ddda5ef7d422436779445c5e66006a42761e1f12efde0018c212f3aeb785e49712e7a9353349aaf1255dfb31b7bf60723a480d9293938e19".to_string(), + }, + }; + + let ark_pvk = api_repr.to_ark_pvk().unwrap(); + let proof = ark_groth16::Proof { + a: G1Affine::deserialize_compressed(hex::decode("fd6ae6c19f7eb7362e420e3e359f3d85c0030b779a815627b805276e45018817").unwrap().as_slice()).unwrap(), + b: G2Affine::deserialize_compressed(hex::decode("c4af5f1e793653d80009c19637b326f78a46d9d031e9e36a6f87e296ba04e31322af2d8d5c3d4129b6b2f3d222f741ce17145ab62f1b238f3f9e8c88831da297").unwrap().as_slice()).unwrap(), + c: G1Affine::deserialize_compressed(hex::decode("a856a923cde90ecb6f8955c9627ede579e67b7082431b965d011fca578892096").unwrap().as_slice()).unwrap(), + }; + let public_inputs = vec![Fr::deserialize_compressed( + hex::decode("08aba90163b227d54013b7d1a892b20edf149a23acf810acf78e8baf8e770d11") + .unwrap() + .as_slice(), + ) + .unwrap()]; + assert!(Groth16::::verify_proof(&ark_pvk, &proof, &public_inputs).unwrap()); + } +} diff --git a/keyless/pepper/service/src/keyless_config.rs b/keyless/pepper/service/src/keyless_config.rs new file mode 100644 index 0000000000000..a70b6762dee5b --- /dev/null +++ b/keyless/pepper/service/src/keyless_config.rs @@ -0,0 +1,69 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::watcher::{unhexlify_api_bytes, ExternalResource}; +use anyhow::{anyhow, Result}; +use aptos_infallible::RwLock; +use aptos_types::keyless::Configuration; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; + +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct TrainingWheelsPubKey { + vec: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct OnChainKeylessConfiguration { + /// Some type info returned by node API. + pub r#type: String, + pub data: ConfigData, +} + +impl OnChainKeylessConfiguration { + pub fn to_rust_repr(&self) -> Result { + let training_wheels_pubkey = self + .data + .training_wheels_pubkey + .vec + .first() + .map(|v| unhexlify_api_bytes(v.as_str())) + .transpose() + .map_err(|e| anyhow!("to_rust_repr() failed with unhexlify err: {e}"))?; + let ret = Configuration { + override_aud_vals: self.data.override_aud_vals.clone(), + max_signatures_per_txn: self.data.max_signatures_per_txn, + max_exp_horizon_secs: self.data.max_exp_horizon_secs.parse().map_err(|e| { + anyhow!("to_rust_repr() failed at max_exp_horizon_secs convert: {e}") + })?, + training_wheels_pubkey, + max_commited_epk_bytes: self.data.max_commited_epk_bytes, + max_iss_val_bytes: self.data.max_iss_val_bytes, + max_extra_field_bytes: self.data.max_extra_field_bytes, + max_jwt_header_b64_bytes: self.data.max_jwt_header_b64_bytes, + }; + Ok(ret) + } +} + +impl ExternalResource for OnChainKeylessConfiguration { + fn resource_name() -> String { + "OnChainKeylessConfiguration".to_string() + } +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)] +pub struct ConfigData { + pub max_commited_epk_bytes: u16, + pub max_exp_horizon_secs: String, + pub max_extra_field_bytes: u16, + pub max_iss_val_bytes: u16, + pub max_jwt_header_b64_bytes: u32, + pub max_signatures_per_txn: u16, + pub override_aud_vals: Vec, + pub training_wheels_pubkey: TrainingWheelsPubKey, +} + +pub static ONCHAIN_KEYLESS_CONFIG: Lazy>>> = + Lazy::new(|| Arc::new(RwLock::new(None))); diff --git a/keyless/pepper/service/src/lib.rs b/keyless/pepper/service/src/lib.rs index f231a7fd4d8f7..3c6fe36e779fc 100644 --- a/keyless/pepper/service/src/lib.rs +++ b/keyless/pepper/service/src/lib.rs @@ -4,6 +4,8 @@ use crate::{ account_db::{init_account_db, ACCOUNT_RECOVERY_DB}, account_managers::ACCOUNT_MANAGERS, + groth16_vk::ONCHAIN_GROTH16_VK, + keyless_config::ONCHAIN_KEYLESS_CONFIG, vuf_keys::VUF_SK, ProcessingFailure::{BadRequest, InternalError}, }; @@ -30,7 +32,7 @@ use aptos_types::{ account_address::AccountAddress, keyless::{ get_public_inputs_hash, Configuration, EphemeralCertificate, Groth16ProofAndStatement, - IdCommitment, KeylessPublicKey, KeylessSignature, OpenIdSig, DEVNET_VERIFICATION_KEY, ZKP, + IdCommitment, KeylessPublicKey, KeylessSignature, OpenIdSig, ZKP, }, transaction::authenticator::{ AnyPublicKey, AnySignature, AuthenticationKey, EphemeralPublicKey, @@ -47,9 +49,12 @@ use uuid::Uuid; pub mod about; pub mod account_db; pub mod account_managers; +pub mod groth16_vk; pub mod jwk; +pub mod keyless_config; pub mod metrics; pub mod vuf_keys; +pub mod watcher; pub type Issuer = String; pub type KeyID = String; @@ -182,7 +187,13 @@ impl HandlerTrait for V0VerifyHandler { .map_err(|e| BadRequest(format!("JWT header decoding error: {e}")))?; let jwk = jwk::cached_decoding_key_as_rsa(iss_val, &jwt_header.kid) .map_err(|e| BadRequest(format!("JWK not found: {e}")))?; - let config = Configuration::new_for_devnet(); + let config_api_repr = + { ONCHAIN_KEYLESS_CONFIG.read().as_ref().cloned() }.ok_or_else(|| { + InternalError("API keyless config not cached locally.".to_string()) + })?; + let config = config_api_repr + .to_rust_repr() + .map_err(|e| InternalError(format!("Could not parse API keyless config: {e}")))?; let training_wheels_pk = match &config.training_wheels_pubkey { None => None, // This takes ~4.4 microseconds, so we are not too concerned about speed here. @@ -247,8 +258,15 @@ impl HandlerTrait for V0VerifyHandler { } } - let result = zksig - .verify_groth16_proof(public_inputs_hash, &DEVNET_VERIFICATION_KEY); + let onchain_groth16_vk = + { ONCHAIN_GROTH16_VK.read().as_ref().cloned() }.ok_or_else( + || InternalError("No Groth16 VK cached locally.".to_string()), + )?; + let ark_groth16_pvk = onchain_groth16_vk.to_ark_pvk().map_err(|e| { + InternalError(format!("Onchain-to-ark convertion err: {e}")) + })?; + let result = + zksig.verify_groth16_proof(public_inputs_hash, &ark_groth16_pvk); result.map_err(|_| { // println!("[aptos-vm][groth16] ZKP verification failed"); // println!("[aptos-vm][groth16] PIH: {}", public_inputs_hash); diff --git a/keyless/pepper/service/src/main.rs b/keyless/pepper/service/src/main.rs index cabbd3e0262f2..6a722b3fa954e 100644 --- a/keyless/pepper/service/src/main.rs +++ b/keyless/pepper/service/src/main.rs @@ -6,9 +6,12 @@ use aptos_keyless_pepper_service::{ about::ABOUT_JSON, account_db::{init_account_db, ACCOUNT_RECOVERY_DB}, account_managers::ACCOUNT_MANAGERS, + groth16_vk::ONCHAIN_GROTH16_VK, jwk::{self, parse_jwks, DECODING_KEY_CACHE}, + keyless_config::ONCHAIN_KEYLESS_CONFIG, metrics::start_metric_server, vuf_keys::{PEPPER_VUF_VERIFICATION_KEY_JSON, VUF_SK}, + watcher::start_external_resource_refresh_loop, HandlerTrait, ProcessingFailure::{BadRequest, InternalError}, V0FetchHandler, V0SignatureHandler, V0VerifyHandler, @@ -37,6 +40,14 @@ async fn handle_request(req: Request) -> Result, Infallible (&Method::GET, "/about") => { build_response(origin, StatusCode::OK, ABOUT_JSON.deref().clone()) }, + (&Method::GET, "/cached/keyless-config") => build_response_for_optional_resource( + origin, + ONCHAIN_KEYLESS_CONFIG.read().as_ref().cloned(), + ), + (&Method::GET, "/cached/groth16-vk") => build_response_for_optional_resource( + origin, + ONCHAIN_GROTH16_VK.read().as_ref().cloned(), + ), (&Method::GET, "/v0/vuf-pub-key") => build_response( origin, StatusCode::OK, @@ -74,6 +85,20 @@ async fn main() { } aptos_logger::Logger::new().init(); start_metric_server(); + if let Ok(url) = std::env::var("ONCHAIN_GROTH16_VK_URL") { + start_external_resource_refresh_loop( + &url, + Duration::from_secs(10), + ONCHAIN_GROTH16_VK.clone(), + ); + } + if let Ok(url) = std::env::var("ONCHAIN_KEYLESS_CONFIG_URL") { + start_external_resource_refresh_loop( + &url, + Duration::from_secs(10), + ONCHAIN_KEYLESS_CONFIG.clone(), + ); + } // TODO: JWKs should be from on-chain states? jwk::start_jwk_refresh_loop( @@ -172,3 +197,16 @@ fn build_response(origin: String, status_code: StatusCode, body_str: String) -> .body(Body::from(body_str)) .expect("Response should build") } + +fn build_response_for_optional_resource( + origin: String, + res: Option, +) -> Response { + match res { + None => build_response(origin, StatusCode::NOT_FOUND, "".to_string()), + Some(val) => match serde_json::to_string(&val) { + Ok(s) => build_response(origin, StatusCode::OK, s), + Err(e) => build_response(origin, StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + }, + } +} diff --git a/keyless/pepper/service/src/watcher.rs b/keyless/pepper/service/src/watcher.rs new file mode 100644 index 0000000000000..72738e602c371 --- /dev/null +++ b/keyless/pepper/service/src/watcher.rs @@ -0,0 +1,77 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::{anyhow, ensure, Result}; +use aptos_infallible::RwLock; +use aptos_logger::{debug, info, warn}; +use serde::de::DeserializeOwned; +use std::{sync::Arc, time::Duration}; + +pub async fn fetch_and_cache_resource( + resource_url: &str, + resource_holder: &RwLock>, +) -> Result<()> { + let resource = reqwest::get(resource_url).await?.json::().await?; + *resource_holder.write() = Some(resource); + Ok(()) +} + +pub fn start_external_resource_refresh_loop< + T: DeserializeOwned + ExternalResource + Send + Sync + 'static, +>( + url: &str, + refresh_interval: Duration, + local_cache: Arc>>, +) { + info!( + "Starting external resource refresh loop for {}", + T::resource_name() + ); + let url = url.to_string(); + let _handle = tokio::spawn(async move { + loop { + let result = fetch_and_cache_resource(&url, local_cache.as_ref()).await; + match result { + Ok(_vk) => { + debug!("fetch_and_cache_resource {} succeeded.", T::resource_name()); + }, + Err(e) => { + warn!( + "fetch_and_cache_resource {} failed: {}", + T::resource_name(), + e + ); + }, + } + + tokio::time::sleep(refresh_interval).await; + } + }); +} + +pub trait ExternalResource { + fn resource_name() -> String; +} + +pub fn unhexlify_api_bytes(api_output: &str) -> Result> { + ensure!(api_output.len() >= 2); + let lower = api_output.to_lowercase(); + ensure!(&lower[0..2] == "0x"); + let bytes = hex::decode(&lower[2..]) + .map_err(|e| anyhow!("unhexlify_api_bytes() failed at decoding: {e}"))?; + Ok(bytes) +} + +#[test] +fn test_unhexlify_api_bytes() { + assert_eq!( + vec![0x00_u8, 0x01, 0xFF], + unhexlify_api_bytes("0x0001ff").unwrap() + ); + assert!(unhexlify_api_bytes("0x").unwrap().is_empty()); + assert!(unhexlify_api_bytes("0001ff").is_err()); + assert!(unhexlify_api_bytes("0x0001fg").is_err()); + assert!(unhexlify_api_bytes("000").is_err()); + assert!(unhexlify_api_bytes("0").is_err()); + assert!(unhexlify_api_bytes("").is_err()); +} diff --git a/protos/proto/aptos/transaction/v1/transaction.proto b/protos/proto/aptos/transaction/v1/transaction.proto index 19331b83bf293..7d3ee043a5e91 100644 --- a/protos/proto/aptos/transaction/v1/transaction.proto +++ b/protos/proto/aptos/transaction/v1/transaction.proto @@ -581,6 +581,11 @@ message MultiKeySignature { uint32 signatures_required = 3; } +message AbstractionSignature { + string function_info = 1; + bytes signature = 2; +} + message SingleSender { AccountSignature sender = 1; } @@ -592,6 +597,7 @@ message AccountSignature { TYPE_MULTI_ED25519 = 2; TYPE_SINGLE_KEY = 4; TYPE_MULTI_KEY = 5; + TYPE_ABSTRACTION = 6; reserved 3; } @@ -603,6 +609,7 @@ message AccountSignature { // 4 is reserved. SingleKeySignature single_key_signature = 5; MultiKeySignature multi_key_signature = 6; + AbstractionSignature abstraction = 7; } } diff --git a/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.py b/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.py index 7dcb01b77feb9..f11d41489c2a2 100644 --- a/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.py +++ b/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.py @@ -17,7 +17,7 @@ ) DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n&aptos/transaction/v1/transaction.proto\x12\x14\x61ptos.transaction.v1\x1a$aptos/util/timestamp/timestamp.proto"\x9a\x01\n\x05\x42lock\x12\x32\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x12\n\x06height\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x37\n\x0ctransactions\x18\x03 \x03(\x0b\x32!.aptos.transaction.v1.Transaction\x12\x10\n\x08\x63hain_id\x18\x04 \x01(\r"\xda\x07\n\x0bTransaction\x12\x32\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x13\n\x07version\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x33\n\x04info\x18\x03 \x01(\x0b\x32%.aptos.transaction.v1.TransactionInfo\x12\x11\n\x05\x65poch\x18\x04 \x01(\x04\x42\x02\x30\x01\x12\x18\n\x0c\x62lock_height\x18\x05 \x01(\x04\x42\x02\x30\x01\x12?\n\x04type\x18\x06 \x01(\x0e\x32\x31.aptos.transaction.v1.Transaction.TransactionType\x12H\n\x0e\x62lock_metadata\x18\x07 \x01(\x0b\x32..aptos.transaction.v1.BlockMetadataTransactionH\x00\x12;\n\x07genesis\x18\x08 \x01(\x0b\x32(.aptos.transaction.v1.GenesisTransactionH\x00\x12L\n\x10state_checkpoint\x18\t \x01(\x0b\x32\x30.aptos.transaction.v1.StateCheckpointTransactionH\x00\x12\x35\n\x04user\x18\n \x01(\x0b\x32%.aptos.transaction.v1.UserTransactionH\x00\x12?\n\tvalidator\x18\x15 \x01(\x0b\x32*.aptos.transaction.v1.ValidatorTransactionH\x00\x12H\n\x0e\x62lock_epilogue\x18\x17 \x01(\x0b\x32..aptos.transaction.v1.BlockEpilogueTransactionH\x00\x12<\n\tsize_info\x18\x16 \x01(\x0b\x32).aptos.transaction.v1.TransactionSizeInfo"\xfd\x01\n\x0fTransactionType\x12 \n\x1cTRANSACTION_TYPE_UNSPECIFIED\x10\x00\x12\x1c\n\x18TRANSACTION_TYPE_GENESIS\x10\x01\x12#\n\x1fTRANSACTION_TYPE_BLOCK_METADATA\x10\x02\x12%\n!TRANSACTION_TYPE_STATE_CHECKPOINT\x10\x03\x12\x19\n\x15TRANSACTION_TYPE_USER\x10\x04\x12\x1e\n\x1aTRANSACTION_TYPE_VALIDATOR\x10\x14\x12#\n\x1fTRANSACTION_TYPE_BLOCK_EPILOGUE\x10\x15\x42\n\n\x08txn_data"\xbe\x01\n\x18\x42lockMetadataTransaction\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\x05round\x18\x02 \x01(\x04\x42\x02\x30\x01\x12+\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event\x12#\n\x1bprevious_block_votes_bitvec\x18\x04 \x01(\x0c\x12\x10\n\x08proposer\x18\x05 \x01(\t\x12\x1f\n\x17\x66\x61iled_proposer_indices\x18\x06 \x03(\r"r\n\x12GenesisTransaction\x12/\n\x07payload\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.WriteSet\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x1c\n\x1aStateCheckpointTransaction"\xfa\n\n\x14ValidatorTransaction\x12[\n\x13observed_jwk_update\x18\x01 \x01(\x0b\x32<.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdateH\x00\x12J\n\ndkg_update\x18\x02 \x01(\x0b\x32\x34.aptos.transaction.v1.ValidatorTransaction.DkgUpdateH\x00\x12+\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event\x1a\xc4\x07\n\x11ObservedJwkUpdate\x12s\n\x17quorum_certified_update\x18\x01 \x01(\x0b\x32R.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.QuorumCertifiedUpdate\x1a\x8d\x04\n\x14\x45xportedProviderJWKs\x12\x0e\n\x06issuer\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\x04\x12\x63\n\x04jwks\x18\x03 \x03(\x0b\x32U.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK\x1a\xee\x02\n\x03JWK\x12\x7f\n\x0funsupported_jwk\x18\x01 \x01(\x0b\x32\x64.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK.UnsupportedJWKH\x00\x12h\n\x03rsa\x18\x02 \x01(\x0b\x32Y.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK.RSAH\x00\x1a\x42\n\x03RSA\x12\x0b\n\x03kid\x18\x01 \x01(\t\x12\x0b\n\x03kty\x18\x02 \x01(\t\x12\x0b\n\x03\x61lg\x18\x03 \x01(\t\x12\t\n\x01\x65\x18\x04 \x01(\t\x12\t\n\x01n\x18\x05 \x01(\t\x1a-\n\x0eUnsupportedJWK\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x42\t\n\x07JwkType\x1a\x41\n\x1a\x45xportedAggregateSignature\x12\x16\n\x0esigner_indices\x18\x01 \x03(\x04\x12\x0b\n\x03sig\x18\x02 \x01(\x0c\x1a\xe6\x01\n\x15QuorumCertifiedUpdate\x12\x61\n\x06update\x18\x01 \x01(\x0b\x32Q.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs\x12j\n\tmulti_sig\x18\x02 \x01(\x0b\x32W.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedAggregateSignature\x1a\xa8\x01\n\tDkgUpdate\x12Z\n\x0e\x64kg_transcript\x18\x01 \x01(\x0b\x32\x42.aptos.transaction.v1.ValidatorTransaction.DkgUpdate.DkgTranscript\x1a?\n\rDkgTranscript\x12\r\n\x05\x65poch\x18\x01 \x01(\x04\x12\x0e\n\x06\x61uthor\x18\x02 \x01(\t\x12\x0f\n\x07payload\x18\x03 \x01(\x0c\x42\x1a\n\x18ValidatorTransactionType"n\n\x18\x42lockEpilogueTransaction\x12?\n\x0e\x62lock_end_info\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.BlockEndInfoH\x00\x88\x01\x01\x42\x11\n\x0f_block_end_info"\x9e\x01\n\x0c\x42lockEndInfo\x12\x1f\n\x17\x62lock_gas_limit_reached\x18\x01 \x01(\x08\x12"\n\x1a\x62lock_output_limit_reached\x18\x02 \x01(\x08\x12\'\n\x1f\x62lock_effective_block_gas_units\x18\x03 \x01(\x04\x12 \n\x18\x62lock_approx_output_size\x18\x04 \x01(\x04"}\n\x0fUserTransaction\x12=\n\x07request\x18\x01 \x01(\x0b\x32,.aptos.transaction.v1.UserTransactionRequest\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x9f\x01\n\x05\x45vent\x12+\n\x03key\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.EventKey\x12\x1b\n\x0fsequence_number\x18\x02 \x01(\x04\x42\x02\x30\x01\x12,\n\x04type\x18\x03 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x10\n\x08type_str\x18\x05 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\t"\xa1\x02\n\x0fTransactionInfo\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\x19\n\x11state_change_hash\x18\x02 \x01(\x0c\x12\x17\n\x0f\x65vent_root_hash\x18\x03 \x01(\x0c\x12"\n\x15state_checkpoint_hash\x18\x04 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x08gas_used\x18\x05 \x01(\x04\x42\x02\x30\x01\x12\x0f\n\x07success\x18\x06 \x01(\x08\x12\x11\n\tvm_status\x18\x07 \x01(\t\x12\x1d\n\x15\x61\x63\x63umulator_root_hash\x18\x08 \x01(\x0c\x12\x35\n\x07\x63hanges\x18\t \x03(\x0b\x32$.aptos.transaction.v1.WriteSetChangeB\x18\n\x16_state_checkpoint_hash"@\n\x08\x45ventKey\x12\x1b\n\x0f\x63reation_number\x18\x01 \x01(\x04\x42\x02\x30\x01\x12\x17\n\x0f\x61\x63\x63ount_address\x18\x02 \x01(\t"\xb0\x02\n\x16UserTransactionRequest\x12\x0e\n\x06sender\x18\x01 \x01(\t\x12\x1b\n\x0fsequence_number\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x1a\n\x0emax_gas_amount\x18\x03 \x01(\x04\x42\x02\x30\x01\x12\x1a\n\x0egas_unit_price\x18\x04 \x01(\x04\x42\x02\x30\x01\x12\x42\n\x19\x65xpiration_timestamp_secs\x18\x05 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x39\n\x07payload\x18\x06 \x01(\x0b\x32(.aptos.transaction.v1.TransactionPayload\x12\x32\n\tsignature\x18\x07 \x01(\x0b\x32\x1f.aptos.transaction.v1.Signature"\xda\x02\n\x08WriteSet\x12\x43\n\x0ewrite_set_type\x18\x01 \x01(\x0e\x32+.aptos.transaction.v1.WriteSet.WriteSetType\x12@\n\x10script_write_set\x18\x02 \x01(\x0b\x32$.aptos.transaction.v1.ScriptWriteSetH\x00\x12@\n\x10\x64irect_write_set\x18\x03 \x01(\x0b\x32$.aptos.transaction.v1.DirectWriteSetH\x00"x\n\x0cWriteSetType\x12\x1e\n\x1aWRITE_SET_TYPE_UNSPECIFIED\x10\x00\x12#\n\x1fWRITE_SET_TYPE_SCRIPT_WRITE_SET\x10\x01\x12#\n\x1fWRITE_SET_TYPE_DIRECT_WRITE_SET\x10\x02\x42\x0b\n\twrite_set"Y\n\x0eScriptWriteSet\x12\x12\n\nexecute_as\x18\x01 \x01(\t\x12\x33\n\x06script\x18\x02 \x01(\x0b\x32#.aptos.transaction.v1.ScriptPayload"}\n\x0e\x44irectWriteSet\x12>\n\x10write_set_change\x18\x01 \x03(\x0b\x32$.aptos.transaction.v1.WriteSetChange\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x89\x05\n\x0eWriteSetChange\x12\x37\n\x04type\x18\x01 \x01(\x0e\x32).aptos.transaction.v1.WriteSetChange.Type\x12;\n\rdelete_module\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.DeleteModuleH\x00\x12?\n\x0f\x64\x65lete_resource\x18\x03 \x01(\x0b\x32$.aptos.transaction.v1.DeleteResourceH\x00\x12\x42\n\x11\x64\x65lete_table_item\x18\x04 \x01(\x0b\x32%.aptos.transaction.v1.DeleteTableItemH\x00\x12\x39\n\x0cwrite_module\x18\x05 \x01(\x0b\x32!.aptos.transaction.v1.WriteModuleH\x00\x12=\n\x0ewrite_resource\x18\x06 \x01(\x0b\x32#.aptos.transaction.v1.WriteResourceH\x00\x12@\n\x10write_table_item\x18\x07 \x01(\x0b\x32$.aptos.transaction.v1.WriteTableItemH\x00"\xb5\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12TYPE_DELETE_MODULE\x10\x01\x12\x18\n\x14TYPE_DELETE_RESOURCE\x10\x02\x12\x1a\n\x16TYPE_DELETE_TABLE_ITEM\x10\x03\x12\x15\n\x11TYPE_WRITE_MODULE\x10\x04\x12\x17\n\x13TYPE_WRITE_RESOURCE\x10\x05\x12\x19\n\x15TYPE_WRITE_TABLE_ITEM\x10\x06\x42\x08\n\x06\x63hange"k\n\x0c\x44\x65leteModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x32\n\x06module\x18\x03 \x01(\x0b\x32".aptos.transaction.v1.MoveModuleId"~\n\x0e\x44\x65leteResource\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x31\n\x04type\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTag\x12\x10\n\x08type_str\x18\x04 \x01(\t"{\n\x0f\x44\x65leteTableItem\x12\x16\n\x0estate_key_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\t\x12\x33\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32%.aptos.transaction.v1.DeleteTableData"0\n\x0f\x44\x65leteTableData\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x10\n\x08key_type\x18\x02 \x01(\t"n\n\x0bWriteModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x36\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32(.aptos.transaction.v1.MoveModuleBytecode"\x8b\x01\n\rWriteResource\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x31\n\x04type\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTag\x12\x10\n\x08type_str\x18\x04 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\t"R\n\x0eWriteTableData\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x10\n\x08key_type\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\t\x12\x12\n\nvalue_type\x18\x04 \x01(\t"y\n\x0eWriteTableItem\x12\x16\n\x0estate_key_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\t\x12\x32\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32$.aptos.transaction.v1.WriteTableData"\x8c\x04\n\x12TransactionPayload\x12;\n\x04type\x18\x01 \x01(\x0e\x32-.aptos.transaction.v1.TransactionPayload.Type\x12L\n\x16\x65ntry_function_payload\x18\x02 \x01(\x0b\x32*.aptos.transaction.v1.EntryFunctionPayloadH\x00\x12=\n\x0escript_payload\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.ScriptPayloadH\x00\x12\x42\n\x11write_set_payload\x18\x05 \x01(\x0b\x32%.aptos.transaction.v1.WriteSetPayloadH\x00\x12\x41\n\x10multisig_payload\x18\x06 \x01(\x0b\x32%.aptos.transaction.v1.MultisigPayloadH\x00"\x93\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bTYPE_ENTRY_FUNCTION_PAYLOAD\x10\x01\x12\x17\n\x13TYPE_SCRIPT_PAYLOAD\x10\x02\x12\x1a\n\x16TYPE_WRITE_SET_PAYLOAD\x10\x04\x12\x19\n\x15TYPE_MULTISIG_PAYLOAD\x10\x05"\x04\x08\x03\x10\x03\x42\t\n\x07payloadJ\x04\x08\x04\x10\x05"\xb9\x01\n\x14\x45ntryFunctionPayload\x12\x37\n\x08\x66unction\x18\x01 \x01(\x0b\x32%.aptos.transaction.v1.EntryFunctionId\x12\x36\n\x0etype_arguments\x18\x02 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x11\n\targuments\x18\x03 \x03(\t\x12\x1d\n\x15\x65ntry_function_id_str\x18\x04 \x01(\t"W\n\x12MoveScriptBytecode\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12/\n\x03\x61\x62i\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.MoveFunction"\x92\x01\n\rScriptPayload\x12\x36\n\x04\x63ode\x18\x01 \x01(\x0b\x32(.aptos.transaction.v1.MoveScriptBytecode\x12\x36\n\x0etype_arguments\x18\x02 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x11\n\targuments\x18\x03 \x03(\t"\x97\x01\n\x0fMultisigPayload\x12\x18\n\x10multisig_address\x18\x01 \x01(\t\x12R\n\x13transaction_payload\x18\x02 \x01(\x0b\x32\x30.aptos.transaction.v1.MultisigTransactionPayloadH\x00\x88\x01\x01\x42\x16\n\x14_transaction_payload"\xf9\x01\n\x1aMultisigTransactionPayload\x12\x43\n\x04type\x18\x01 \x01(\x0e\x32\x35.aptos.transaction.v1.MultisigTransactionPayload.Type\x12L\n\x16\x65ntry_function_payload\x18\x02 \x01(\x0b\x32*.aptos.transaction.v1.EntryFunctionPayloadH\x00"=\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bTYPE_ENTRY_FUNCTION_PAYLOAD\x10\x01\x42\t\n\x07payload"U\n\x12MoveModuleBytecode\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12-\n\x03\x61\x62i\x18\x02 \x01(\x0b\x32 .aptos.transaction.v1.MoveModule"\xd2\x01\n\nMoveModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x33\n\x07\x66riends\x18\x03 \x03(\x0b\x32".aptos.transaction.v1.MoveModuleId\x12=\n\x11\x65xposed_functions\x18\x04 \x03(\x0b\x32".aptos.transaction.v1.MoveFunction\x12\x31\n\x07structs\x18\x05 \x03(\x0b\x32 .aptos.transaction.v1.MoveStruct"\x92\x03\n\x0cMoveFunction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x41\n\nvisibility\x18\x02 \x01(\x0e\x32-.aptos.transaction.v1.MoveFunction.Visibility\x12\x10\n\x08is_entry\x18\x03 \x01(\x08\x12O\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x32.aptos.transaction.v1.MoveFunctionGenericTypeParam\x12.\n\x06params\x18\x05 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12.\n\x06return\x18\x06 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType"n\n\nVisibility\x12\x1a\n\x16VISIBILITY_UNSPECIFIED\x10\x00\x12\x16\n\x12VISIBILITY_PRIVATE\x10\x01\x12\x15\n\x11VISIBILITY_PUBLIC\x10\x02\x12\x15\n\x11VISIBILITY_FRIEND\x10\x03"\xfb\x01\n\nMoveStruct\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tis_native\x18\x02 \x01(\x08\x12\x10\n\x08is_event\x18\x06 \x01(\x08\x12\x34\n\tabilities\x18\x03 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility\x12M\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x30.aptos.transaction.v1.MoveStructGenericTypeParam\x12\x35\n\x06\x66ields\x18\x05 \x03(\x0b\x32%.aptos.transaction.v1.MoveStructField"h\n\x1aMoveStructGenericTypeParam\x12\x36\n\x0b\x63onstraints\x18\x01 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility\x12\x12\n\nis_phantom\x18\x02 \x01(\x08"M\n\x0fMoveStructField\x12\x0c\n\x04name\x18\x01 \x01(\t\x12,\n\x04type\x18\x02 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveType"V\n\x1cMoveFunctionGenericTypeParam\x12\x36\n\x0b\x63onstraints\x18\x01 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility"\xf8\x02\n\x08MoveType\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.aptos.transaction.v1.MoveTypes\x12\x30\n\x06vector\x18\x03 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveTypeH\x00\x12\x35\n\x06struct\x18\x04 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTagH\x00\x12"\n\x18generic_type_param_index\x18\x05 \x01(\rH\x00\x12\x41\n\treference\x18\x06 \x01(\x0b\x32,.aptos.transaction.v1.MoveType.ReferenceTypeH\x00\x12\x14\n\nunparsable\x18\x07 \x01(\tH\x00\x1aL\n\rReferenceType\x12\x0f\n\x07mutable\x18\x01 \x01(\x08\x12*\n\x02to\x18\x02 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveTypeB\t\n\x07\x63ontent"D\n\x0fWriteSetPayload\x12\x31\n\twrite_set\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.WriteSet"S\n\x0f\x45ntryFunctionId\x12\x32\n\x06module\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.MoveModuleId\x12\x0c\n\x04name\x18\x02 \x01(\t"-\n\x0cMoveModuleId\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t"{\n\rMoveStructTag\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0e\n\x06module\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12;\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType"\x9b\x04\n\tSignature\x12\x32\n\x04type\x18\x01 \x01(\x0e\x32$.aptos.transaction.v1.Signature.Type\x12\x39\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x02 \x01(\x0b\x32&.aptos.transaction.v1.Ed25519SignatureH\x00\x12\x44\n\rmulti_ed25519\x18\x03 \x01(\x0b\x32+.aptos.transaction.v1.MultiEd25519SignatureH\x00\x12@\n\x0bmulti_agent\x18\x04 \x01(\x0b\x32).aptos.transaction.v1.MultiAgentSignatureH\x00\x12<\n\tfee_payer\x18\x05 \x01(\x0b\x32\'.aptos.transaction.v1.FeePayerSignatureH\x00\x12;\n\rsingle_sender\x18\x07 \x01(\x0b\x32".aptos.transaction.v1.SingleSenderH\x00"\x8e\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x16\n\x12TYPE_MULTI_ED25519\x10\x02\x12\x14\n\x10TYPE_MULTI_AGENT\x10\x03\x12\x12\n\x0eTYPE_FEE_PAYER\x10\x04\x12\x16\n\x12TYPE_SINGLE_SENDER\x10\x06"\x04\x08\x05\x10\x05\x42\x0b\n\tsignature"9\n\x10\x45\x64\x32\x35\x35\x31\x39Signature\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c"o\n\x15MultiEd25519Signature\x12\x13\n\x0bpublic_keys\x18\x01 \x03(\x0c\x12\x12\n\nsignatures\x18\x02 \x03(\x0c\x12\x11\n\tthreshold\x18\x03 \x01(\r\x12\x1a\n\x12public_key_indices\x18\x04 \x03(\r"\xb4\x01\n\x13MultiAgentSignature\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12"\n\x1asecondary_signer_addresses\x18\x02 \x03(\t\x12\x41\n\x11secondary_signers\x18\x03 \x03(\x0b\x32&.aptos.transaction.v1.AccountSignature"\x8f\x02\n\x11\x46\x65\x65PayerSignature\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12"\n\x1asecondary_signer_addresses\x18\x02 \x03(\t\x12\x41\n\x11secondary_signers\x18\x03 \x03(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12\x19\n\x11\x66\x65\x65_payer_address\x18\x04 \x01(\t\x12@\n\x10\x66\x65\x65_payer_signer\x18\x05 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature"\xec\x01\n\x0c\x41nyPublicKey\x12\x35\n\x04type\x18\x01 \x01(\x0e\x32\'.aptos.transaction.v1.AnyPublicKey.Type\x12\x12\n\npublic_key\x18\x02 \x01(\x0c"\x90\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x18\n\x14TYPE_SECP256K1_ECDSA\x10\x02\x12\x18\n\x14TYPE_SECP256R1_ECDSA\x10\x03\x12\x10\n\x0cTYPE_KEYLESS\x10\x04\x12\x1a\n\x16TYPE_FEDERATED_KEYLESS\x10\x05"\xb9\x03\n\x0c\x41nySignature\x12\x35\n\x04type\x18\x01 \x01(\x0e\x32\'.aptos.transaction.v1.AnySignature.Type\x12\x15\n\tsignature\x18\x02 \x01(\x0c\x42\x02\x18\x01\x12\x30\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x03 \x01(\x0b\x32\x1d.aptos.transaction.v1.Ed25519H\x00\x12?\n\x0fsecp256k1_ecdsa\x18\x04 \x01(\x0b\x32$.aptos.transaction.v1.Secp256k1EcdsaH\x00\x12\x32\n\x08webauthn\x18\x05 \x01(\x0b\x32\x1e.aptos.transaction.v1.WebAuthnH\x00\x12\x30\n\x07keyless\x18\x06 \x01(\x0b\x32\x1d.aptos.transaction.v1.KeylessH\x00"m\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x18\n\x14TYPE_SECP256K1_ECDSA\x10\x02\x12\x11\n\rTYPE_WEBAUTHN\x10\x03\x12\x10\n\x0cTYPE_KEYLESS\x10\x04\x42\x13\n\x11signature_variant"\x1c\n\x07\x45\x64\x32\x35\x35\x31\x39\x12\x11\n\tsignature\x18\x01 \x01(\x0c"#\n\x0eSecp256k1Ecdsa\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x1d\n\x08WebAuthn\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x1c\n\x07Keyless\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x83\x01\n\x12SingleKeySignature\x12\x36\n\npublic_key\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.AnyPublicKey\x12\x35\n\tsignature\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.AnySignature"X\n\x10IndexedSignature\x12\r\n\x05index\x18\x01 \x01(\r\x12\x35\n\tsignature\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.AnySignature"\xa5\x01\n\x11MultiKeySignature\x12\x37\n\x0bpublic_keys\x18\x01 \x03(\x0b\x32".aptos.transaction.v1.AnyPublicKey\x12:\n\nsignatures\x18\x02 \x03(\x0b\x32&.aptos.transaction.v1.IndexedSignature\x12\x1b\n\x13signatures_required\x18\x03 \x01(\r"F\n\x0cSingleSender\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature"\xe4\x03\n\x10\x41\x63\x63ountSignature\x12\x39\n\x04type\x18\x01 \x01(\x0e\x32+.aptos.transaction.v1.AccountSignature.Type\x12\x39\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x02 \x01(\x0b\x32&.aptos.transaction.v1.Ed25519SignatureH\x00\x12\x44\n\rmulti_ed25519\x18\x03 \x01(\x0b\x32+.aptos.transaction.v1.MultiEd25519SignatureH\x00\x12H\n\x14single_key_signature\x18\x05 \x01(\x0b\x32(.aptos.transaction.v1.SingleKeySignatureH\x00\x12\x46\n\x13multi_key_signature\x18\x06 \x01(\x0b\x32\'.aptos.transaction.v1.MultiKeySignatureH\x00"u\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x16\n\x12TYPE_MULTI_ED25519\x10\x02\x12\x13\n\x0fTYPE_SINGLE_KEY\x10\x04\x12\x12\n\x0eTYPE_MULTI_KEY\x10\x05"\x04\x08\x03\x10\x03\x42\x0b\n\tsignature"\xb1\x01\n\x13TransactionSizeInfo\x12\x19\n\x11transaction_bytes\x18\x01 \x01(\r\x12<\n\x0f\x65vent_size_info\x18\x02 \x03(\x0b\x32#.aptos.transaction.v1.EventSizeInfo\x12\x41\n\x12write_op_size_info\x18\x03 \x03(\x0b\x32%.aptos.transaction.v1.WriteOpSizeInfo"<\n\rEventSizeInfo\x12\x16\n\x0etype_tag_bytes\x18\x01 \x01(\r\x12\x13\n\x0btotal_bytes\x18\x02 \x01(\r"9\n\x0fWriteOpSizeInfo\x12\x11\n\tkey_bytes\x18\x01 \x01(\r\x12\x13\n\x0bvalue_bytes\x18\x02 \x01(\r*\xea\x02\n\tMoveTypes\x12\x1a\n\x16MOVE_TYPES_UNSPECIFIED\x10\x00\x12\x13\n\x0fMOVE_TYPES_BOOL\x10\x01\x12\x11\n\rMOVE_TYPES_U8\x10\x02\x12\x12\n\x0eMOVE_TYPES_U16\x10\x0c\x12\x12\n\x0eMOVE_TYPES_U32\x10\r\x12\x12\n\x0eMOVE_TYPES_U64\x10\x03\x12\x13\n\x0fMOVE_TYPES_U128\x10\x04\x12\x13\n\x0fMOVE_TYPES_U256\x10\x0e\x12\x16\n\x12MOVE_TYPES_ADDRESS\x10\x05\x12\x15\n\x11MOVE_TYPES_SIGNER\x10\x06\x12\x15\n\x11MOVE_TYPES_VECTOR\x10\x07\x12\x15\n\x11MOVE_TYPES_STRUCT\x10\x08\x12!\n\x1dMOVE_TYPES_GENERIC_TYPE_PARAM\x10\t\x12\x18\n\x14MOVE_TYPES_REFERENCE\x10\n\x12\x19\n\x15MOVE_TYPES_UNPARSABLE\x10\x0b*\x87\x01\n\x0bMoveAbility\x12\x1c\n\x18MOVE_ABILITY_UNSPECIFIED\x10\x00\x12\x15\n\x11MOVE_ABILITY_COPY\x10\x01\x12\x15\n\x11MOVE_ABILITY_DROP\x10\x02\x12\x16\n\x12MOVE_ABILITY_STORE\x10\x03\x12\x14\n\x10MOVE_ABILITY_KEY\x10\x04\x62\x06proto3' + b'\n&aptos/transaction/v1/transaction.proto\x12\x14\x61ptos.transaction.v1\x1a$aptos/util/timestamp/timestamp.proto"\x9a\x01\n\x05\x42lock\x12\x32\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x12\n\x06height\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x37\n\x0ctransactions\x18\x03 \x03(\x0b\x32!.aptos.transaction.v1.Transaction\x12\x10\n\x08\x63hain_id\x18\x04 \x01(\r"\xda\x07\n\x0bTransaction\x12\x32\n\ttimestamp\x18\x01 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x13\n\x07version\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x33\n\x04info\x18\x03 \x01(\x0b\x32%.aptos.transaction.v1.TransactionInfo\x12\x11\n\x05\x65poch\x18\x04 \x01(\x04\x42\x02\x30\x01\x12\x18\n\x0c\x62lock_height\x18\x05 \x01(\x04\x42\x02\x30\x01\x12?\n\x04type\x18\x06 \x01(\x0e\x32\x31.aptos.transaction.v1.Transaction.TransactionType\x12H\n\x0e\x62lock_metadata\x18\x07 \x01(\x0b\x32..aptos.transaction.v1.BlockMetadataTransactionH\x00\x12;\n\x07genesis\x18\x08 \x01(\x0b\x32(.aptos.transaction.v1.GenesisTransactionH\x00\x12L\n\x10state_checkpoint\x18\t \x01(\x0b\x32\x30.aptos.transaction.v1.StateCheckpointTransactionH\x00\x12\x35\n\x04user\x18\n \x01(\x0b\x32%.aptos.transaction.v1.UserTransactionH\x00\x12?\n\tvalidator\x18\x15 \x01(\x0b\x32*.aptos.transaction.v1.ValidatorTransactionH\x00\x12H\n\x0e\x62lock_epilogue\x18\x17 \x01(\x0b\x32..aptos.transaction.v1.BlockEpilogueTransactionH\x00\x12<\n\tsize_info\x18\x16 \x01(\x0b\x32).aptos.transaction.v1.TransactionSizeInfo"\xfd\x01\n\x0fTransactionType\x12 \n\x1cTRANSACTION_TYPE_UNSPECIFIED\x10\x00\x12\x1c\n\x18TRANSACTION_TYPE_GENESIS\x10\x01\x12#\n\x1fTRANSACTION_TYPE_BLOCK_METADATA\x10\x02\x12%\n!TRANSACTION_TYPE_STATE_CHECKPOINT\x10\x03\x12\x19\n\x15TRANSACTION_TYPE_USER\x10\x04\x12\x1e\n\x1aTRANSACTION_TYPE_VALIDATOR\x10\x14\x12#\n\x1fTRANSACTION_TYPE_BLOCK_EPILOGUE\x10\x15\x42\n\n\x08txn_data"\xbe\x01\n\x18\x42lockMetadataTransaction\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\x05round\x18\x02 \x01(\x04\x42\x02\x30\x01\x12+\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event\x12#\n\x1bprevious_block_votes_bitvec\x18\x04 \x01(\x0c\x12\x10\n\x08proposer\x18\x05 \x01(\t\x12\x1f\n\x17\x66\x61iled_proposer_indices\x18\x06 \x03(\r"r\n\x12GenesisTransaction\x12/\n\x07payload\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.WriteSet\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x1c\n\x1aStateCheckpointTransaction"\xfa\n\n\x14ValidatorTransaction\x12[\n\x13observed_jwk_update\x18\x01 \x01(\x0b\x32<.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdateH\x00\x12J\n\ndkg_update\x18\x02 \x01(\x0b\x32\x34.aptos.transaction.v1.ValidatorTransaction.DkgUpdateH\x00\x12+\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event\x1a\xc4\x07\n\x11ObservedJwkUpdate\x12s\n\x17quorum_certified_update\x18\x01 \x01(\x0b\x32R.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.QuorumCertifiedUpdate\x1a\x8d\x04\n\x14\x45xportedProviderJWKs\x12\x0e\n\x06issuer\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\x04\x12\x63\n\x04jwks\x18\x03 \x03(\x0b\x32U.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK\x1a\xee\x02\n\x03JWK\x12\x7f\n\x0funsupported_jwk\x18\x01 \x01(\x0b\x32\x64.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK.UnsupportedJWKH\x00\x12h\n\x03rsa\x18\x02 \x01(\x0b\x32Y.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs.JWK.RSAH\x00\x1a\x42\n\x03RSA\x12\x0b\n\x03kid\x18\x01 \x01(\t\x12\x0b\n\x03kty\x18\x02 \x01(\t\x12\x0b\n\x03\x61lg\x18\x03 \x01(\t\x12\t\n\x01\x65\x18\x04 \x01(\t\x12\t\n\x01n\x18\x05 \x01(\t\x1a-\n\x0eUnsupportedJWK\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x42\t\n\x07JwkType\x1a\x41\n\x1a\x45xportedAggregateSignature\x12\x16\n\x0esigner_indices\x18\x01 \x03(\x04\x12\x0b\n\x03sig\x18\x02 \x01(\x0c\x1a\xe6\x01\n\x15QuorumCertifiedUpdate\x12\x61\n\x06update\x18\x01 \x01(\x0b\x32Q.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedProviderJWKs\x12j\n\tmulti_sig\x18\x02 \x01(\x0b\x32W.aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate.ExportedAggregateSignature\x1a\xa8\x01\n\tDkgUpdate\x12Z\n\x0e\x64kg_transcript\x18\x01 \x01(\x0b\x32\x42.aptos.transaction.v1.ValidatorTransaction.DkgUpdate.DkgTranscript\x1a?\n\rDkgTranscript\x12\r\n\x05\x65poch\x18\x01 \x01(\x04\x12\x0e\n\x06\x61uthor\x18\x02 \x01(\t\x12\x0f\n\x07payload\x18\x03 \x01(\x0c\x42\x1a\n\x18ValidatorTransactionType"n\n\x18\x42lockEpilogueTransaction\x12?\n\x0e\x62lock_end_info\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.BlockEndInfoH\x00\x88\x01\x01\x42\x11\n\x0f_block_end_info"\x9e\x01\n\x0c\x42lockEndInfo\x12\x1f\n\x17\x62lock_gas_limit_reached\x18\x01 \x01(\x08\x12"\n\x1a\x62lock_output_limit_reached\x18\x02 \x01(\x08\x12\'\n\x1f\x62lock_effective_block_gas_units\x18\x03 \x01(\x04\x12 \n\x18\x62lock_approx_output_size\x18\x04 \x01(\x04"}\n\x0fUserTransaction\x12=\n\x07request\x18\x01 \x01(\x0b\x32,.aptos.transaction.v1.UserTransactionRequest\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x9f\x01\n\x05\x45vent\x12+\n\x03key\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.EventKey\x12\x1b\n\x0fsequence_number\x18\x02 \x01(\x04\x42\x02\x30\x01\x12,\n\x04type\x18\x03 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x10\n\x08type_str\x18\x05 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\t"\xa1\x02\n\x0fTransactionInfo\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\x19\n\x11state_change_hash\x18\x02 \x01(\x0c\x12\x17\n\x0f\x65vent_root_hash\x18\x03 \x01(\x0c\x12"\n\x15state_checkpoint_hash\x18\x04 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x08gas_used\x18\x05 \x01(\x04\x42\x02\x30\x01\x12\x0f\n\x07success\x18\x06 \x01(\x08\x12\x11\n\tvm_status\x18\x07 \x01(\t\x12\x1d\n\x15\x61\x63\x63umulator_root_hash\x18\x08 \x01(\x0c\x12\x35\n\x07\x63hanges\x18\t \x03(\x0b\x32$.aptos.transaction.v1.WriteSetChangeB\x18\n\x16_state_checkpoint_hash"@\n\x08\x45ventKey\x12\x1b\n\x0f\x63reation_number\x18\x01 \x01(\x04\x42\x02\x30\x01\x12\x17\n\x0f\x61\x63\x63ount_address\x18\x02 \x01(\t"\xb0\x02\n\x16UserTransactionRequest\x12\x0e\n\x06sender\x18\x01 \x01(\t\x12\x1b\n\x0fsequence_number\x18\x02 \x01(\x04\x42\x02\x30\x01\x12\x1a\n\x0emax_gas_amount\x18\x03 \x01(\x04\x42\x02\x30\x01\x12\x1a\n\x0egas_unit_price\x18\x04 \x01(\x04\x42\x02\x30\x01\x12\x42\n\x19\x65xpiration_timestamp_secs\x18\x05 \x01(\x0b\x32\x1f.aptos.util.timestamp.Timestamp\x12\x39\n\x07payload\x18\x06 \x01(\x0b\x32(.aptos.transaction.v1.TransactionPayload\x12\x32\n\tsignature\x18\x07 \x01(\x0b\x32\x1f.aptos.transaction.v1.Signature"\xda\x02\n\x08WriteSet\x12\x43\n\x0ewrite_set_type\x18\x01 \x01(\x0e\x32+.aptos.transaction.v1.WriteSet.WriteSetType\x12@\n\x10script_write_set\x18\x02 \x01(\x0b\x32$.aptos.transaction.v1.ScriptWriteSetH\x00\x12@\n\x10\x64irect_write_set\x18\x03 \x01(\x0b\x32$.aptos.transaction.v1.DirectWriteSetH\x00"x\n\x0cWriteSetType\x12\x1e\n\x1aWRITE_SET_TYPE_UNSPECIFIED\x10\x00\x12#\n\x1fWRITE_SET_TYPE_SCRIPT_WRITE_SET\x10\x01\x12#\n\x1fWRITE_SET_TYPE_DIRECT_WRITE_SET\x10\x02\x42\x0b\n\twrite_set"Y\n\x0eScriptWriteSet\x12\x12\n\nexecute_as\x18\x01 \x01(\t\x12\x33\n\x06script\x18\x02 \x01(\x0b\x32#.aptos.transaction.v1.ScriptPayload"}\n\x0e\x44irectWriteSet\x12>\n\x10write_set_change\x18\x01 \x03(\x0b\x32$.aptos.transaction.v1.WriteSetChange\x12+\n\x06\x65vents\x18\x02 \x03(\x0b\x32\x1b.aptos.transaction.v1.Event"\x89\x05\n\x0eWriteSetChange\x12\x37\n\x04type\x18\x01 \x01(\x0e\x32).aptos.transaction.v1.WriteSetChange.Type\x12;\n\rdelete_module\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.DeleteModuleH\x00\x12?\n\x0f\x64\x65lete_resource\x18\x03 \x01(\x0b\x32$.aptos.transaction.v1.DeleteResourceH\x00\x12\x42\n\x11\x64\x65lete_table_item\x18\x04 \x01(\x0b\x32%.aptos.transaction.v1.DeleteTableItemH\x00\x12\x39\n\x0cwrite_module\x18\x05 \x01(\x0b\x32!.aptos.transaction.v1.WriteModuleH\x00\x12=\n\x0ewrite_resource\x18\x06 \x01(\x0b\x32#.aptos.transaction.v1.WriteResourceH\x00\x12@\n\x10write_table_item\x18\x07 \x01(\x0b\x32$.aptos.transaction.v1.WriteTableItemH\x00"\xb5\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12TYPE_DELETE_MODULE\x10\x01\x12\x18\n\x14TYPE_DELETE_RESOURCE\x10\x02\x12\x1a\n\x16TYPE_DELETE_TABLE_ITEM\x10\x03\x12\x15\n\x11TYPE_WRITE_MODULE\x10\x04\x12\x17\n\x13TYPE_WRITE_RESOURCE\x10\x05\x12\x19\n\x15TYPE_WRITE_TABLE_ITEM\x10\x06\x42\x08\n\x06\x63hange"k\n\x0c\x44\x65leteModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x32\n\x06module\x18\x03 \x01(\x0b\x32".aptos.transaction.v1.MoveModuleId"~\n\x0e\x44\x65leteResource\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x31\n\x04type\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTag\x12\x10\n\x08type_str\x18\x04 \x01(\t"{\n\x0f\x44\x65leteTableItem\x12\x16\n\x0estate_key_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\t\x12\x33\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32%.aptos.transaction.v1.DeleteTableData"0\n\x0f\x44\x65leteTableData\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x10\n\x08key_type\x18\x02 \x01(\t"n\n\x0bWriteModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x36\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32(.aptos.transaction.v1.MoveModuleBytecode"\x8b\x01\n\rWriteResource\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x16\n\x0estate_key_hash\x18\x02 \x01(\x0c\x12\x31\n\x04type\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTag\x12\x10\n\x08type_str\x18\x04 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\t"R\n\x0eWriteTableData\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x10\n\x08key_type\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\t\x12\x12\n\nvalue_type\x18\x04 \x01(\t"y\n\x0eWriteTableItem\x12\x16\n\x0estate_key_hash\x18\x01 \x01(\x0c\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\t\x12\x32\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32$.aptos.transaction.v1.WriteTableData"\x8c\x04\n\x12TransactionPayload\x12;\n\x04type\x18\x01 \x01(\x0e\x32-.aptos.transaction.v1.TransactionPayload.Type\x12L\n\x16\x65ntry_function_payload\x18\x02 \x01(\x0b\x32*.aptos.transaction.v1.EntryFunctionPayloadH\x00\x12=\n\x0escript_payload\x18\x03 \x01(\x0b\x32#.aptos.transaction.v1.ScriptPayloadH\x00\x12\x42\n\x11write_set_payload\x18\x05 \x01(\x0b\x32%.aptos.transaction.v1.WriteSetPayloadH\x00\x12\x41\n\x10multisig_payload\x18\x06 \x01(\x0b\x32%.aptos.transaction.v1.MultisigPayloadH\x00"\x93\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bTYPE_ENTRY_FUNCTION_PAYLOAD\x10\x01\x12\x17\n\x13TYPE_SCRIPT_PAYLOAD\x10\x02\x12\x1a\n\x16TYPE_WRITE_SET_PAYLOAD\x10\x04\x12\x19\n\x15TYPE_MULTISIG_PAYLOAD\x10\x05"\x04\x08\x03\x10\x03\x42\t\n\x07payloadJ\x04\x08\x04\x10\x05"\xb9\x01\n\x14\x45ntryFunctionPayload\x12\x37\n\x08\x66unction\x18\x01 \x01(\x0b\x32%.aptos.transaction.v1.EntryFunctionId\x12\x36\n\x0etype_arguments\x18\x02 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x11\n\targuments\x18\x03 \x03(\t\x12\x1d\n\x15\x65ntry_function_id_str\x18\x04 \x01(\t"W\n\x12MoveScriptBytecode\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12/\n\x03\x61\x62i\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.MoveFunction"\x92\x01\n\rScriptPayload\x12\x36\n\x04\x63ode\x18\x01 \x01(\x0b\x32(.aptos.transaction.v1.MoveScriptBytecode\x12\x36\n\x0etype_arguments\x18\x02 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12\x11\n\targuments\x18\x03 \x03(\t"\x97\x01\n\x0fMultisigPayload\x12\x18\n\x10multisig_address\x18\x01 \x01(\t\x12R\n\x13transaction_payload\x18\x02 \x01(\x0b\x32\x30.aptos.transaction.v1.MultisigTransactionPayloadH\x00\x88\x01\x01\x42\x16\n\x14_transaction_payload"\xf9\x01\n\x1aMultisigTransactionPayload\x12\x43\n\x04type\x18\x01 \x01(\x0e\x32\x35.aptos.transaction.v1.MultisigTransactionPayload.Type\x12L\n\x16\x65ntry_function_payload\x18\x02 \x01(\x0b\x32*.aptos.transaction.v1.EntryFunctionPayloadH\x00"=\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x1f\n\x1bTYPE_ENTRY_FUNCTION_PAYLOAD\x10\x01\x42\t\n\x07payload"U\n\x12MoveModuleBytecode\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12-\n\x03\x61\x62i\x18\x02 \x01(\x0b\x32 .aptos.transaction.v1.MoveModule"\xd2\x01\n\nMoveModule\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x33\n\x07\x66riends\x18\x03 \x03(\x0b\x32".aptos.transaction.v1.MoveModuleId\x12=\n\x11\x65xposed_functions\x18\x04 \x03(\x0b\x32".aptos.transaction.v1.MoveFunction\x12\x31\n\x07structs\x18\x05 \x03(\x0b\x32 .aptos.transaction.v1.MoveStruct"\x92\x03\n\x0cMoveFunction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x41\n\nvisibility\x18\x02 \x01(\x0e\x32-.aptos.transaction.v1.MoveFunction.Visibility\x12\x10\n\x08is_entry\x18\x03 \x01(\x08\x12O\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x32.aptos.transaction.v1.MoveFunctionGenericTypeParam\x12.\n\x06params\x18\x05 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType\x12.\n\x06return\x18\x06 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType"n\n\nVisibility\x12\x1a\n\x16VISIBILITY_UNSPECIFIED\x10\x00\x12\x16\n\x12VISIBILITY_PRIVATE\x10\x01\x12\x15\n\x11VISIBILITY_PUBLIC\x10\x02\x12\x15\n\x11VISIBILITY_FRIEND\x10\x03"\xfb\x01\n\nMoveStruct\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tis_native\x18\x02 \x01(\x08\x12\x10\n\x08is_event\x18\x06 \x01(\x08\x12\x34\n\tabilities\x18\x03 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility\x12M\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x30.aptos.transaction.v1.MoveStructGenericTypeParam\x12\x35\n\x06\x66ields\x18\x05 \x03(\x0b\x32%.aptos.transaction.v1.MoveStructField"h\n\x1aMoveStructGenericTypeParam\x12\x36\n\x0b\x63onstraints\x18\x01 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility\x12\x12\n\nis_phantom\x18\x02 \x01(\x08"M\n\x0fMoveStructField\x12\x0c\n\x04name\x18\x01 \x01(\t\x12,\n\x04type\x18\x02 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveType"V\n\x1cMoveFunctionGenericTypeParam\x12\x36\n\x0b\x63onstraints\x18\x01 \x03(\x0e\x32!.aptos.transaction.v1.MoveAbility"\xf8\x02\n\x08MoveType\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.aptos.transaction.v1.MoveTypes\x12\x30\n\x06vector\x18\x03 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveTypeH\x00\x12\x35\n\x06struct\x18\x04 \x01(\x0b\x32#.aptos.transaction.v1.MoveStructTagH\x00\x12"\n\x18generic_type_param_index\x18\x05 \x01(\rH\x00\x12\x41\n\treference\x18\x06 \x01(\x0b\x32,.aptos.transaction.v1.MoveType.ReferenceTypeH\x00\x12\x14\n\nunparsable\x18\x07 \x01(\tH\x00\x1aL\n\rReferenceType\x12\x0f\n\x07mutable\x18\x01 \x01(\x08\x12*\n\x02to\x18\x02 \x01(\x0b\x32\x1e.aptos.transaction.v1.MoveTypeB\t\n\x07\x63ontent"D\n\x0fWriteSetPayload\x12\x31\n\twrite_set\x18\x01 \x01(\x0b\x32\x1e.aptos.transaction.v1.WriteSet"S\n\x0f\x45ntryFunctionId\x12\x32\n\x06module\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.MoveModuleId\x12\x0c\n\x04name\x18\x02 \x01(\t"-\n\x0cMoveModuleId\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t"{\n\rMoveStructTag\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0e\n\x06module\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12;\n\x13generic_type_params\x18\x04 \x03(\x0b\x32\x1e.aptos.transaction.v1.MoveType"\x9b\x04\n\tSignature\x12\x32\n\x04type\x18\x01 \x01(\x0e\x32$.aptos.transaction.v1.Signature.Type\x12\x39\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x02 \x01(\x0b\x32&.aptos.transaction.v1.Ed25519SignatureH\x00\x12\x44\n\rmulti_ed25519\x18\x03 \x01(\x0b\x32+.aptos.transaction.v1.MultiEd25519SignatureH\x00\x12@\n\x0bmulti_agent\x18\x04 \x01(\x0b\x32).aptos.transaction.v1.MultiAgentSignatureH\x00\x12<\n\tfee_payer\x18\x05 \x01(\x0b\x32\'.aptos.transaction.v1.FeePayerSignatureH\x00\x12;\n\rsingle_sender\x18\x07 \x01(\x0b\x32".aptos.transaction.v1.SingleSenderH\x00"\x8e\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x16\n\x12TYPE_MULTI_ED25519\x10\x02\x12\x14\n\x10TYPE_MULTI_AGENT\x10\x03\x12\x12\n\x0eTYPE_FEE_PAYER\x10\x04\x12\x16\n\x12TYPE_SINGLE_SENDER\x10\x06"\x04\x08\x05\x10\x05\x42\x0b\n\tsignature"9\n\x10\x45\x64\x32\x35\x35\x31\x39Signature\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c"o\n\x15MultiEd25519Signature\x12\x13\n\x0bpublic_keys\x18\x01 \x03(\x0c\x12\x12\n\nsignatures\x18\x02 \x03(\x0c\x12\x11\n\tthreshold\x18\x03 \x01(\r\x12\x1a\n\x12public_key_indices\x18\x04 \x03(\r"\xb4\x01\n\x13MultiAgentSignature\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12"\n\x1asecondary_signer_addresses\x18\x02 \x03(\t\x12\x41\n\x11secondary_signers\x18\x03 \x03(\x0b\x32&.aptos.transaction.v1.AccountSignature"\x8f\x02\n\x11\x46\x65\x65PayerSignature\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12"\n\x1asecondary_signer_addresses\x18\x02 \x03(\t\x12\x41\n\x11secondary_signers\x18\x03 \x03(\x0b\x32&.aptos.transaction.v1.AccountSignature\x12\x19\n\x11\x66\x65\x65_payer_address\x18\x04 \x01(\t\x12@\n\x10\x66\x65\x65_payer_signer\x18\x05 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature"\xec\x01\n\x0c\x41nyPublicKey\x12\x35\n\x04type\x18\x01 \x01(\x0e\x32\'.aptos.transaction.v1.AnyPublicKey.Type\x12\x12\n\npublic_key\x18\x02 \x01(\x0c"\x90\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x18\n\x14TYPE_SECP256K1_ECDSA\x10\x02\x12\x18\n\x14TYPE_SECP256R1_ECDSA\x10\x03\x12\x10\n\x0cTYPE_KEYLESS\x10\x04\x12\x1a\n\x16TYPE_FEDERATED_KEYLESS\x10\x05"\xb9\x03\n\x0c\x41nySignature\x12\x35\n\x04type\x18\x01 \x01(\x0e\x32\'.aptos.transaction.v1.AnySignature.Type\x12\x15\n\tsignature\x18\x02 \x01(\x0c\x42\x02\x18\x01\x12\x30\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x03 \x01(\x0b\x32\x1d.aptos.transaction.v1.Ed25519H\x00\x12?\n\x0fsecp256k1_ecdsa\x18\x04 \x01(\x0b\x32$.aptos.transaction.v1.Secp256k1EcdsaH\x00\x12\x32\n\x08webauthn\x18\x05 \x01(\x0b\x32\x1e.aptos.transaction.v1.WebAuthnH\x00\x12\x30\n\x07keyless\x18\x06 \x01(\x0b\x32\x1d.aptos.transaction.v1.KeylessH\x00"m\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x18\n\x14TYPE_SECP256K1_ECDSA\x10\x02\x12\x11\n\rTYPE_WEBAUTHN\x10\x03\x12\x10\n\x0cTYPE_KEYLESS\x10\x04\x42\x13\n\x11signature_variant"\x1c\n\x07\x45\x64\x32\x35\x35\x31\x39\x12\x11\n\tsignature\x18\x01 \x01(\x0c"#\n\x0eSecp256k1Ecdsa\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x1d\n\x08WebAuthn\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x1c\n\x07Keyless\x12\x11\n\tsignature\x18\x01 \x01(\x0c"\x83\x01\n\x12SingleKeySignature\x12\x36\n\npublic_key\x18\x01 \x01(\x0b\x32".aptos.transaction.v1.AnyPublicKey\x12\x35\n\tsignature\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.AnySignature"X\n\x10IndexedSignature\x12\r\n\x05index\x18\x01 \x01(\r\x12\x35\n\tsignature\x18\x02 \x01(\x0b\x32".aptos.transaction.v1.AnySignature"\xa5\x01\n\x11MultiKeySignature\x12\x37\n\x0bpublic_keys\x18\x01 \x03(\x0b\x32".aptos.transaction.v1.AnyPublicKey\x12:\n\nsignatures\x18\x02 \x03(\x0b\x32&.aptos.transaction.v1.IndexedSignature\x12\x1b\n\x13signatures_required\x18\x03 \x01(\r"@\n\x14\x41\x62stractionSignature\x12\x15\n\rfunction_info\x18\x01 \x01(\t\x12\x11\n\tsignature\x18\x02 \x01(\x0c"F\n\x0cSingleSender\x12\x36\n\x06sender\x18\x01 \x01(\x0b\x32&.aptos.transaction.v1.AccountSignature"\xbe\x04\n\x10\x41\x63\x63ountSignature\x12\x39\n\x04type\x18\x01 \x01(\x0e\x32+.aptos.transaction.v1.AccountSignature.Type\x12\x39\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x02 \x01(\x0b\x32&.aptos.transaction.v1.Ed25519SignatureH\x00\x12\x44\n\rmulti_ed25519\x18\x03 \x01(\x0b\x32+.aptos.transaction.v1.MultiEd25519SignatureH\x00\x12H\n\x14single_key_signature\x18\x05 \x01(\x0b\x32(.aptos.transaction.v1.SingleKeySignatureH\x00\x12\x46\n\x13multi_key_signature\x18\x06 \x01(\x0b\x32\'.aptos.transaction.v1.MultiKeySignatureH\x00\x12\x41\n\x0b\x61\x62straction\x18\x07 \x01(\x0b\x32*.aptos.transaction.v1.AbstractionSignatureH\x00"\x8b\x01\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cTYPE_ED25519\x10\x01\x12\x16\n\x12TYPE_MULTI_ED25519\x10\x02\x12\x13\n\x0fTYPE_SINGLE_KEY\x10\x04\x12\x12\n\x0eTYPE_MULTI_KEY\x10\x05\x12\x14\n\x10TYPE_ABSTRACTION\x10\x06"\x04\x08\x03\x10\x03\x42\x0b\n\tsignature"\xb1\x01\n\x13TransactionSizeInfo\x12\x19\n\x11transaction_bytes\x18\x01 \x01(\r\x12<\n\x0f\x65vent_size_info\x18\x02 \x03(\x0b\x32#.aptos.transaction.v1.EventSizeInfo\x12\x41\n\x12write_op_size_info\x18\x03 \x03(\x0b\x32%.aptos.transaction.v1.WriteOpSizeInfo"<\n\rEventSizeInfo\x12\x16\n\x0etype_tag_bytes\x18\x01 \x01(\r\x12\x13\n\x0btotal_bytes\x18\x02 \x01(\r"9\n\x0fWriteOpSizeInfo\x12\x11\n\tkey_bytes\x18\x01 \x01(\r\x12\x13\n\x0bvalue_bytes\x18\x02 \x01(\r*\xea\x02\n\tMoveTypes\x12\x1a\n\x16MOVE_TYPES_UNSPECIFIED\x10\x00\x12\x13\n\x0fMOVE_TYPES_BOOL\x10\x01\x12\x11\n\rMOVE_TYPES_U8\x10\x02\x12\x12\n\x0eMOVE_TYPES_U16\x10\x0c\x12\x12\n\x0eMOVE_TYPES_U32\x10\r\x12\x12\n\x0eMOVE_TYPES_U64\x10\x03\x12\x13\n\x0fMOVE_TYPES_U128\x10\x04\x12\x13\n\x0fMOVE_TYPES_U256\x10\x0e\x12\x16\n\x12MOVE_TYPES_ADDRESS\x10\x05\x12\x15\n\x11MOVE_TYPES_SIGNER\x10\x06\x12\x15\n\x11MOVE_TYPES_VECTOR\x10\x07\x12\x15\n\x11MOVE_TYPES_STRUCT\x10\x08\x12!\n\x1dMOVE_TYPES_GENERIC_TYPE_PARAM\x10\t\x12\x18\n\x14MOVE_TYPES_REFERENCE\x10\n\x12\x19\n\x15MOVE_TYPES_UNPARSABLE\x10\x0b*\x87\x01\n\x0bMoveAbility\x12\x1c\n\x18MOVE_ABILITY_UNSPECIFIED\x10\x00\x12\x15\n\x11MOVE_ABILITY_COPY\x10\x01\x12\x15\n\x11MOVE_ABILITY_DROP\x10\x02\x12\x16\n\x12MOVE_ABILITY_STORE\x10\x03\x12\x14\n\x10MOVE_ABILITY_KEY\x10\x04\x62\x06proto3' ) _globals = globals() @@ -57,10 +57,10 @@ ]._serialized_options = b"0\001" _ANYSIGNATURE.fields_by_name["signature"]._options = None _ANYSIGNATURE.fields_by_name["signature"]._serialized_options = b"\030\001" - _globals["_MOVETYPES"]._serialized_start = 12843 - _globals["_MOVETYPES"]._serialized_end = 13205 - _globals["_MOVEABILITY"]._serialized_start = 13208 - _globals["_MOVEABILITY"]._serialized_end = 13343 + _globals["_MOVETYPES"]._serialized_start = 12999 + _globals["_MOVETYPES"]._serialized_end = 13361 + _globals["_MOVEABILITY"]._serialized_start = 13364 + _globals["_MOVEABILITY"]._serialized_end = 13499 _globals["_BLOCK"]._serialized_start = 103 _globals["_BLOCK"]._serialized_end = 257 _globals["_TRANSACTION"]._serialized_start = 260 @@ -237,16 +237,18 @@ _globals["_INDEXEDSIGNATURE"]._serialized_end = 11812 _globals["_MULTIKEYSIGNATURE"]._serialized_start = 11815 _globals["_MULTIKEYSIGNATURE"]._serialized_end = 11980 - _globals["_SINGLESENDER"]._serialized_start = 11982 - _globals["_SINGLESENDER"]._serialized_end = 12052 - _globals["_ACCOUNTSIGNATURE"]._serialized_start = 12055 - _globals["_ACCOUNTSIGNATURE"]._serialized_end = 12539 - _globals["_ACCOUNTSIGNATURE_TYPE"]._serialized_start = 12409 - _globals["_ACCOUNTSIGNATURE_TYPE"]._serialized_end = 12526 - _globals["_TRANSACTIONSIZEINFO"]._serialized_start = 12542 - _globals["_TRANSACTIONSIZEINFO"]._serialized_end = 12719 - _globals["_EVENTSIZEINFO"]._serialized_start = 12721 - _globals["_EVENTSIZEINFO"]._serialized_end = 12781 - _globals["_WRITEOPSIZEINFO"]._serialized_start = 12783 - _globals["_WRITEOPSIZEINFO"]._serialized_end = 12840 + _globals["_ABSTRACTIONSIGNATURE"]._serialized_start = 11982 + _globals["_ABSTRACTIONSIGNATURE"]._serialized_end = 12046 + _globals["_SINGLESENDER"]._serialized_start = 12048 + _globals["_SINGLESENDER"]._serialized_end = 12118 + _globals["_ACCOUNTSIGNATURE"]._serialized_start = 12121 + _globals["_ACCOUNTSIGNATURE"]._serialized_end = 12695 + _globals["_ACCOUNTSIGNATURE_TYPE"]._serialized_start = 12543 + _globals["_ACCOUNTSIGNATURE_TYPE"]._serialized_end = 12682 + _globals["_TRANSACTIONSIZEINFO"]._serialized_start = 12698 + _globals["_TRANSACTIONSIZEINFO"]._serialized_end = 12875 + _globals["_EVENTSIZEINFO"]._serialized_start = 12877 + _globals["_EVENTSIZEINFO"]._serialized_end = 12937 + _globals["_WRITEOPSIZEINFO"]._serialized_start = 12939 + _globals["_WRITEOPSIZEINFO"]._serialized_end = 12996 # @@protoc_insertion_point(module_scope) diff --git a/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.pyi b/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.pyi index 54935f9e289d1..1367b643a9957 100644 --- a/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.pyi +++ b/protos/python/aptos_protos/aptos/transaction/v1/transaction_pb2.pyi @@ -1358,6 +1358,16 @@ class MultiKeySignature(_message.Message): signatures_required: _Optional[int] = ..., ) -> None: ... +class AbstractionSignature(_message.Message): + __slots__ = ["function_info", "signature"] + FUNCTION_INFO_FIELD_NUMBER: _ClassVar[int] + SIGNATURE_FIELD_NUMBER: _ClassVar[int] + function_info: str + signature: bytes + def __init__( + self, function_info: _Optional[str] = ..., signature: _Optional[bytes] = ... + ) -> None: ... + class SingleSender(_message.Message): __slots__ = ["sender"] SENDER_FIELD_NUMBER: _ClassVar[int] @@ -1373,6 +1383,7 @@ class AccountSignature(_message.Message): "multi_ed25519", "single_key_signature", "multi_key_signature", + "abstraction", ] class Type(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): @@ -1382,21 +1393,25 @@ class AccountSignature(_message.Message): TYPE_MULTI_ED25519: _ClassVar[AccountSignature.Type] TYPE_SINGLE_KEY: _ClassVar[AccountSignature.Type] TYPE_MULTI_KEY: _ClassVar[AccountSignature.Type] + TYPE_ABSTRACTION: _ClassVar[AccountSignature.Type] TYPE_UNSPECIFIED: AccountSignature.Type TYPE_ED25519: AccountSignature.Type TYPE_MULTI_ED25519: AccountSignature.Type TYPE_SINGLE_KEY: AccountSignature.Type TYPE_MULTI_KEY: AccountSignature.Type + TYPE_ABSTRACTION: AccountSignature.Type TYPE_FIELD_NUMBER: _ClassVar[int] ED25519_FIELD_NUMBER: _ClassVar[int] MULTI_ED25519_FIELD_NUMBER: _ClassVar[int] SINGLE_KEY_SIGNATURE_FIELD_NUMBER: _ClassVar[int] MULTI_KEY_SIGNATURE_FIELD_NUMBER: _ClassVar[int] + ABSTRACTION_FIELD_NUMBER: _ClassVar[int] type: AccountSignature.Type ed25519: Ed25519Signature multi_ed25519: MultiEd25519Signature single_key_signature: SingleKeySignature multi_key_signature: MultiKeySignature + abstraction: AbstractionSignature def __init__( self, type: _Optional[_Union[AccountSignature.Type, str]] = ..., @@ -1404,6 +1419,7 @@ class AccountSignature(_message.Message): multi_ed25519: _Optional[_Union[MultiEd25519Signature, _Mapping]] = ..., single_key_signature: _Optional[_Union[SingleKeySignature, _Mapping]] = ..., multi_key_signature: _Optional[_Union[MultiKeySignature, _Mapping]] = ..., + abstraction: _Optional[_Union[AbstractionSignature, _Mapping]] = ..., ) -> None: ... class TransactionSizeInfo(_message.Message): diff --git a/protos/rust/src/pb/aptos.bigquery_schema.transaction.v1.rs b/protos/rust/src/pb/aptos.bigquery_schema.transaction.v1.rs index 9045273d87043..74a4ad5408735 100644 --- a/protos/rust/src/pb/aptos.bigquery_schema.transaction.v1.rs +++ b/protos/rust/src/pb/aptos.bigquery_schema.transaction.v1.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // @generated +// This file is @generated by prost-build. /// Transaction is a simplified representation for the transaction /// happened on the chain. Mainly built for streaming into BigQuery. /// It matches with the structure defined for the transaction in Indexer. diff --git a/protos/rust/src/pb/aptos.bigquery_schema.transaction.v1.serde.rs b/protos/rust/src/pb/aptos.bigquery_schema.transaction.v1.serde.rs index 790f4c7101117..a4261dde1fdd7 100644 --- a/protos/rust/src/pb/aptos.bigquery_schema.transaction.v1.serde.rs +++ b/protos/rust/src/pb/aptos.bigquery_schema.transaction.v1.serde.rs @@ -17,7 +17,9 @@ impl serde::Serialize for Transaction { len += 1; } let mut struct_ser = serializer.serialize_struct("aptos.bigquery_schema.transaction.v1.Transaction", len)?; + #[allow(clippy::needless_borrow)] struct_ser.serialize_field("version", ToString::to_string(&self.version).as_str())?; + #[allow(clippy::needless_borrow)] struct_ser.serialize_field("blockHeight", ToString::to_string(&self.block_height).as_str())?; struct_ser.serialize_field("hash", &self.hash)?; struct_ser.serialize_field("type", &self.r#type)?; @@ -29,13 +31,18 @@ impl serde::Serialize for Transaction { if let Some(v) = self.state_checkpoint_hash.as_ref() { struct_ser.serialize_field("stateCheckpointHash", v)?; } + #[allow(clippy::needless_borrow)] struct_ser.serialize_field("gasUsed", ToString::to_string(&self.gas_used).as_str())?; struct_ser.serialize_field("success", &self.success)?; struct_ser.serialize_field("vmStatus", &self.vm_status)?; struct_ser.serialize_field("accumulatorRootHash", &self.accumulator_root_hash)?; + #[allow(clippy::needless_borrow)] struct_ser.serialize_field("numEvents", ToString::to_string(&self.num_events).as_str())?; + #[allow(clippy::needless_borrow)] struct_ser.serialize_field("numWriteSetChanges", ToString::to_string(&self.num_write_set_changes).as_str())?; + #[allow(clippy::needless_borrow)] struct_ser.serialize_field("epoch", ToString::to_string(&self.epoch).as_str())?; + #[allow(clippy::needless_borrow)] struct_ser.serialize_field("insertedAt", ToString::to_string(&self.inserted_at).as_str())?; struct_ser.end() } @@ -145,7 +152,7 @@ impl<'de> serde::Deserialize<'de> for Transaction { formatter.write_str("struct aptos.bigquery_schema.transaction.v1.Transaction") } - fn visit_map(self, mut map: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -165,14 +172,14 @@ impl<'de> serde::Deserialize<'de> for Transaction { let mut num_write_set_changes__ = None; let mut epoch__ = None; let mut inserted_at__ = None; - while let Some(k) = map.next_key()? { + while let Some(k) = map_.next_key()? { match k { GeneratedField::Version => { if version__.is_some() { return Err(serde::de::Error::duplicate_field("version")); } version__ = - Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } GeneratedField::BlockHeight => { @@ -180,77 +187,77 @@ impl<'de> serde::Deserialize<'de> for Transaction { return Err(serde::de::Error::duplicate_field("blockHeight")); } block_height__ = - Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } GeneratedField::Hash => { if hash__.is_some() { return Err(serde::de::Error::duplicate_field("hash")); } - hash__ = Some(map.next_value()?); + hash__ = Some(map_.next_value()?); } GeneratedField::Type => { if r#type__.is_some() { return Err(serde::de::Error::duplicate_field("type")); } - r#type__ = Some(map.next_value()?); + r#type__ = Some(map_.next_value()?); } GeneratedField::Payload => { if payload__.is_some() { return Err(serde::de::Error::duplicate_field("payload")); } - payload__ = map.next_value()?; + payload__ = map_.next_value()?; } GeneratedField::StateChangeHash => { if state_change_hash__.is_some() { return Err(serde::de::Error::duplicate_field("stateChangeHash")); } - state_change_hash__ = Some(map.next_value()?); + state_change_hash__ = Some(map_.next_value()?); } GeneratedField::EventRootHash => { if event_root_hash__.is_some() { return Err(serde::de::Error::duplicate_field("eventRootHash")); } - event_root_hash__ = Some(map.next_value()?); + event_root_hash__ = Some(map_.next_value()?); } GeneratedField::StateCheckpointHash => { if state_checkpoint_hash__.is_some() { return Err(serde::de::Error::duplicate_field("stateCheckpointHash")); } - state_checkpoint_hash__ = map.next_value()?; + state_checkpoint_hash__ = map_.next_value()?; } GeneratedField::GasUsed => { if gas_used__.is_some() { return Err(serde::de::Error::duplicate_field("gasUsed")); } gas_used__ = - Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } GeneratedField::Success => { if success__.is_some() { return Err(serde::de::Error::duplicate_field("success")); } - success__ = Some(map.next_value()?); + success__ = Some(map_.next_value()?); } GeneratedField::VmStatus => { if vm_status__.is_some() { return Err(serde::de::Error::duplicate_field("vmStatus")); } - vm_status__ = Some(map.next_value()?); + vm_status__ = Some(map_.next_value()?); } GeneratedField::AccumulatorRootHash => { if accumulator_root_hash__.is_some() { return Err(serde::de::Error::duplicate_field("accumulatorRootHash")); } - accumulator_root_hash__ = Some(map.next_value()?); + accumulator_root_hash__ = Some(map_.next_value()?); } GeneratedField::NumEvents => { if num_events__.is_some() { return Err(serde::de::Error::duplicate_field("numEvents")); } num_events__ = - Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } GeneratedField::NumWriteSetChanges => { @@ -258,7 +265,7 @@ impl<'de> serde::Deserialize<'de> for Transaction { return Err(serde::de::Error::duplicate_field("numWriteSetChanges")); } num_write_set_changes__ = - Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } GeneratedField::Epoch => { @@ -266,7 +273,7 @@ impl<'de> serde::Deserialize<'de> for Transaction { return Err(serde::de::Error::duplicate_field("epoch")); } epoch__ = - Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } GeneratedField::InsertedAt => { @@ -274,7 +281,7 @@ impl<'de> serde::Deserialize<'de> for Transaction { return Err(serde::de::Error::duplicate_field("insertedAt")); } inserted_at__ = - Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } } diff --git a/protos/rust/src/pb/aptos.indexer.v1.rs b/protos/rust/src/pb/aptos.indexer.v1.rs index fa19bc8c41dfa..f8bba237f4fdd 100644 --- a/protos/rust/src/pb/aptos.indexer.v1.rs +++ b/protos/rust/src/pb/aptos.indexer.v1.rs @@ -4,6 +4,7 @@ // @generated // This file is @generated by prost-build. /// This is for storage only. +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TransactionsInStorage { /// Required; transactions data. @@ -13,6 +14,7 @@ pub struct TransactionsInStorage { #[prost(uint64, optional, tag="2")] pub starting_version: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetTransactionsRequest { /// Required; start version of current stream. @@ -28,6 +30,7 @@ pub struct GetTransactionsRequest { pub batch_size: ::core::option::Option, } /// TransactionsResponse is a batch of transactions. +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TransactionsResponse { /// Required; transactions data. @@ -37,6 +40,7 @@ pub struct TransactionsResponse { #[prost(uint64, optional, tag="2")] pub chain_id: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct StreamProgressSampleProto { #[prost(message, optional, tag="1")] @@ -46,11 +50,13 @@ pub struct StreamProgressSampleProto { #[prost(uint64, tag="3")] pub size_bytes: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StreamProgress { #[prost(message, repeated, tag="1")] pub samples: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ActiveStream { #[prost(string, optional, tag="1")] @@ -64,11 +70,13 @@ pub struct ActiveStream { #[prost(message, optional, tag="5")] pub progress: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StreamInfo { #[prost(message, repeated, tag="1")] pub active_streams: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct LiveDataServiceInfo { #[prost(uint64, optional, tag="1")] @@ -83,6 +91,7 @@ pub struct LiveDataServiceInfo { #[prost(uint64, optional, tag="5")] pub min_servable_version: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct HistoricalDataServiceInfo { #[prost(uint64, optional, tag="1")] @@ -94,6 +103,7 @@ pub struct HistoricalDataServiceInfo { #[prost(message, optional, tag="4")] pub stream_info: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct FullnodeInfo { #[prost(uint64, optional, tag="1")] @@ -103,6 +113,7 @@ pub struct FullnodeInfo { #[prost(uint64, optional, tag="3")] pub known_latest_version: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GrpcManagerInfo { #[prost(uint64, optional, tag="1")] @@ -114,6 +125,7 @@ pub struct GrpcManagerInfo { #[prost(string, optional, tag="4")] pub master_address: ::core::option::Option<::prost::alloc::string::String>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ServiceInfo { #[prost(string, optional, tag="1")] @@ -123,7 +135,8 @@ pub struct ServiceInfo { } /// Nested message and enum types in `ServiceInfo`. pub mod service_info { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Info { #[prost(message, tag="2")] LiveDataServiceInfo(super::LiveDataServiceInfo), @@ -135,16 +148,19 @@ pub mod service_info { GrpcManagerInfo(super::GrpcManagerInfo), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct HeartbeatRequest { #[prost(message, optional, tag="1")] pub service_info: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct HeartbeatResponse { #[prost(uint64, optional, tag="1")] pub known_latest_version: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct PingDataServiceRequest { #[prost(uint64, optional, tag="1")] @@ -153,6 +169,7 @@ pub struct PingDataServiceRequest { #[prost(bool, tag="2")] pub ping_live_data_service: bool, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PingDataServiceResponse { #[prost(oneof="ping_data_service_response::Info", tags="1, 2")] @@ -160,7 +177,8 @@ pub struct PingDataServiceResponse { } /// Nested message and enum types in `PingDataServiceResponse`. pub mod ping_data_service_response { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Info { #[prost(message, tag="1")] LiveDataServiceInfo(super::LiveDataServiceInfo), @@ -168,11 +186,13 @@ pub mod ping_data_service_response { HistoricalDataServiceInfo(super::HistoricalDataServiceInfo), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetDataServiceForRequestRequest { #[prost(message, optional, tag="1")] pub user_request: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetDataServiceForRequestResponse { #[prost(string, tag="1")] diff --git a/protos/rust/src/pb/aptos.indexer.v1.tonic.rs b/protos/rust/src/pb/aptos.indexer.v1.tonic.rs index 4e0c6ea804053..7c1140ba61e57 100644 --- a/protos/rust/src/pb/aptos.indexer.v1.tonic.rs +++ b/protos/rust/src/pb/aptos.indexer.v1.tonic.rs @@ -4,13 +4,7 @@ // @generated /// Generated client implementations. pub mod raw_data_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -33,8 +27,8 @@ pub mod raw_data_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -59,7 +53,7 @@ pub mod raw_data_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { RawDataClient::new(InterceptedService::new(inner, interceptor)) } @@ -107,7 +101,8 @@ pub mod raw_data_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -124,22 +119,16 @@ pub mod raw_data_client { } /// Generated server implementations. pub mod raw_data_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with RawDataServer. #[async_trait] - pub trait RawData: std::marker::Send + std::marker::Sync + 'static { + pub trait RawData: Send + Sync + 'static { /// Server streaming response type for the GetTransactions method. type GetTransactionsStream: tonic::codegen::tokio_stream::Stream< Item = std::result::Result, > - + std::marker::Send + + Send + 'static; /** Get transactions batch without any filtering from starting version and end if transaction count is present. */ @@ -153,14 +142,14 @@ pub mod raw_data_server { } /// #[derive(Debug)] - pub struct RawDataServer { + pub struct RawDataServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl RawDataServer { + impl RawDataServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -214,8 +203,8 @@ pub mod raw_data_server { impl tonic::codegen::Service> for RawDataServer where T: RawData, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -277,25 +266,23 @@ pub mod raw_data_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for RawDataServer { + impl Clone for RawDataServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -307,21 +294,13 @@ pub mod raw_data_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.indexer.v1.RawData"; - impl tonic::server::NamedService for RawDataServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService for RawDataServer { + const NAME: &'static str = "aptos.indexer.v1.RawData"; } } /// Generated client implementations. pub mod grpc_manager_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -344,8 +323,8 @@ pub mod grpc_manager_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -370,7 +349,7 @@ pub mod grpc_manager_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { GrpcManagerClient::new(InterceptedService::new(inner, interceptor)) } @@ -417,7 +396,8 @@ pub mod grpc_manager_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -442,7 +422,8 @@ pub mod grpc_manager_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -469,7 +450,8 @@ pub mod grpc_manager_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -491,17 +473,11 @@ pub mod grpc_manager_client { } /// Generated server implementations. pub mod grpc_manager_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with GrpcManagerServer. #[async_trait] - pub trait GrpcManager: std::marker::Send + std::marker::Sync + 'static { + pub trait GrpcManager: Send + Sync + 'static { /// async fn heartbeat( &self, @@ -529,14 +505,14 @@ pub mod grpc_manager_server { } /// #[derive(Debug)] - pub struct GrpcManagerServer { + pub struct GrpcManagerServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl GrpcManagerServer { + impl GrpcManagerServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -590,8 +566,8 @@ pub mod grpc_manager_server { impl tonic::codegen::Service> for GrpcManagerServer where T: GrpcManager, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -747,25 +723,23 @@ pub mod grpc_manager_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for GrpcManagerServer { + impl Clone for GrpcManagerServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -777,21 +751,13 @@ pub mod grpc_manager_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.indexer.v1.GrpcManager"; - impl tonic::server::NamedService for GrpcManagerServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService for GrpcManagerServer { + const NAME: &'static str = "aptos.indexer.v1.GrpcManager"; } } /// Generated client implementations. pub mod data_service_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -814,8 +780,8 @@ pub mod data_service_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -840,7 +806,7 @@ pub mod data_service_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { DataServiceClient::new(InterceptedService::new(inner, interceptor)) } @@ -887,7 +853,8 @@ pub mod data_service_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -912,7 +879,8 @@ pub mod data_service_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -931,17 +899,11 @@ pub mod data_service_client { } /// Generated server implementations. pub mod data_service_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with DataServiceServer. #[async_trait] - pub trait DataService: std::marker::Send + std::marker::Sync + 'static { + pub trait DataService: Send + Sync + 'static { /// async fn ping( &self, @@ -954,7 +916,7 @@ pub mod data_service_server { type GetTransactionsStream: tonic::codegen::tokio_stream::Stream< Item = std::result::Result, > - + std::marker::Send + + Send + 'static; /// async fn get_transactions( @@ -967,14 +929,14 @@ pub mod data_service_server { } /// #[derive(Debug)] - pub struct DataServiceServer { + pub struct DataServiceServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl DataServiceServer { + impl DataServiceServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -1028,8 +990,8 @@ pub mod data_service_server { impl tonic::codegen::Service> for DataServiceServer where T: DataService, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -1136,25 +1098,23 @@ pub mod data_service_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for DataServiceServer { + impl Clone for DataServiceServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -1166,9 +1126,7 @@ pub mod data_service_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.indexer.v1.DataService"; - impl tonic::server::NamedService for DataServiceServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService for DataServiceServer { + const NAME: &'static str = "aptos.indexer.v1.DataService"; } } diff --git a/protos/rust/src/pb/aptos.internal.fullnode.v1.rs b/protos/rust/src/pb/aptos.internal.fullnode.v1.rs index f5547af9719d0..90c0d9208ae5f 100644 --- a/protos/rust/src/pb/aptos.internal.fullnode.v1.rs +++ b/protos/rust/src/pb/aptos.internal.fullnode.v1.rs @@ -10,11 +10,13 @@ // TransactionOutput data(size n) // StreamStatus: BATCH_END with version x + (k + 1) * n - 1 +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TransactionsOutput { #[prost(message, repeated, tag="1")] pub transactions: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct StreamStatus { #[prost(enumeration="stream_status::StatusType", tag="1")] @@ -44,9 +46,9 @@ pub mod stream_status { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "STATUS_TYPE_UNSPECIFIED", - Self::Init => "STATUS_TYPE_INIT", - Self::BatchEnd => "STATUS_TYPE_BATCH_END", + StatusType::Unspecified => "STATUS_TYPE_UNSPECIFIED", + StatusType::Init => "STATUS_TYPE_INIT", + StatusType::BatchEnd => "STATUS_TYPE_BATCH_END", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -60,6 +62,7 @@ pub mod stream_status { } } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct GetTransactionsFromNodeRequest { /// Required; start version of current stream. @@ -71,6 +74,7 @@ pub struct GetTransactionsFromNodeRequest { #[prost(uint64, optional, tag="2")] pub transactions_count: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TransactionsFromNodeResponse { /// Making sure that all the responses include a chain id @@ -81,7 +85,8 @@ pub struct TransactionsFromNodeResponse { } /// Nested message and enum types in `TransactionsFromNodeResponse`. pub mod transactions_from_node_response { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Response { #[prost(message, tag="1")] Status(super::StreamStatus), @@ -89,9 +94,11 @@ pub mod transactions_from_node_response { Data(super::TransactionsOutput), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct PingFullnodeRequest { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct PingFullnodeResponse { #[prost(message, optional, tag="1")] diff --git a/protos/rust/src/pb/aptos.internal.fullnode.v1.tonic.rs b/protos/rust/src/pb/aptos.internal.fullnode.v1.tonic.rs index f8cf73cd62ea8..3879fd94dcefd 100644 --- a/protos/rust/src/pb/aptos.internal.fullnode.v1.tonic.rs +++ b/protos/rust/src/pb/aptos.internal.fullnode.v1.tonic.rs @@ -4,13 +4,7 @@ // @generated /// Generated client implementations. pub mod fullnode_data_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -33,8 +27,8 @@ pub mod fullnode_data_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -59,7 +53,7 @@ pub mod fullnode_data_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { FullnodeDataClient::new(InterceptedService::new(inner, interceptor)) } @@ -106,7 +100,8 @@ pub mod fullnode_data_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -135,7 +130,8 @@ pub mod fullnode_data_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -157,17 +153,11 @@ pub mod fullnode_data_client { } /// Generated server implementations. pub mod fullnode_data_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with FullnodeDataServer. #[async_trait] - pub trait FullnodeData: std::marker::Send + std::marker::Sync + 'static { + pub trait FullnodeData: Send + Sync + 'static { /// async fn ping( &self, @@ -183,7 +173,7 @@ pub mod fullnode_data_server { tonic::Status, >, > - + std::marker::Send + + Send + 'static; /// async fn get_transactions_from_node( @@ -196,14 +186,14 @@ pub mod fullnode_data_server { } /// #[derive(Debug)] - pub struct FullnodeDataServer { + pub struct FullnodeDataServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl FullnodeDataServer { + impl FullnodeDataServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -257,8 +247,8 @@ pub mod fullnode_data_server { impl tonic::codegen::Service> for FullnodeDataServer where T: FullnodeData, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -371,25 +361,23 @@ pub mod fullnode_data_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for FullnodeDataServer { + impl Clone for FullnodeDataServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -401,9 +389,7 @@ pub mod fullnode_data_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.internal.fullnode.v1.FullnodeData"; - impl tonic::server::NamedService for FullnodeDataServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService for FullnodeDataServer { + const NAME: &'static str = "aptos.internal.fullnode.v1.FullnodeData"; } } diff --git a/protos/rust/src/pb/aptos.remote_executor.v1.rs b/protos/rust/src/pb/aptos.remote_executor.v1.rs index 29daad3efd968..b84e6e1e68f50 100644 --- a/protos/rust/src/pb/aptos.remote_executor.v1.rs +++ b/protos/rust/src/pb/aptos.remote_executor.v1.rs @@ -3,6 +3,7 @@ // @generated // This file is @generated by prost-build. +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct NetworkMessage { #[prost(bytes="vec", tag="1")] @@ -10,6 +11,7 @@ pub struct NetworkMessage { #[prost(string, tag="2")] pub message_type: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct Empty { } diff --git a/protos/rust/src/pb/aptos.remote_executor.v1.tonic.rs b/protos/rust/src/pb/aptos.remote_executor.v1.tonic.rs index 85f08bf9e8caa..bab5b94b15a56 100644 --- a/protos/rust/src/pb/aptos.remote_executor.v1.tonic.rs +++ b/protos/rust/src/pb/aptos.remote_executor.v1.tonic.rs @@ -4,13 +4,7 @@ // @generated /// Generated client implementations. pub mod network_message_service_client { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; use tonic::codegen::http::Uri; /// @@ -33,8 +27,8 @@ pub mod network_message_service_client { where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + std::marker::Send + 'static, - ::Error: Into + std::marker::Send, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -59,7 +53,7 @@ pub mod network_message_service_client { >, , - >>::Error: Into + std::marker::Send + std::marker::Sync, + >>::Error: Into + Send + Sync, { NetworkMessageServiceClient::new(InterceptedService::new(inner, interceptor)) } @@ -103,7 +97,8 @@ pub mod network_message_service_client { .ready() .await .map_err(|e| { - tonic::Status::unknown( + tonic::Status::new( + tonic::Code::Unknown, format!("Service was not ready: {}", e.into()), ) })?; @@ -125,17 +120,11 @@ pub mod network_message_service_client { } /// Generated server implementations. pub mod network_message_service_server { - #![allow( - unused_variables, - dead_code, - missing_docs, - clippy::wildcard_imports, - clippy::let_unit_value, - )] + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with NetworkMessageServiceServer. #[async_trait] - pub trait NetworkMessageService: std::marker::Send + std::marker::Sync + 'static { + pub trait NetworkMessageService: Send + Sync + 'static { /// async fn simple_msg_exchange( &self, @@ -144,14 +133,14 @@ pub mod network_message_service_server { } /// #[derive(Debug)] - pub struct NetworkMessageServiceServer { + pub struct NetworkMessageServiceServer { inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, max_decoding_message_size: Option, max_encoding_message_size: Option, } - impl NetworkMessageServiceServer { + impl NetworkMessageServiceServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -206,8 +195,8 @@ pub mod network_message_service_server { for NetworkMessageServiceServer where T: NetworkMessageService, - B: Body + std::marker::Send + 'static, - B::Error: Into + std::marker::Send + 'static, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -271,25 +260,23 @@ pub mod network_message_service_server { } _ => { Box::pin(async move { - let mut response = http::Response::new(empty_body()); - let headers = response.headers_mut(); - headers - .insert( - tonic::Status::GRPC_STATUS, - (tonic::Code::Unimplemented as i32).into(), - ); - headers - .insert( - http::header::CONTENT_TYPE, - tonic::metadata::GRPC_CONTENT_TYPE, - ); - Ok(response) + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", tonic::Code::Unimplemented as i32) + .header( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ) + .body(empty_body()) + .unwrap(), + ) }) } } } } - impl Clone for NetworkMessageServiceServer { + impl Clone for NetworkMessageServiceServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -301,9 +288,8 @@ pub mod network_message_service_server { } } } - /// Generated gRPC service name - pub const SERVICE_NAME: &str = "aptos.remote_executor.v1.NetworkMessageService"; - impl tonic::server::NamedService for NetworkMessageServiceServer { - const NAME: &'static str = SERVICE_NAME; + impl tonic::server::NamedService + for NetworkMessageServiceServer { + const NAME: &'static str = "aptos.remote_executor.v1.NetworkMessageService"; } } diff --git a/protos/rust/src/pb/aptos.transaction.v1.rs b/protos/rust/src/pb/aptos.transaction.v1.rs index 8e9ffcceb7d51..3f029a2fe9981 100644 --- a/protos/rust/src/pb/aptos.transaction.v1.rs +++ b/protos/rust/src/pb/aptos.transaction.v1.rs @@ -12,6 +12,7 @@ /// the same `height`. /// /// The Genesis Transaction (version 0) is contained within the first block, which has a height of `0` +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Block { /// Timestamp represents the timestamp of the `BlockMetadataTransaction` (or `GenesisTransaction` for the genesis block) @@ -34,6 +35,7 @@ pub struct Block { /// - Block Metadata Transaction: transactions generated by the chain to group together transactions forming a "block" /// - Block Epilogue / State Checkpoint Transaction: transactions generated by the chain to end the group transactions forming a bloc /// - Genesis Transaction: the first transaction of the chain, with all core contract and validator information baked in +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Transaction { #[prost(message, optional, tag="1")] @@ -74,13 +76,13 @@ pub mod transaction { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "TRANSACTION_TYPE_UNSPECIFIED", - Self::Genesis => "TRANSACTION_TYPE_GENESIS", - Self::BlockMetadata => "TRANSACTION_TYPE_BLOCK_METADATA", - Self::StateCheckpoint => "TRANSACTION_TYPE_STATE_CHECKPOINT", - Self::User => "TRANSACTION_TYPE_USER", - Self::Validator => "TRANSACTION_TYPE_VALIDATOR", - Self::BlockEpilogue => "TRANSACTION_TYPE_BLOCK_EPILOGUE", + TransactionType::Unspecified => "TRANSACTION_TYPE_UNSPECIFIED", + TransactionType::Genesis => "TRANSACTION_TYPE_GENESIS", + TransactionType::BlockMetadata => "TRANSACTION_TYPE_BLOCK_METADATA", + TransactionType::StateCheckpoint => "TRANSACTION_TYPE_STATE_CHECKPOINT", + TransactionType::User => "TRANSACTION_TYPE_USER", + TransactionType::Validator => "TRANSACTION_TYPE_VALIDATOR", + TransactionType::BlockEpilogue => "TRANSACTION_TYPE_BLOCK_EPILOGUE", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -97,7 +99,8 @@ pub mod transaction { } } } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum TxnData { #[prost(message, tag="7")] BlockMetadata(super::BlockMetadataTransaction), @@ -116,6 +119,7 @@ pub mod transaction { } } /// Transaction types. +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct BlockMetadataTransaction { #[prost(string, tag="1")] @@ -131,6 +135,7 @@ pub struct BlockMetadataTransaction { #[prost(uint32, repeated, tag="6")] pub failed_proposer_indices: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GenesisTransaction { #[prost(message, optional, tag="1")] @@ -138,9 +143,11 @@ pub struct GenesisTransaction { #[prost(message, repeated, tag="2")] pub events: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct StateCheckpointTransaction { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValidatorTransaction { #[prost(message, repeated, tag="3")] @@ -150,14 +157,16 @@ pub struct ValidatorTransaction { } /// Nested message and enum types in `ValidatorTransaction`. pub mod validator_transaction { - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ObservedJwkUpdate { #[prost(message, optional, tag="1")] pub quorum_certified_update: ::core::option::Option, } /// Nested message and enum types in `ObservedJwkUpdate`. pub mod observed_jwk_update { - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ExportedProviderJwKs { #[prost(string, tag="1")] pub issuer: ::prost::alloc::string::String, @@ -168,14 +177,16 @@ pub mod validator_transaction { } /// Nested message and enum types in `ExportedProviderJWKs`. pub mod exported_provider_jw_ks { - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Jwk { #[prost(oneof="jwk::JwkType", tags="1, 2")] pub jwk_type: ::core::option::Option, } /// Nested message and enum types in `JWK`. pub mod jwk { - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Rsa { #[prost(string, tag="1")] pub kid: ::prost::alloc::string::String, @@ -188,14 +199,16 @@ pub mod validator_transaction { #[prost(string, tag="5")] pub n: ::prost::alloc::string::String, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct UnsupportedJwk { #[prost(bytes="vec", tag="1")] pub id: ::prost::alloc::vec::Vec, #[prost(bytes="vec", tag="2")] pub payload: ::prost::alloc::vec::Vec, } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum JwkType { #[prost(message, tag="1")] UnsupportedJwk(UnsupportedJwk), @@ -204,7 +217,8 @@ pub mod validator_transaction { } } } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ExportedAggregateSignature { #[prost(uint64, repeated, tag="1")] pub signer_indices: ::prost::alloc::vec::Vec, @@ -212,7 +226,8 @@ pub mod validator_transaction { #[prost(bytes="vec", tag="2")] pub sig: ::prost::alloc::vec::Vec, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct QuorumCertifiedUpdate { #[prost(message, optional, tag="1")] pub update: ::core::option::Option, @@ -220,14 +235,16 @@ pub mod validator_transaction { pub multi_sig: ::core::option::Option, } } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct DkgUpdate { #[prost(message, optional, tag="1")] pub dkg_transcript: ::core::option::Option, } /// Nested message and enum types in `DkgUpdate`. pub mod dkg_update { - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct DkgTranscript { #[prost(uint64, tag="1")] pub epoch: u64, @@ -237,7 +254,8 @@ pub mod validator_transaction { pub payload: ::prost::alloc::vec::Vec, } } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum ValidatorTransactionType { #[prost(message, tag="1")] ObservedJwkUpdate(ObservedJwkUpdate), @@ -245,11 +263,13 @@ pub mod validator_transaction { DkgUpdate(DkgUpdate), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct BlockEpilogueTransaction { #[prost(message, optional, tag="1")] pub block_end_info: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct BlockEndInfo { #[prost(bool, tag="1")] @@ -261,6 +281,7 @@ pub struct BlockEndInfo { #[prost(uint64, tag="4")] pub block_approx_output_size: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UserTransaction { #[prost(message, optional, tag="1")] @@ -268,6 +289,7 @@ pub struct UserTransaction { #[prost(message, repeated, tag="2")] pub events: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Event { #[prost(message, optional, tag="1")] @@ -281,6 +303,7 @@ pub struct Event { #[prost(string, tag="4")] pub data: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TransactionInfo { #[prost(bytes="vec", tag="1")] @@ -302,6 +325,7 @@ pub struct TransactionInfo { #[prost(message, repeated, tag="9")] pub changes: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct EventKey { #[prost(uint64, tag="1")] @@ -309,6 +333,7 @@ pub struct EventKey { #[prost(string, tag="2")] pub account_address: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UserTransactionRequest { #[prost(string, tag="1")] @@ -326,6 +351,7 @@ pub struct UserTransactionRequest { #[prost(message, optional, tag="7")] pub signature: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct WriteSet { #[prost(enumeration="write_set::WriteSetType", tag="1")] @@ -349,9 +375,9 @@ pub mod write_set { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "WRITE_SET_TYPE_UNSPECIFIED", - Self::ScriptWriteSet => "WRITE_SET_TYPE_SCRIPT_WRITE_SET", - Self::DirectWriteSet => "WRITE_SET_TYPE_DIRECT_WRITE_SET", + WriteSetType::Unspecified => "WRITE_SET_TYPE_UNSPECIFIED", + WriteSetType::ScriptWriteSet => "WRITE_SET_TYPE_SCRIPT_WRITE_SET", + WriteSetType::DirectWriteSet => "WRITE_SET_TYPE_DIRECT_WRITE_SET", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -364,7 +390,8 @@ pub mod write_set { } } } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum WriteSet { #[prost(message, tag="2")] ScriptWriteSet(super::ScriptWriteSet), @@ -372,6 +399,7 @@ pub mod write_set { DirectWriteSet(super::DirectWriteSet), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ScriptWriteSet { #[prost(string, tag="1")] @@ -379,6 +407,7 @@ pub struct ScriptWriteSet { #[prost(message, optional, tag="2")] pub script: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DirectWriteSet { #[prost(message, repeated, tag="1")] @@ -386,6 +415,7 @@ pub struct DirectWriteSet { #[prost(message, repeated, tag="2")] pub events: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct WriteSetChange { #[prost(enumeration="write_set_change::Type", tag="1")] @@ -413,13 +443,13 @@ pub mod write_set_change { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "TYPE_UNSPECIFIED", - Self::DeleteModule => "TYPE_DELETE_MODULE", - Self::DeleteResource => "TYPE_DELETE_RESOURCE", - Self::DeleteTableItem => "TYPE_DELETE_TABLE_ITEM", - Self::WriteModule => "TYPE_WRITE_MODULE", - Self::WriteResource => "TYPE_WRITE_RESOURCE", - Self::WriteTableItem => "TYPE_WRITE_TABLE_ITEM", + Type::Unspecified => "TYPE_UNSPECIFIED", + Type::DeleteModule => "TYPE_DELETE_MODULE", + Type::DeleteResource => "TYPE_DELETE_RESOURCE", + Type::DeleteTableItem => "TYPE_DELETE_TABLE_ITEM", + Type::WriteModule => "TYPE_WRITE_MODULE", + Type::WriteResource => "TYPE_WRITE_RESOURCE", + Type::WriteTableItem => "TYPE_WRITE_TABLE_ITEM", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -436,7 +466,8 @@ pub mod write_set_change { } } } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Change { #[prost(message, tag="2")] DeleteModule(super::DeleteModule), @@ -452,6 +483,7 @@ pub mod write_set_change { WriteTableItem(super::WriteTableItem), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteModule { #[prost(string, tag="1")] @@ -461,6 +493,7 @@ pub struct DeleteModule { #[prost(message, optional, tag="3")] pub module: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteResource { #[prost(string, tag="1")] @@ -472,6 +505,7 @@ pub struct DeleteResource { #[prost(string, tag="4")] pub type_str: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteTableItem { #[prost(bytes="vec", tag="1")] @@ -483,6 +517,7 @@ pub struct DeleteTableItem { #[prost(message, optional, tag="4")] pub data: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteTableData { #[prost(string, tag="1")] @@ -490,6 +525,7 @@ pub struct DeleteTableData { #[prost(string, tag="2")] pub key_type: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct WriteModule { #[prost(string, tag="1")] @@ -499,6 +535,7 @@ pub struct WriteModule { #[prost(message, optional, tag="3")] pub data: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct WriteResource { #[prost(string, tag="1")] @@ -512,6 +549,7 @@ pub struct WriteResource { #[prost(string, tag="5")] pub data: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct WriteTableData { #[prost(string, tag="1")] @@ -523,6 +561,7 @@ pub struct WriteTableData { #[prost(string, tag="4")] pub value_type: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct WriteTableItem { #[prost(bytes="vec", tag="1")] @@ -534,6 +573,7 @@ pub struct WriteTableItem { #[prost(message, optional, tag="4")] pub data: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TransactionPayload { #[prost(enumeration="transaction_payload::Type", tag="1")] @@ -559,11 +599,11 @@ pub mod transaction_payload { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "TYPE_UNSPECIFIED", - Self::EntryFunctionPayload => "TYPE_ENTRY_FUNCTION_PAYLOAD", - Self::ScriptPayload => "TYPE_SCRIPT_PAYLOAD", - Self::WriteSetPayload => "TYPE_WRITE_SET_PAYLOAD", - Self::MultisigPayload => "TYPE_MULTISIG_PAYLOAD", + Type::Unspecified => "TYPE_UNSPECIFIED", + Type::EntryFunctionPayload => "TYPE_ENTRY_FUNCTION_PAYLOAD", + Type::ScriptPayload => "TYPE_SCRIPT_PAYLOAD", + Type::WriteSetPayload => "TYPE_WRITE_SET_PAYLOAD", + Type::MultisigPayload => "TYPE_MULTISIG_PAYLOAD", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -578,7 +618,8 @@ pub mod transaction_payload { } } } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Payload { #[prost(message, tag="2")] EntryFunctionPayload(super::EntryFunctionPayload), @@ -590,6 +631,7 @@ pub mod transaction_payload { MultisigPayload(super::MultisigPayload), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct EntryFunctionPayload { #[prost(message, optional, tag="1")] @@ -601,6 +643,7 @@ pub struct EntryFunctionPayload { #[prost(string, tag="4")] pub entry_function_id_str: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveScriptBytecode { #[prost(bytes="vec", tag="1")] @@ -608,6 +651,7 @@ pub struct MoveScriptBytecode { #[prost(message, optional, tag="2")] pub abi: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ScriptPayload { #[prost(message, optional, tag="1")] @@ -617,6 +661,7 @@ pub struct ScriptPayload { #[prost(string, repeated, tag="3")] pub arguments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MultisigPayload { #[prost(string, tag="1")] @@ -624,6 +669,7 @@ pub struct MultisigPayload { #[prost(message, optional, tag="2")] pub transaction_payload: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MultisigTransactionPayload { #[prost(enumeration="multisig_transaction_payload::Type", tag="1")] @@ -646,8 +692,8 @@ pub mod multisig_transaction_payload { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "TYPE_UNSPECIFIED", - Self::EntryFunctionPayload => "TYPE_ENTRY_FUNCTION_PAYLOAD", + Type::Unspecified => "TYPE_UNSPECIFIED", + Type::EntryFunctionPayload => "TYPE_ENTRY_FUNCTION_PAYLOAD", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -659,12 +705,14 @@ pub mod multisig_transaction_payload { } } } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Payload { #[prost(message, tag="2")] EntryFunctionPayload(super::EntryFunctionPayload), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveModuleBytecode { #[prost(bytes="vec", tag="1")] @@ -672,6 +720,7 @@ pub struct MoveModuleBytecode { #[prost(message, optional, tag="2")] pub abi: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveModule { #[prost(string, tag="1")] @@ -685,6 +734,7 @@ pub struct MoveModule { #[prost(message, repeated, tag="5")] pub structs: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveFunction { #[prost(string, tag="1")] @@ -717,10 +767,10 @@ pub mod move_function { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "VISIBILITY_UNSPECIFIED", - Self::Private => "VISIBILITY_PRIVATE", - Self::Public => "VISIBILITY_PUBLIC", - Self::Friend => "VISIBILITY_FRIEND", + Visibility::Unspecified => "VISIBILITY_UNSPECIFIED", + Visibility::Private => "VISIBILITY_PRIVATE", + Visibility::Public => "VISIBILITY_PUBLIC", + Visibility::Friend => "VISIBILITY_FRIEND", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -735,6 +785,7 @@ pub mod move_function { } } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveStruct { #[prost(string, tag="1")] @@ -750,6 +801,7 @@ pub struct MoveStruct { #[prost(message, repeated, tag="5")] pub fields: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveStructGenericTypeParam { #[prost(enumeration="MoveAbility", repeated, tag="1")] @@ -757,6 +809,7 @@ pub struct MoveStructGenericTypeParam { #[prost(bool, tag="2")] pub is_phantom: bool, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveStructField { #[prost(string, tag="1")] @@ -764,11 +817,13 @@ pub struct MoveStructField { #[prost(message, optional, tag="2")] pub r#type: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveFunctionGenericTypeParam { #[prost(enumeration="MoveAbility", repeated, tag="1")] pub constraints: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveType { #[prost(enumeration="MoveTypes", tag="1")] @@ -778,14 +833,16 @@ pub struct MoveType { } /// Nested message and enum types in `MoveType`. pub mod move_type { - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ReferenceType { #[prost(bool, tag="1")] pub mutable: bool, #[prost(message, optional, boxed, tag="2")] pub to: ::core::option::Option<::prost::alloc::boxed::Box>, } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Content { #[prost(message, tag="3")] Vector(::prost::alloc::boxed::Box), @@ -799,11 +856,13 @@ pub mod move_type { Unparsable(::prost::alloc::string::String), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct WriteSetPayload { #[prost(message, optional, tag="1")] pub write_set: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct EntryFunctionId { #[prost(message, optional, tag="1")] @@ -811,6 +870,7 @@ pub struct EntryFunctionId { #[prost(string, tag="2")] pub name: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveModuleId { #[prost(string, tag="1")] @@ -818,6 +878,7 @@ pub struct MoveModuleId { #[prost(string, tag="2")] pub name: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MoveStructTag { #[prost(string, tag="1")] @@ -829,6 +890,7 @@ pub struct MoveStructTag { #[prost(message, repeated, tag="4")] pub generic_type_params: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Signature { #[prost(enumeration="signature::Type", tag="1")] @@ -855,12 +917,12 @@ pub mod signature { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "TYPE_UNSPECIFIED", - Self::Ed25519 => "TYPE_ED25519", - Self::MultiEd25519 => "TYPE_MULTI_ED25519", - Self::MultiAgent => "TYPE_MULTI_AGENT", - Self::FeePayer => "TYPE_FEE_PAYER", - Self::SingleSender => "TYPE_SINGLE_SENDER", + Type::Unspecified => "TYPE_UNSPECIFIED", + Type::Ed25519 => "TYPE_ED25519", + Type::MultiEd25519 => "TYPE_MULTI_ED25519", + Type::MultiAgent => "TYPE_MULTI_AGENT", + Type::FeePayer => "TYPE_FEE_PAYER", + Type::SingleSender => "TYPE_SINGLE_SENDER", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -876,7 +938,8 @@ pub mod signature { } } } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Signature { #[prost(message, tag="2")] Ed25519(super::Ed25519Signature), @@ -891,6 +954,7 @@ pub mod signature { SingleSender(super::SingleSender), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Ed25519Signature { #[prost(bytes="vec", tag="1")] @@ -898,6 +962,7 @@ pub struct Ed25519Signature { #[prost(bytes="vec", tag="2")] pub signature: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MultiEd25519Signature { #[prost(bytes="vec", repeated, tag="1")] @@ -909,6 +974,7 @@ pub struct MultiEd25519Signature { #[prost(uint32, repeated, tag="4")] pub public_key_indices: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MultiAgentSignature { #[prost(message, optional, tag="1")] @@ -918,6 +984,7 @@ pub struct MultiAgentSignature { #[prost(message, repeated, tag="3")] pub secondary_signers: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FeePayerSignature { #[prost(message, optional, tag="1")] @@ -931,6 +998,7 @@ pub struct FeePayerSignature { #[prost(message, optional, tag="5")] pub fee_payer_signer: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AnyPublicKey { #[prost(enumeration="any_public_key::Type", tag="1")] @@ -957,12 +1025,12 @@ pub mod any_public_key { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "TYPE_UNSPECIFIED", - Self::Ed25519 => "TYPE_ED25519", - Self::Secp256k1Ecdsa => "TYPE_SECP256K1_ECDSA", - Self::Secp256r1Ecdsa => "TYPE_SECP256R1_ECDSA", - Self::Keyless => "TYPE_KEYLESS", - Self::FederatedKeyless => "TYPE_FEDERATED_KEYLESS", + Type::Unspecified => "TYPE_UNSPECIFIED", + Type::Ed25519 => "TYPE_ED25519", + Type::Secp256k1Ecdsa => "TYPE_SECP256K1_ECDSA", + Type::Secp256r1Ecdsa => "TYPE_SECP256R1_ECDSA", + Type::Keyless => "TYPE_KEYLESS", + Type::FederatedKeyless => "TYPE_FEDERATED_KEYLESS", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -979,6 +1047,7 @@ pub mod any_public_key { } } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AnySignature { #[prost(enumeration="any_signature::Type", tag="1")] @@ -1010,11 +1079,11 @@ pub mod any_signature { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "TYPE_UNSPECIFIED", - Self::Ed25519 => "TYPE_ED25519", - Self::Secp256k1Ecdsa => "TYPE_SECP256K1_ECDSA", - Self::Webauthn => "TYPE_WEBAUTHN", - Self::Keyless => "TYPE_KEYLESS", + Type::Unspecified => "TYPE_UNSPECIFIED", + Type::Ed25519 => "TYPE_ED25519", + Type::Secp256k1Ecdsa => "TYPE_SECP256K1_ECDSA", + Type::Webauthn => "TYPE_WEBAUTHN", + Type::Keyless => "TYPE_KEYLESS", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1030,7 +1099,8 @@ pub mod any_signature { } } /// Support: >= 1.10. - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum SignatureVariant { #[prost(message, tag="3")] Ed25519(super::Ed25519), @@ -1042,26 +1112,31 @@ pub mod any_signature { Keyless(super::Keyless), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Ed25519 { #[prost(bytes="vec", tag="1")] pub signature: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Secp256k1Ecdsa { #[prost(bytes="vec", tag="1")] pub signature: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct WebAuthn { #[prost(bytes="vec", tag="1")] pub signature: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Keyless { #[prost(bytes="vec", tag="1")] pub signature: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SingleKeySignature { #[prost(message, optional, tag="1")] @@ -1069,6 +1144,7 @@ pub struct SingleKeySignature { #[prost(message, optional, tag="2")] pub signature: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct IndexedSignature { #[prost(uint32, tag="1")] @@ -1076,6 +1152,7 @@ pub struct IndexedSignature { #[prost(message, optional, tag="2")] pub signature: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MultiKeySignature { #[prost(message, repeated, tag="1")] @@ -1085,16 +1162,26 @@ pub struct MultiKeySignature { #[prost(uint32, tag="3")] pub signatures_required: u32, } +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AbstractionSignature { + #[prost(string, tag="1")] + pub function_info: ::prost::alloc::string::String, + #[prost(bytes="vec", tag="2")] + pub signature: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SingleSender { #[prost(message, optional, tag="1")] pub sender: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AccountSignature { #[prost(enumeration="account_signature::Type", tag="1")] pub r#type: i32, - #[prost(oneof="account_signature::Signature", tags="2, 3, 5, 6")] + #[prost(oneof="account_signature::Signature", tags="2, 3, 5, 6, 7")] pub signature: ::core::option::Option, } /// Nested message and enum types in `AccountSignature`. @@ -1107,6 +1194,7 @@ pub mod account_signature { MultiEd25519 = 2, SingleKey = 4, MultiKey = 5, + Abstraction = 6, } impl Type { /// String value of the enum field names used in the ProtoBuf definition. @@ -1115,11 +1203,12 @@ pub mod account_signature { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "TYPE_UNSPECIFIED", - Self::Ed25519 => "TYPE_ED25519", - Self::MultiEd25519 => "TYPE_MULTI_ED25519", - Self::SingleKey => "TYPE_SINGLE_KEY", - Self::MultiKey => "TYPE_MULTI_KEY", + Type::Unspecified => "TYPE_UNSPECIFIED", + Type::Ed25519 => "TYPE_ED25519", + Type::MultiEd25519 => "TYPE_MULTI_ED25519", + Type::SingleKey => "TYPE_SINGLE_KEY", + Type::MultiKey => "TYPE_MULTI_KEY", + Type::Abstraction => "TYPE_ABSTRACTION", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1130,11 +1219,13 @@ pub mod account_signature { "TYPE_MULTI_ED25519" => Some(Self::MultiEd25519), "TYPE_SINGLE_KEY" => Some(Self::SingleKey), "TYPE_MULTI_KEY" => Some(Self::MultiKey), + "TYPE_ABSTRACTION" => Some(Self::Abstraction), _ => None, } } } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Signature { #[prost(message, tag="2")] Ed25519(super::Ed25519Signature), @@ -1145,8 +1236,11 @@ pub mod account_signature { SingleKeySignature(super::SingleKeySignature), #[prost(message, tag="6")] MultiKeySignature(super::MultiKeySignature), + #[prost(message, tag="7")] + Abstraction(super::AbstractionSignature), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TransactionSizeInfo { #[prost(uint32, tag="1")] @@ -1156,6 +1250,7 @@ pub struct TransactionSizeInfo { #[prost(message, repeated, tag="3")] pub write_op_size_info: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct EventSizeInfo { #[prost(uint32, tag="1")] @@ -1163,6 +1258,7 @@ pub struct EventSizeInfo { #[prost(uint32, tag="2")] pub total_bytes: u32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct WriteOpSizeInfo { #[prost(uint32, tag="1")] @@ -1201,21 +1297,21 @@ impl MoveTypes { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "MOVE_TYPES_UNSPECIFIED", - Self::Bool => "MOVE_TYPES_BOOL", - Self::U8 => "MOVE_TYPES_U8", - Self::U16 => "MOVE_TYPES_U16", - Self::U32 => "MOVE_TYPES_U32", - Self::U64 => "MOVE_TYPES_U64", - Self::U128 => "MOVE_TYPES_U128", - Self::U256 => "MOVE_TYPES_U256", - Self::Address => "MOVE_TYPES_ADDRESS", - Self::Signer => "MOVE_TYPES_SIGNER", - Self::Vector => "MOVE_TYPES_VECTOR", - Self::Struct => "MOVE_TYPES_STRUCT", - Self::GenericTypeParam => "MOVE_TYPES_GENERIC_TYPE_PARAM", - Self::Reference => "MOVE_TYPES_REFERENCE", - Self::Unparsable => "MOVE_TYPES_UNPARSABLE", + MoveTypes::Unspecified => "MOVE_TYPES_UNSPECIFIED", + MoveTypes::Bool => "MOVE_TYPES_BOOL", + MoveTypes::U8 => "MOVE_TYPES_U8", + MoveTypes::U16 => "MOVE_TYPES_U16", + MoveTypes::U32 => "MOVE_TYPES_U32", + MoveTypes::U64 => "MOVE_TYPES_U64", + MoveTypes::U128 => "MOVE_TYPES_U128", + MoveTypes::U256 => "MOVE_TYPES_U256", + MoveTypes::Address => "MOVE_TYPES_ADDRESS", + MoveTypes::Signer => "MOVE_TYPES_SIGNER", + MoveTypes::Vector => "MOVE_TYPES_VECTOR", + MoveTypes::Struct => "MOVE_TYPES_STRUCT", + MoveTypes::GenericTypeParam => "MOVE_TYPES_GENERIC_TYPE_PARAM", + MoveTypes::Reference => "MOVE_TYPES_REFERENCE", + MoveTypes::Unparsable => "MOVE_TYPES_UNPARSABLE", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1256,11 +1352,11 @@ impl MoveAbility { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Unspecified => "MOVE_ABILITY_UNSPECIFIED", - Self::Copy => "MOVE_ABILITY_COPY", - Self::Drop => "MOVE_ABILITY_DROP", - Self::Store => "MOVE_ABILITY_STORE", - Self::Key => "MOVE_ABILITY_KEY", + MoveAbility::Unspecified => "MOVE_ABILITY_UNSPECIFIED", + MoveAbility::Copy => "MOVE_ABILITY_COPY", + MoveAbility::Drop => "MOVE_ABILITY_DROP", + MoveAbility::Store => "MOVE_ABILITY_STORE", + MoveAbility::Key => "MOVE_ABILITY_KEY", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1277,7 +1373,7 @@ impl MoveAbility { } /// Encoded file descriptor set for the `aptos.transaction.v1` package pub const FILE_DESCRIPTOR_SET: &[u8] = &[ - 0x0a, 0xdd, 0xb8, 0x02, 0x0a, 0x26, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2f, 0x74, 0x72, 0x61, 0x6e, + 0x0a, 0x9d, 0xbc, 0x02, 0x0a, 0x26, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, @@ -2181,1604 +2277,1632 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0x4e, 0x0a, 0x0c, 0x53, 0x69, 0x6e, - 0x67, 0x6c, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x65, 0x6e, - 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, - 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x22, 0xa8, 0x04, 0x0a, 0x10, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x3f, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, - 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, - 0x42, 0x0a, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x65, 0x64, 0x32, 0x35, - 0x35, 0x31, 0x39, 0x12, 0x52, 0x0a, 0x0d, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x65, 0x64, 0x32, - 0x35, 0x35, 0x31, 0x39, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x70, 0x74, - 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x75, 0x6c, 0x74, 0x69, - 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x5c, 0x0a, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, - 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x6e, - 0x67, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, - 0x00, 0x52, 0x12, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x59, 0x0a, 0x13, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x6b, - 0x65, 0x79, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x4b, - 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x11, 0x6d, - 0x75, 0x6c, 0x74, 0x69, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x22, 0x75, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, - 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, - 0x12, 0x16, 0x0a, 0x12, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x45, - 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x04, 0x12, 0x12, 0x0a, - 0x0e, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x10, - 0x05, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x42, 0x0b, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x22, 0xe3, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2b, 0x0a, 0x11, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, - 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x69, - 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x52, 0x0a, 0x12, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, - 0x6f, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, - 0x70, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x4f, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x56, 0x0a, 0x0d, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x0a, 0x0e, 0x74, - 0x79, 0x70, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x54, 0x61, 0x67, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x22, 0x4f, 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x70, 0x53, 0x69, 0x7a, - 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x2a, 0xea, 0x02, 0x0a, 0x09, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x73, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, - 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, - 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, - 0x5f, 0x55, 0x38, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x53, 0x5f, 0x55, 0x31, 0x36, 0x10, 0x0c, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f, 0x56, - 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x33, 0x32, 0x10, 0x0d, 0x12, 0x12, 0x0a, - 0x0e, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x36, 0x34, 0x10, - 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, - 0x55, 0x31, 0x32, 0x38, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x32, 0x35, 0x36, 0x10, 0x0e, 0x12, 0x16, 0x0a, 0x12, 0x4d, - 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, - 0x53, 0x10, 0x05, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x53, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x52, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, - 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x10, - 0x07, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, - 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x10, 0x08, 0x12, 0x21, 0x0a, 0x1d, 0x4d, 0x4f, 0x56, 0x45, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x10, 0x09, 0x12, 0x18, 0x0a, 0x14, 0x4d, - 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, - 0x4e, 0x43, 0x45, 0x10, 0x0a, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x53, 0x5f, 0x55, 0x4e, 0x50, 0x41, 0x52, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0b, - 0x2a, 0x87, 0x01, 0x0a, 0x0b, 0x4d, 0x6f, 0x76, 0x65, 0x41, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, - 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x43, - 0x4f, 0x50, 0x59, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, - 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, - 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x53, 0x54, 0x4f, - 0x52, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, - 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x04, 0x42, 0x9e, 0x01, 0x0a, 0x18, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0xa2, 0x02, 0x03, 0x41, 0x54, - 0x58, 0xaa, 0x02, 0x14, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x14, 0x41, 0x70, 0x74, 0x6f, 0x73, - 0x5c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0xe2, - 0x02, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x5c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x16, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x3a, 0x3a, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x4a, 0xaa, 0xba, 0x01, 0x0a, - 0x07, 0x12, 0x05, 0x03, 0x00, 0xee, 0x04, 0x01, 0x0a, 0x4e, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x03, - 0x00, 0x12, 0x32, 0x44, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0xc2, - 0xa9, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x0a, 0x20, 0x53, 0x50, 0x44, 0x58, 0x2d, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, - 0x2d, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, - 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x05, - 0x00, 0x1d, 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x07, 0x00, 0x2e, 0x0a, 0xa3, 0x05, - 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x12, 0x00, 0x20, 0x01, 0x1a, 0x96, 0x05, 0x20, 0x41, 0x20, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x20, 0x68, - 0x6f, 0x6c, 0x64, 0x73, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, - 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x28, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, - 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x6c, - 0x79, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x60, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x29, 0x0a, 0x20, 0x41, - 0x6c, 0x6c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, - 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x72, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, - 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x72, 0x20, 0x6d, - 0x6f, 0x72, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x0a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x60, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x64, 0x65, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x6f, 0x6e, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x54, 0x68, - 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x60, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x60, - 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6c, 0x79, 0x20, 0x6d, - 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x63, - 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2c, 0x0a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x72, - 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, 0x20, - 0x61, 0x20, 0x67, 0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x73, 0x6f, - 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, - 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x61, 0x6d, 0x65, 0x20, 0x60, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x60, 0x2e, 0x0a, 0x0a, 0x20, - 0x54, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x20, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x20, 0x30, 0x29, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, - 0x74, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x68, - 0x61, 0x73, 0x20, 0x61, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x60, - 0x30, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x12, 0x08, 0x0d, 0x0a, - 0xde, 0x01, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x15, 0x02, 0x2f, 0x1a, 0xd0, 0x01, - 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, - 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x28, 0x6f, 0x72, 0x20, 0x60, 0x47, 0x65, 0x6e, 0x65, 0x73, - 0x69, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x20, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, - 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x60, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x60, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x60, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x60, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x0a, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x15, 0x02, 0x20, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x15, 0x21, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x15, 0x2d, 0x2e, 0x0a, 0x88, 0x01, 0x0a, 0x04, 0x04, - 0x00, 0x02, 0x01, 0x12, 0x03, 0x18, 0x02, 0x29, 0x1a, 0x7b, 0x20, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x75, 0x6c, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x69, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x60, 0x42, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0x59, 0x0a, 0x14, 0x41, 0x62, 0x73, + 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x22, 0x4e, 0x0a, 0x0c, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x06, 0x73, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x22, 0x8f, 0x05, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x3f, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x42, 0x0a, 0x07, 0x65, 0x64, + 0x32, 0x35, 0x35, 0x31, 0x39, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x70, + 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x52, + 0x0a, 0x0d, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x6c, + 0x74, 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x45, 0x64, 0x32, 0x35, 0x35, + 0x31, 0x39, 0x12, 0x5c, 0x0a, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x6b, 0x65, 0x79, + 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x28, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x4b, 0x65, + 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x12, 0x73, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x59, 0x0a, 0x13, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, + 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x11, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x4b, + 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x4e, 0x0a, 0x0b, 0x61, + 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2a, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x0b, + 0x61, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8b, 0x01, 0x0a, 0x04, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x45, 0x44, 0x32, 0x35, 0x35, + 0x31, 0x39, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, + 0x47, 0x4c, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x05, 0x12, 0x14, 0x0a, + 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x42, 0x53, 0x54, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x10, 0x06, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x42, 0x0b, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xe3, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2b, + 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x52, 0x0a, 0x12, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x5f, 0x6f, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x4f, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x4f, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x56, 0x0a, 0x0d, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x0a, + 0x0e, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x54, 0x61, 0x67, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x22, 0x4f, 0x0a, 0x0f, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x70, 0x53, + 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0xea, 0x02, 0x0a, 0x09, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x42, 0x4f, + 0x4f, 0x4c, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x53, 0x5f, 0x55, 0x38, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f, 0x56, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x31, 0x36, 0x10, 0x0c, 0x12, 0x12, 0x0a, 0x0e, 0x4d, + 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x33, 0x32, 0x10, 0x0d, 0x12, + 0x12, 0x0a, 0x0e, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x36, + 0x34, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x53, 0x5f, 0x55, 0x31, 0x32, 0x38, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x4f, 0x56, 0x45, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x32, 0x35, 0x36, 0x10, 0x0e, 0x12, 0x16, 0x0a, + 0x12, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x41, 0x44, 0x44, 0x52, + 0x45, 0x53, 0x53, 0x10, 0x05, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x53, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x52, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, + 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x56, 0x45, 0x43, 0x54, 0x4f, + 0x52, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x53, 0x5f, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x10, 0x08, 0x12, 0x21, 0x0a, 0x1d, 0x4d, 0x4f, + 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x10, 0x09, 0x12, 0x18, 0x0a, + 0x14, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x46, 0x45, + 0x52, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x0a, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x4f, 0x56, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x53, 0x5f, 0x55, 0x4e, 0x50, 0x41, 0x52, 0x53, 0x41, 0x42, 0x4c, 0x45, + 0x10, 0x0b, 0x2a, 0x87, 0x01, 0x0a, 0x0b, 0x4d, 0x6f, 0x76, 0x65, 0x41, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, + 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, + 0x5f, 0x43, 0x4f, 0x50, 0x59, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x4f, 0x56, 0x45, 0x5f, + 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x02, 0x12, 0x16, + 0x0a, 0x12, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x53, + 0x54, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x41, + 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x04, 0x42, 0x9e, 0x01, 0x0a, + 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0xa2, 0x02, 0x03, + 0x41, 0x54, 0x58, 0xaa, 0x02, 0x14, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x14, 0x41, 0x70, 0x74, + 0x6f, 0x73, 0x5c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x5c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x3a, 0x3a, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x4a, 0xa8, 0xbc, + 0x01, 0x0a, 0x07, 0x12, 0x05, 0x03, 0x00, 0xf5, 0x04, 0x01, 0x0a, 0x4e, 0x0a, 0x01, 0x0c, 0x12, + 0x03, 0x03, 0x00, 0x12, 0x32, 0x44, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x20, 0xc2, 0xa9, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x53, 0x50, 0x44, 0x58, 0x2d, 0x4c, 0x69, 0x63, 0x65, 0x6e, + 0x73, 0x65, 0x2d, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x41, + 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, + 0x03, 0x05, 0x00, 0x1d, 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x07, 0x00, 0x2e, 0x0a, + 0xa3, 0x05, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x12, 0x00, 0x20, 0x01, 0x1a, 0x96, 0x05, 0x20, + 0x41, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x41, 0x70, 0x74, 0x6f, 0x73, + 0x20, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, + 0x69, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x28, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x61, + 0x6c, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x60, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x29, 0x0a, + 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x60, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x72, 0x65, 0x20, 0x66, 0x6f, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x72, + 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x0a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, - 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, - 0x18, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x18, 0x09, - 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x18, 0x12, 0x13, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x08, 0x12, 0x03, 0x18, 0x14, 0x28, 0x0a, 0x0d, 0x0a, - 0x06, 0x04, 0x00, 0x02, 0x01, 0x08, 0x06, 0x12, 0x03, 0x18, 0x15, 0x27, 0x0a, 0x87, 0x02, 0x0a, - 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x1c, 0x02, 0x28, 0x1a, 0xf9, 0x01, 0x20, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x68, 0x6f, 0x6c, 0x64, 0x73, - 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x20, - 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, 0x77, 0x68, - 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x64, 0x65, 0x6e, 0x6f, 0x74, 0x65, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x6f, 0x6e, 0x65, 0x2e, 0x0a, 0x0a, 0x20, + 0x54, 0x68, 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x60, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x60, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6c, 0x79, + 0x20, 0x6d, 0x6f, 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x69, + 0x6e, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, + 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2c, 0x0a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, + 0x65, 0x20, 0x61, 0x20, 0x67, 0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, + 0x73, 0x6f, 0x20, 0x61, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3a, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x69, + 0x6c, 0x6c, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, 0x20, 0x74, 0x77, 0x6f, 0x20, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0a, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x60, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x60, 0x2e, 0x0a, + 0x0a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x20, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x30, 0x29, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, + 0x72, 0x73, 0x74, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, + 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x6f, 0x66, + 0x20, 0x60, 0x30, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x12, 0x08, + 0x0d, 0x0a, 0xde, 0x01, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x15, 0x02, 0x2f, 0x1a, + 0xd0, 0x01, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x72, 0x65, 0x70, + 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x28, 0x6f, 0x72, 0x20, 0x60, 0x47, 0x65, 0x6e, + 0x65, 0x73, 0x69, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, + 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x76, 0x65, + 0x72, 0x79, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x60, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x60, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x60, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x60, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x15, 0x02, 0x20, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x15, 0x21, 0x2a, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x15, 0x2d, 0x2e, 0x0a, 0x88, 0x01, 0x0a, + 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x18, 0x02, 0x29, 0x1a, 0x7b, 0x20, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6c, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x2c, 0x20, + 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, + 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, + 0x12, 0x03, 0x18, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, + 0x18, 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x18, 0x12, + 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x08, 0x12, 0x03, 0x18, 0x14, 0x28, 0x0a, + 0x0d, 0x0a, 0x06, 0x04, 0x00, 0x02, 0x01, 0x08, 0x06, 0x12, 0x03, 0x18, 0x15, 0x27, 0x0a, 0x87, + 0x02, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x1c, 0x02, 0x28, 0x1a, 0xf9, 0x01, 0x20, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x68, 0x6f, 0x6c, + 0x64, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, - 0x64, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, - 0x28, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x29, 0x0a, - 0x20, 0x61, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x2c, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x70, 0x20, 0x74, 0x6f, - 0x20, 0x28, 0x62, 0x75, 0x74, 0x20, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x29, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x60, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x04, 0x12, - 0x03, 0x1c, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, 0x1c, - 0x0b, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x1c, 0x17, 0x23, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x1c, 0x26, 0x27, 0x0a, 0x99, - 0x01, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x1f, 0x02, 0x16, 0x1a, 0x8b, 0x01, 0x20, - 0x43, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x49, 0x44, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x73, - 0x20, 0x75, 0x73, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, - 0x77, 0x65, 0x27, 0x72, 0x65, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x69, - 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x6e, 0x73, 0x75, - 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x65, 0x27, 0x72, 0x65, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x6d, 0x69, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x20, - 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, - 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, - 0x02, 0x03, 0x05, 0x12, 0x03, 0x1f, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, - 0x01, 0x12, 0x03, 0x1f, 0x09, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x03, 0x12, - 0x03, 0x1f, 0x14, 0x15, 0x0a, 0x94, 0x04, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x27, 0x00, 0x47, - 0x01, 0x1a, 0x87, 0x04, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x20, - 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2c, 0x20, 0x74, 0x68, - 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x34, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, - 0x6f, 0x66, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, - 0x0a, 0x20, 0x2d, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x20, 0x77, - 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x0a, 0x20, 0x2d, - 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x68, - 0x65, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, - 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x22, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x22, 0x0a, 0x20, 0x2d, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x45, 0x70, 0x69, 0x6c, 0x6f, - 0x67, 0x75, 0x65, 0x20, 0x2f, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, - 0x62, 0x6c, 0x6f, 0x63, 0x0a, 0x20, 0x2d, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x20, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2c, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x62, 0x61, 0x6b, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, - 0x01, 0x01, 0x12, 0x03, 0x27, 0x08, 0x13, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, - 0x03, 0x28, 0x02, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x28, - 0x02, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x28, 0x21, 0x2a, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x2d, 0x2e, 0x0a, 0x0b, - 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x29, 0x02, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x29, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x01, 0x01, 0x12, 0x03, 0x29, 0x09, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, - 0x12, 0x03, 0x29, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x08, 0x12, 0x03, - 0x29, 0x15, 0x29, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x01, 0x08, 0x06, 0x12, 0x03, 0x29, - 0x16, 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, 0x2a, 0x02, 0x1b, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, 0x03, 0x2a, 0x02, 0x11, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x2a, 0x12, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x2a, 0x19, 0x1a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, - 0x03, 0x12, 0x03, 0x2b, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x05, 0x12, - 0x03, 0x2b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, 0x03, 0x2b, - 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x2b, 0x11, 0x12, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x08, 0x12, 0x03, 0x2b, 0x13, 0x27, 0x0a, 0x0d, - 0x0a, 0x06, 0x04, 0x01, 0x02, 0x03, 0x08, 0x06, 0x12, 0x03, 0x2b, 0x14, 0x26, 0x0a, 0x0b, 0x0a, - 0x04, 0x04, 0x01, 0x02, 0x04, 0x12, 0x03, 0x2c, 0x02, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x04, 0x05, 0x12, 0x03, 0x2c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, - 0x01, 0x12, 0x03, 0x2c, 0x09, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x03, 0x12, - 0x03, 0x2c, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x08, 0x12, 0x03, 0x2c, - 0x1a, 0x2e, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x04, 0x08, 0x06, 0x12, 0x03, 0x2c, 0x1b, - 0x2d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x04, 0x00, 0x12, 0x04, 0x2e, 0x02, 0x37, 0x03, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x04, 0x00, 0x01, 0x12, 0x03, 0x2e, 0x07, 0x16, 0x0a, 0x0d, 0x0a, - 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x2f, 0x04, 0x25, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2f, 0x04, 0x20, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x2f, 0x23, 0x24, 0x0a, 0x0d, 0x0a, 0x06, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x30, 0x04, 0x21, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x01, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x30, 0x04, 0x1c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x01, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x30, 0x1f, 0x20, 0x0a, 0x0d, 0x0a, 0x06, 0x04, - 0x01, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x31, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, - 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x31, 0x04, 0x23, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, - 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x03, 0x31, 0x26, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, - 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x32, 0x04, 0x2a, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, - 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x32, 0x04, 0x25, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, - 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x32, 0x28, 0x29, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, - 0x00, 0x02, 0x04, 0x12, 0x03, 0x33, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, - 0x02, 0x04, 0x01, 0x12, 0x03, 0x33, 0x04, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, - 0x02, 0x04, 0x02, 0x12, 0x03, 0x33, 0x1c, 0x1d, 0x0a, 0x32, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, - 0x02, 0x05, 0x12, 0x03, 0x35, 0x04, 0x24, 0x1a, 0x23, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x20, 0x35, 0x2d, 0x31, 0x39, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x20, 0x66, 0x6f, - 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x0a, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x03, 0x35, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x03, 0x35, 0x21, 0x23, 0x0a, 0x0d, 0x0a, 0x06, - 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x12, 0x03, 0x36, 0x04, 0x29, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x01, 0x04, 0x00, 0x02, 0x06, 0x01, 0x12, 0x03, 0x36, 0x04, 0x23, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x01, 0x04, 0x00, 0x02, 0x06, 0x02, 0x12, 0x03, 0x36, 0x26, 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, - 0x01, 0x02, 0x05, 0x12, 0x03, 0x39, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x05, - 0x06, 0x12, 0x03, 0x39, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x05, 0x01, 0x12, - 0x03, 0x39, 0x12, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x05, 0x03, 0x12, 0x03, 0x39, - 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x3b, 0x02, 0x44, 0x03, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x3b, 0x08, 0x10, 0x0a, 0x0b, - 0x0a, 0x04, 0x04, 0x01, 0x02, 0x06, 0x12, 0x03, 0x3c, 0x04, 0x30, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x06, 0x06, 0x12, 0x03, 0x3c, 0x04, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x06, 0x01, 0x12, 0x03, 0x3c, 0x1d, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x06, 0x03, - 0x12, 0x03, 0x3c, 0x2e, 0x2f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x07, 0x12, 0x03, 0x3d, - 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x06, 0x12, 0x03, 0x3d, 0x04, 0x16, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x01, 0x12, 0x03, 0x3d, 0x17, 0x1e, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x03, 0x12, 0x03, 0x3d, 0x21, 0x22, 0x0a, 0x0b, 0x0a, 0x04, - 0x04, 0x01, 0x02, 0x08, 0x12, 0x03, 0x3e, 0x04, 0x34, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x08, 0x06, 0x12, 0x03, 0x3e, 0x04, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x08, 0x01, - 0x12, 0x03, 0x3e, 0x1f, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x08, 0x03, 0x12, 0x03, - 0x3e, 0x32, 0x33, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x09, 0x12, 0x03, 0x3f, 0x04, 0x1e, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x06, 0x12, 0x03, 0x3f, 0x04, 0x13, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x01, 0x12, 0x03, 0x3f, 0x14, 0x18, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x09, 0x03, 0x12, 0x03, 0x3f, 0x1b, 0x1d, 0x0a, 0x30, 0x0a, 0x04, 0x04, 0x01, - 0x02, 0x0a, 0x12, 0x03, 0x41, 0x04, 0x28, 0x1a, 0x23, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, - 0x31, 0x31, 0x2d, 0x31, 0x39, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x20, 0x66, 0x6f, - 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x0a, 0x06, 0x12, 0x03, 0x41, 0x04, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x0a, 0x01, 0x12, 0x03, 0x41, 0x19, 0x22, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0a, - 0x03, 0x12, 0x03, 0x41, 0x25, 0x27, 0x0a, 0x6e, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x0b, 0x12, 0x03, - 0x43, 0x04, 0x31, 0x1a, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x32, 0x32, 0x20, 0x69, - 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x75, 0x70, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x77, 0x20, - 0x28, 0x61, 0x6c, 0x6c, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, - 0x68, 0x61, 0x76, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x29, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x20, - 0x74, 0x6f, 0x20, 0x32, 0x33, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, 0x06, 0x12, - 0x03, 0x43, 0x04, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, 0x01, 0x12, 0x03, 0x43, - 0x1d, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, 0x03, 0x12, 0x03, 0x43, 0x2e, 0x30, - 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x0c, 0x12, 0x03, 0x46, 0x02, 0x25, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x02, 0x0c, 0x06, 0x12, 0x03, 0x46, 0x02, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x0c, 0x01, 0x12, 0x03, 0x46, 0x16, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x0c, 0x03, 0x12, 0x03, 0x46, 0x22, 0x24, 0x0a, 0x20, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x4a, - 0x00, 0x51, 0x01, 0x1a, 0x14, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, - 0x12, 0x03, 0x4a, 0x08, 0x20, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, 0x03, 0x4b, - 0x02, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x05, 0x12, 0x03, 0x4b, 0x02, 0x08, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x4b, 0x09, 0x0b, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x4b, 0x0e, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, - 0x04, 0x02, 0x02, 0x01, 0x12, 0x03, 0x4c, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, - 0x01, 0x05, 0x12, 0x03, 0x4c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x01, - 0x12, 0x03, 0x4c, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x03, 0x12, 0x03, - 0x4c, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x08, 0x12, 0x03, 0x4c, 0x13, - 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x02, 0x01, 0x08, 0x06, 0x12, 0x03, 0x4c, 0x14, 0x26, - 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x02, 0x12, 0x03, 0x4d, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x02, 0x02, 0x02, 0x04, 0x12, 0x03, 0x4d, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x02, 0x02, 0x02, 0x06, 0x12, 0x03, 0x4d, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, - 0x02, 0x01, 0x12, 0x03, 0x4d, 0x11, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x03, - 0x12, 0x03, 0x4d, 0x1a, 0x1b, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x03, 0x12, 0x03, 0x4e, - 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x05, 0x12, 0x03, 0x4e, 0x02, 0x07, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x01, 0x12, 0x03, 0x4e, 0x08, 0x23, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x03, 0x12, 0x03, 0x4e, 0x26, 0x27, 0x0a, 0x0b, 0x0a, 0x04, - 0x04, 0x02, 0x02, 0x04, 0x12, 0x03, 0x4f, 0x02, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, - 0x04, 0x05, 0x12, 0x03, 0x4f, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x04, 0x01, - 0x12, 0x03, 0x4f, 0x09, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x04, 0x03, 0x12, 0x03, - 0x4f, 0x14, 0x15, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x05, 0x12, 0x03, 0x50, 0x02, 0x2e, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x04, 0x12, 0x03, 0x50, 0x02, 0x0a, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x05, 0x12, 0x03, 0x50, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x02, 0x02, 0x05, 0x01, 0x12, 0x03, 0x50, 0x12, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, - 0x02, 0x05, 0x03, 0x12, 0x03, 0x50, 0x2c, 0x2d, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, - 0x53, 0x00, 0x56, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x53, 0x08, 0x1a, - 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, 0x12, 0x03, 0x54, 0x02, 0x17, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, 0x54, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x54, 0x0b, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, - 0x00, 0x03, 0x12, 0x03, 0x54, 0x15, 0x16, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x01, 0x12, - 0x03, 0x55, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x04, 0x12, 0x03, 0x55, - 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x06, 0x12, 0x03, 0x55, 0x0b, 0x10, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x12, 0x03, 0x55, 0x11, 0x17, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x03, 0x12, 0x03, 0x55, 0x1a, 0x1b, 0x0a, 0x09, 0x0a, 0x02, - 0x04, 0x04, 0x12, 0x03, 0x58, 0x00, 0x25, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, 0x12, 0x03, - 0x58, 0x08, 0x22, 0x0a, 0x0b, 0x0a, 0x02, 0x04, 0x05, 0x12, 0x05, 0x5a, 0x00, 0x8e, 0x01, 0x01, - 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x5a, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x05, 0x08, 0x00, 0x12, 0x04, 0x5b, 0x02, 0x5e, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, - 0x08, 0x00, 0x01, 0x12, 0x03, 0x5b, 0x08, 0x20, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x00, - 0x12, 0x03, 0x5c, 0x04, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x06, 0x12, 0x03, - 0x5c, 0x04, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x01, 0x12, 0x03, 0x5c, 0x16, - 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x03, 0x12, 0x03, 0x5c, 0x2c, 0x2d, 0x0a, - 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x01, 0x12, 0x03, 0x5d, 0x04, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x05, 0x02, 0x01, 0x06, 0x12, 0x03, 0x5d, 0x04, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, - 0x02, 0x01, 0x01, 0x12, 0x03, 0x5d, 0x0e, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, - 0x03, 0x12, 0x03, 0x5d, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x04, 0x04, 0x05, 0x03, 0x00, 0x12, 0x05, - 0x60, 0x02, 0x82, 0x01, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x03, 0x00, 0x01, 0x12, 0x03, - 0x60, 0x0a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x12, 0x04, 0x61, - 0x04, 0x77, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, - 0x61, 0x0c, 0x20, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, - 0x03, 0x62, 0x06, 0x18, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, - 0x05, 0x12, 0x03, 0x62, 0x06, 0x0c, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, - 0x02, 0x00, 0x01, 0x12, 0x03, 0x62, 0x0d, 0x13, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, - 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x62, 0x16, 0x17, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x63, 0x06, 0x19, 0x0a, 0x10, 0x0a, 0x09, 0x04, - 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x63, 0x06, 0x0c, 0x0a, 0x10, 0x0a, - 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x63, 0x0d, 0x14, 0x0a, - 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x63, 0x17, - 0x18, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x12, 0x04, 0x64, - 0x06, 0x74, 0x07, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, - 0x12, 0x03, 0x64, 0x0e, 0x11, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x00, 0x12, 0x04, 0x65, 0x08, 0x6b, 0x09, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x65, 0x10, 0x13, 0x0a, 0x13, 0x0a, - 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x66, + 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x20, + 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x28, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, + 0x29, 0x0a, 0x20, 0x61, 0x20, 0x60, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x2c, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x70, 0x20, + 0x74, 0x6f, 0x20, 0x28, 0x62, 0x75, 0x74, 0x20, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, + 0x67, 0x29, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x60, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x60, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, + 0x04, 0x12, 0x03, 0x1c, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x06, 0x12, + 0x03, 0x1c, 0x0b, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x1c, + 0x17, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x1c, 0x26, 0x27, + 0x0a, 0x99, 0x01, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x1f, 0x02, 0x16, 0x1a, 0x8b, + 0x01, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x49, 0x44, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, + 0x6d, 0x73, 0x20, 0x75, 0x73, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x20, 0x77, 0x65, 0x27, 0x72, 0x65, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x6f, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, + 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x6e, + 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x65, 0x27, 0x72, 0x65, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x6d, 0x69, 0x78, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, + 0x65, 0x20, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x00, 0x02, 0x03, 0x05, 0x12, 0x03, 0x1f, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, + 0x02, 0x03, 0x01, 0x12, 0x03, 0x1f, 0x09, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, + 0x03, 0x12, 0x03, 0x1f, 0x14, 0x15, 0x0a, 0x94, 0x04, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x27, + 0x00, 0x47, 0x01, 0x1a, 0x87, 0x04, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x65, + 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2c, 0x20, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x34, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x3a, 0x0a, 0x20, 0x2d, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x0a, + 0x20, 0x2d, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x74, 0x6f, 0x67, 0x65, + 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x22, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x22, 0x0a, 0x20, 0x2d, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x45, 0x70, 0x69, + 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x20, 0x2f, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x6e, 0x64, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6e, 0x67, 0x20, + 0x61, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x0a, 0x20, 0x2d, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, + 0x73, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x63, 0x6f, 0x72, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x61, 0x6b, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x0a, 0x0a, 0x0a, + 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x27, 0x08, 0x13, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, + 0x00, 0x12, 0x03, 0x28, 0x02, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, + 0x03, 0x28, 0x02, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x28, + 0x21, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x2d, 0x2e, + 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x29, 0x02, 0x2a, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x29, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x29, 0x09, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, + 0x01, 0x03, 0x12, 0x03, 0x29, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x08, + 0x12, 0x03, 0x29, 0x15, 0x29, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x01, 0x08, 0x06, 0x12, + 0x03, 0x29, 0x16, 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, 0x2a, 0x02, + 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, 0x03, 0x2a, 0x02, 0x11, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x2a, 0x12, 0x16, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x2a, 0x19, 0x1a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x01, 0x02, 0x03, 0x12, 0x03, 0x2b, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, + 0x05, 0x12, 0x03, 0x2b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, + 0x03, 0x2b, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x2b, + 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x08, 0x12, 0x03, 0x2b, 0x13, 0x27, + 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x03, 0x08, 0x06, 0x12, 0x03, 0x2b, 0x14, 0x26, 0x0a, + 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x04, 0x12, 0x03, 0x2c, 0x02, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x04, 0x05, 0x12, 0x03, 0x2c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x04, 0x01, 0x12, 0x03, 0x2c, 0x09, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, + 0x03, 0x12, 0x03, 0x2c, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x08, 0x12, + 0x03, 0x2c, 0x1a, 0x2e, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x02, 0x04, 0x08, 0x06, 0x12, 0x03, + 0x2c, 0x1b, 0x2d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x04, 0x00, 0x12, 0x04, 0x2e, 0x02, 0x37, + 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x04, 0x00, 0x01, 0x12, 0x03, 0x2e, 0x07, 0x16, 0x0a, + 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x2f, 0x04, 0x25, 0x0a, 0x0e, + 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2f, 0x04, 0x20, 0x0a, 0x0e, + 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x2f, 0x23, 0x24, 0x0a, 0x0d, + 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x30, 0x04, 0x21, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x30, 0x04, 0x1c, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x30, 0x1f, 0x20, 0x0a, 0x0d, 0x0a, + 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x31, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x31, 0x04, 0x23, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x01, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x03, 0x31, 0x26, 0x27, 0x0a, 0x0d, 0x0a, 0x06, + 0x04, 0x01, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x32, 0x04, 0x2a, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x01, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x32, 0x04, 0x25, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x01, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x32, 0x28, 0x29, 0x0a, 0x0d, 0x0a, 0x06, 0x04, + 0x01, 0x04, 0x00, 0x02, 0x04, 0x12, 0x03, 0x33, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, + 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x33, 0x04, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, + 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x03, 0x33, 0x1c, 0x1d, 0x0a, 0x32, 0x0a, 0x06, 0x04, 0x01, + 0x04, 0x00, 0x02, 0x05, 0x12, 0x03, 0x35, 0x04, 0x24, 0x1a, 0x23, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x20, 0x35, 0x2d, 0x31, 0x39, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x0a, 0x0a, 0x0e, + 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x03, 0x35, 0x04, 0x1e, 0x0a, 0x0e, + 0x0a, 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x03, 0x35, 0x21, 0x23, 0x0a, 0x0d, + 0x0a, 0x06, 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x12, 0x03, 0x36, 0x04, 0x29, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x01, 0x12, 0x03, 0x36, 0x04, 0x23, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x01, 0x04, 0x00, 0x02, 0x06, 0x02, 0x12, 0x03, 0x36, 0x26, 0x28, 0x0a, 0x0b, 0x0a, + 0x04, 0x04, 0x01, 0x02, 0x05, 0x12, 0x03, 0x39, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x05, 0x06, 0x12, 0x03, 0x39, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x05, + 0x01, 0x12, 0x03, 0x39, 0x12, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x05, 0x03, 0x12, + 0x03, 0x39, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x3b, 0x02, + 0x44, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x3b, 0x08, 0x10, + 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x06, 0x12, 0x03, 0x3c, 0x04, 0x30, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x06, 0x06, 0x12, 0x03, 0x3c, 0x04, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x06, 0x01, 0x12, 0x03, 0x3c, 0x1d, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, + 0x06, 0x03, 0x12, 0x03, 0x3c, 0x2e, 0x2f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x07, 0x12, + 0x03, 0x3d, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x06, 0x12, 0x03, 0x3d, + 0x04, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x01, 0x12, 0x03, 0x3d, 0x17, 0x1e, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x07, 0x03, 0x12, 0x03, 0x3d, 0x21, 0x22, 0x0a, 0x0b, + 0x0a, 0x04, 0x04, 0x01, 0x02, 0x08, 0x12, 0x03, 0x3e, 0x04, 0x34, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x08, 0x06, 0x12, 0x03, 0x3e, 0x04, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, + 0x08, 0x01, 0x12, 0x03, 0x3e, 0x1f, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x08, 0x03, + 0x12, 0x03, 0x3e, 0x32, 0x33, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x09, 0x12, 0x03, 0x3f, + 0x04, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x06, 0x12, 0x03, 0x3f, 0x04, 0x13, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x01, 0x12, 0x03, 0x3f, 0x14, 0x18, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x01, 0x02, 0x09, 0x03, 0x12, 0x03, 0x3f, 0x1b, 0x1d, 0x0a, 0x30, 0x0a, 0x04, + 0x04, 0x01, 0x02, 0x0a, 0x12, 0x03, 0x41, 0x04, 0x28, 0x1a, 0x23, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x20, 0x31, 0x31, 0x2d, 0x31, 0x39, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x0a, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0a, 0x06, 0x12, 0x03, 0x41, 0x04, 0x18, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x0a, 0x01, 0x12, 0x03, 0x41, 0x19, 0x22, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x0a, 0x03, 0x12, 0x03, 0x41, 0x25, 0x27, 0x0a, 0x6e, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x0b, + 0x12, 0x03, 0x43, 0x04, 0x31, 0x1a, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x32, 0x32, + 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x75, 0x70, 0x20, 0x62, 0x65, 0x6c, 0x6f, + 0x77, 0x20, 0x28, 0x61, 0x6c, 0x6c, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, + 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, + 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x67, 0x6f, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x6f, 0x20, 0x32, 0x33, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, + 0x06, 0x12, 0x03, 0x43, 0x04, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, 0x01, 0x12, + 0x03, 0x43, 0x1d, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0b, 0x03, 0x12, 0x03, 0x43, + 0x2e, 0x30, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x0c, 0x12, 0x03, 0x46, 0x02, 0x25, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x0c, 0x06, 0x12, 0x03, 0x46, 0x02, 0x15, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x0c, 0x01, 0x12, 0x03, 0x46, 0x16, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x0c, 0x03, 0x12, 0x03, 0x46, 0x22, 0x24, 0x0a, 0x20, 0x0a, 0x02, 0x04, 0x02, 0x12, + 0x04, 0x4a, 0x00, 0x51, 0x01, 0x1a, 0x14, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, + 0x02, 0x01, 0x12, 0x03, 0x4a, 0x08, 0x20, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, + 0x03, 0x4b, 0x02, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x05, 0x12, 0x03, 0x4b, + 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x4b, 0x09, 0x0b, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x4b, 0x0e, 0x0f, 0x0a, 0x0b, + 0x0a, 0x04, 0x04, 0x02, 0x02, 0x01, 0x12, 0x03, 0x4c, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x02, 0x02, 0x01, 0x05, 0x12, 0x03, 0x4c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, + 0x01, 0x01, 0x12, 0x03, 0x4c, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x03, + 0x12, 0x03, 0x4c, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x08, 0x12, 0x03, + 0x4c, 0x13, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x02, 0x01, 0x08, 0x06, 0x12, 0x03, 0x4c, + 0x14, 0x26, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x02, 0x12, 0x03, 0x4d, 0x02, 0x1c, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x04, 0x12, 0x03, 0x4d, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x02, 0x02, 0x02, 0x06, 0x12, 0x03, 0x4d, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x02, 0x02, 0x02, 0x01, 0x12, 0x03, 0x4d, 0x11, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, + 0x02, 0x03, 0x12, 0x03, 0x4d, 0x1a, 0x1b, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x03, 0x12, + 0x03, 0x4e, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x05, 0x12, 0x03, 0x4e, + 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x01, 0x12, 0x03, 0x4e, 0x08, 0x23, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x03, 0x12, 0x03, 0x4e, 0x26, 0x27, 0x0a, 0x0b, + 0x0a, 0x04, 0x04, 0x02, 0x02, 0x04, 0x12, 0x03, 0x4f, 0x02, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x02, 0x02, 0x04, 0x05, 0x12, 0x03, 0x4f, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, + 0x04, 0x01, 0x12, 0x03, 0x4f, 0x09, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x04, 0x03, + 0x12, 0x03, 0x4f, 0x14, 0x15, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x05, 0x12, 0x03, 0x50, + 0x02, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x04, 0x12, 0x03, 0x50, 0x02, 0x0a, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x05, 0x12, 0x03, 0x50, 0x0b, 0x11, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x02, 0x02, 0x05, 0x01, 0x12, 0x03, 0x50, 0x12, 0x29, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x02, 0x02, 0x05, 0x03, 0x12, 0x03, 0x50, 0x2c, 0x2d, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, + 0x12, 0x04, 0x53, 0x00, 0x56, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x53, + 0x08, 0x1a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, 0x12, 0x03, 0x54, 0x02, 0x17, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, 0x54, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x54, 0x0b, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x54, 0x15, 0x16, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, + 0x01, 0x12, 0x03, 0x55, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x04, 0x12, + 0x03, 0x55, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x06, 0x12, 0x03, 0x55, + 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x12, 0x03, 0x55, 0x11, 0x17, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x03, 0x12, 0x03, 0x55, 0x1a, 0x1b, 0x0a, 0x09, + 0x0a, 0x02, 0x04, 0x04, 0x12, 0x03, 0x58, 0x00, 0x25, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, + 0x12, 0x03, 0x58, 0x08, 0x22, 0x0a, 0x0b, 0x0a, 0x02, 0x04, 0x05, 0x12, 0x05, 0x5a, 0x00, 0x8e, + 0x01, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x5a, 0x08, 0x1c, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x05, 0x08, 0x00, 0x12, 0x04, 0x5b, 0x02, 0x5e, 0x03, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x05, 0x08, 0x00, 0x01, 0x12, 0x03, 0x5b, 0x08, 0x20, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, + 0x02, 0x00, 0x12, 0x03, 0x5c, 0x04, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x06, + 0x12, 0x03, 0x5c, 0x04, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x01, 0x12, 0x03, + 0x5c, 0x16, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x03, 0x12, 0x03, 0x5c, 0x2c, + 0x2d, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x01, 0x12, 0x03, 0x5d, 0x04, 0x1d, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x06, 0x12, 0x03, 0x5d, 0x04, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x05, 0x02, 0x01, 0x01, 0x12, 0x03, 0x5d, 0x0e, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, + 0x02, 0x01, 0x03, 0x12, 0x03, 0x5d, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x04, 0x04, 0x05, 0x03, 0x00, + 0x12, 0x05, 0x60, 0x02, 0x82, 0x01, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x03, 0x00, 0x01, + 0x12, 0x03, 0x60, 0x0a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x12, + 0x04, 0x61, 0x04, 0x77, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x01, + 0x12, 0x03, 0x61, 0x0c, 0x20, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, + 0x00, 0x12, 0x03, 0x62, 0x06, 0x18, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, + 0x02, 0x00, 0x05, 0x12, 0x03, 0x62, 0x06, 0x0c, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x62, 0x0d, 0x13, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x62, 0x16, 0x17, 0x0a, 0x0f, 0x0a, 0x08, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x63, 0x06, 0x19, 0x0a, 0x10, 0x0a, + 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x63, 0x06, 0x0c, 0x0a, + 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x63, 0x0d, + 0x14, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, + 0x63, 0x17, 0x18, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x12, + 0x04, 0x64, 0x06, 0x74, 0x07, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x01, 0x12, 0x03, 0x64, 0x0e, 0x11, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x12, 0x04, 0x65, 0x08, 0x6b, 0x09, 0x0a, 0x12, 0x0a, 0x0b, 0x04, + 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x65, 0x10, 0x13, 0x0a, + 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, + 0x03, 0x66, 0x0a, 0x19, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x66, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x66, 0x11, 0x14, + 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x03, 0x12, 0x03, 0x66, 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x67, 0x0a, 0x19, 0x0a, 0x14, 0x0a, 0x0d, 0x04, + 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x67, 0x0a, + 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, + 0x01, 0x01, 0x12, 0x03, 0x67, 0x11, 0x14, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x67, 0x17, 0x18, 0x0a, 0x13, 0x0a, + 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x12, 0x03, 0x68, 0x0a, 0x19, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x02, 0x00, 0x05, 0x12, 0x03, 0x66, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x66, 0x11, 0x14, 0x0a, 0x14, - 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, - 0x03, 0x66, 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x67, 0x0a, 0x19, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x67, 0x0a, 0x10, 0x0a, - 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x01, - 0x12, 0x03, 0x67, 0x11, 0x14, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x67, 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, 0x04, - 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x12, 0x03, 0x68, 0x0a, 0x19, - 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, - 0x05, 0x12, 0x03, 0x68, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x68, 0x11, 0x14, 0x0a, 0x14, 0x0a, 0x0d, - 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x68, - 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x02, 0x03, 0x12, 0x03, 0x69, 0x0a, 0x17, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x03, 0x05, 0x12, 0x03, 0x69, 0x0a, 0x10, 0x0a, 0x14, 0x0a, - 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, - 0x69, 0x11, 0x12, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x69, 0x15, 0x16, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x12, 0x03, 0x6a, 0x0a, 0x17, 0x0a, 0x14, - 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x05, 0x12, - 0x03, 0x6a, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x6a, 0x11, 0x12, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x03, 0x12, 0x03, 0x6a, 0x15, 0x16, - 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x12, 0x04, - 0x6c, 0x08, 0x6f, 0x09, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x01, 0x01, 0x12, 0x03, 0x6c, 0x10, 0x1e, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x12, 0x03, 0x6d, 0x0a, 0x17, 0x0a, 0x14, 0x0a, - 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, - 0x6d, 0x0a, 0x0f, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x6d, 0x10, 0x12, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x6d, 0x15, 0x16, 0x0a, - 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x12, - 0x03, 0x6e, 0x0a, 0x1c, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x6e, 0x0a, 0x0f, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x6e, 0x10, 0x17, - 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, - 0x03, 0x12, 0x03, 0x6e, 0x1a, 0x1b, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x08, 0x00, 0x12, 0x04, 0x70, 0x08, 0x73, 0x09, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x70, 0x0e, 0x15, 0x0a, 0x11, - 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x71, 0x0a, - 0x2d, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x06, - 0x12, 0x03, 0x71, 0x0a, 0x18, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x71, 0x19, 0x28, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, - 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x71, 0x2b, 0x2c, 0x0a, 0x11, 0x0a, - 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x72, 0x0a, 0x16, - 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x06, 0x12, - 0x03, 0x72, 0x0a, 0x0d, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x02, 0x01, 0x01, 0x12, 0x03, 0x72, 0x0e, 0x11, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, - 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x72, 0x14, 0x15, 0x0a, 0x0f, 0x0a, 0x08, - 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x12, 0x03, 0x76, 0x06, 0x1c, 0x0a, 0x10, 0x0a, - 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x04, 0x12, 0x03, 0x76, 0x06, 0x0e, 0x0a, - 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, 0x76, 0x0f, - 0x12, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, - 0x76, 0x13, 0x17, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x03, - 0x12, 0x03, 0x76, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x12, - 0x04, 0x78, 0x04, 0x7c, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x01, - 0x12, 0x03, 0x78, 0x0c, 0x26, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, - 0x00, 0x12, 0x03, 0x79, 0x06, 0x29, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, - 0x02, 0x00, 0x04, 0x12, 0x03, 0x79, 0x06, 0x0e, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, - 0x03, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, 0x79, 0x0f, 0x15, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x79, 0x16, 0x24, 0x0a, 0x10, 0x0a, 0x09, - 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x79, 0x27, 0x28, 0x0a, 0x1e, - 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x12, 0x03, 0x7b, 0x06, 0x14, 0x1a, - 0x0d, 0x20, 0x48, 0x65, 0x78, 0x54, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x10, - 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x7b, 0x06, 0x0b, - 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x7b, - 0x0c, 0x0f, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x03, 0x12, - 0x03, 0x7b, 0x12, 0x13, 0x0a, 0x0f, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x12, 0x05, - 0x7d, 0x04, 0x80, 0x01, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x01, - 0x12, 0x03, 0x7d, 0x0c, 0x21, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, - 0x00, 0x12, 0x03, 0x7e, 0x06, 0x26, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, - 0x02, 0x00, 0x06, 0x12, 0x03, 0x7e, 0x06, 0x1a, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, - 0x03, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x7e, 0x1b, 0x21, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, - 0x03, 0x00, 0x03, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x7e, 0x24, 0x25, 0x0a, 0x0f, 0x0a, 0x08, - 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x12, 0x03, 0x7f, 0x06, 0x2f, 0x0a, 0x10, 0x0a, - 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x06, 0x12, 0x03, 0x7f, 0x06, 0x20, 0x0a, - 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x01, 0x12, 0x03, 0x7f, 0x21, - 0x2a, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x03, 0x12, 0x03, - 0x7f, 0x2d, 0x2e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x12, 0x04, 0x81, - 0x01, 0x04, 0x36, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x06, 0x12, 0x04, - 0x81, 0x01, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, - 0x04, 0x81, 0x01, 0x1a, 0x31, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x03, - 0x12, 0x04, 0x81, 0x01, 0x34, 0x35, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x05, 0x03, 0x01, 0x12, 0x06, - 0x84, 0x01, 0x02, 0x8b, 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x03, 0x01, 0x01, 0x12, - 0x04, 0x84, 0x01, 0x0a, 0x13, 0x0a, 0x10, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x12, - 0x06, 0x85, 0x01, 0x04, 0x89, 0x01, 0x05, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x01, 0x03, - 0x00, 0x01, 0x12, 0x04, 0x85, 0x01, 0x0c, 0x19, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x01, - 0x03, 0x00, 0x02, 0x00, 0x12, 0x04, 0x86, 0x01, 0x06, 0x17, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, - 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x04, 0x86, 0x01, 0x06, 0x0c, 0x0a, 0x11, 0x0a, - 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x86, 0x01, 0x0d, 0x12, - 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x04, 0x86, - 0x01, 0x15, 0x16, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01, 0x12, - 0x04, 0x87, 0x01, 0x06, 0x18, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, - 0x01, 0x05, 0x12, 0x04, 0x87, 0x01, 0x06, 0x0c, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, - 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x87, 0x01, 0x0d, 0x13, 0x0a, 0x11, 0x0a, 0x09, 0x04, - 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x04, 0x87, 0x01, 0x16, 0x17, 0x0a, 0x10, - 0x0a, 0x08, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, 0x12, 0x04, 0x88, 0x01, 0x06, 0x18, - 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, 0x05, 0x12, 0x04, 0x88, - 0x01, 0x06, 0x0b, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, 0x01, - 0x12, 0x04, 0x88, 0x01, 0x0c, 0x13, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, - 0x02, 0x02, 0x03, 0x12, 0x04, 0x88, 0x01, 0x16, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, - 0x01, 0x02, 0x00, 0x12, 0x04, 0x8a, 0x01, 0x04, 0x25, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, - 0x01, 0x02, 0x00, 0x06, 0x12, 0x04, 0x8a, 0x01, 0x04, 0x11, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, - 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8a, 0x01, 0x12, 0x20, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x05, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x04, 0x8a, 0x01, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x05, 0x02, 0x02, 0x12, 0x04, 0x8d, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, - 0x02, 0x02, 0x04, 0x12, 0x04, 0x8d, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x02, - 0x02, 0x06, 0x12, 0x04, 0x8d, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, - 0x01, 0x12, 0x04, 0x8d, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, 0x03, - 0x12, 0x04, 0x8d, 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x06, 0x12, 0x06, 0x90, 0x01, - 0x00, 0x92, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x06, 0x01, 0x12, 0x04, 0x90, 0x01, 0x08, - 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x06, 0x02, 0x00, 0x12, 0x04, 0x91, 0x01, 0x02, 0x2b, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x04, 0x12, 0x04, 0x91, 0x01, 0x02, 0x0a, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x06, 0x12, 0x04, 0x91, 0x01, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x06, 0x02, 0x00, 0x01, 0x12, 0x04, 0x91, 0x01, 0x18, 0x26, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x06, 0x02, 0x00, 0x03, 0x12, 0x04, 0x91, 0x01, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, 0x02, 0x04, - 0x07, 0x12, 0x06, 0x94, 0x01, 0x00, 0x99, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x07, 0x01, - 0x12, 0x04, 0x94, 0x01, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x00, 0x12, 0x04, - 0x95, 0x01, 0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x05, 0x12, 0x04, 0x95, - 0x01, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x01, 0x12, 0x04, 0x95, 0x01, - 0x07, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x03, 0x12, 0x04, 0x95, 0x01, 0x21, - 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x01, 0x12, 0x04, 0x96, 0x01, 0x02, 0x26, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x05, 0x12, 0x04, 0x96, 0x01, 0x02, 0x06, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x01, 0x12, 0x04, 0x96, 0x01, 0x07, 0x21, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x07, 0x02, 0x01, 0x03, 0x12, 0x04, 0x96, 0x01, 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x07, 0x02, 0x02, 0x12, 0x04, 0x97, 0x01, 0x02, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, - 0x02, 0x02, 0x05, 0x12, 0x04, 0x97, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, - 0x02, 0x01, 0x12, 0x04, 0x97, 0x01, 0x09, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x02, - 0x03, 0x12, 0x04, 0x97, 0x01, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x03, 0x12, - 0x04, 0x98, 0x01, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x05, 0x12, 0x04, - 0x98, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x01, 0x12, 0x04, 0x98, - 0x01, 0x09, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x03, 0x12, 0x04, 0x98, 0x01, - 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x08, 0x12, 0x06, 0x9b, 0x01, 0x00, 0x9e, 0x01, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x08, 0x01, 0x12, 0x04, 0x9b, 0x01, 0x08, 0x17, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x08, 0x02, 0x00, 0x12, 0x04, 0x9c, 0x01, 0x02, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x08, 0x02, 0x00, 0x06, 0x12, 0x04, 0x9c, 0x01, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, - 0x02, 0x00, 0x01, 0x12, 0x04, 0x9c, 0x01, 0x19, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, - 0x00, 0x03, 0x12, 0x04, 0x9c, 0x01, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x01, - 0x12, 0x04, 0x9d, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x04, 0x12, - 0x04, 0x9d, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x06, 0x12, 0x04, - 0x9d, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x01, 0x12, 0x04, 0x9d, - 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x03, 0x12, 0x04, 0x9d, 0x01, - 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x09, 0x12, 0x06, 0xa0, 0x01, 0x00, 0xa6, 0x01, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x09, 0x01, 0x12, 0x04, 0xa0, 0x01, 0x08, 0x0d, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x09, 0x02, 0x00, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x09, 0x02, 0x00, 0x06, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xa1, 0x01, 0x0b, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xa1, 0x01, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x01, - 0x12, 0x04, 0xa2, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x05, 0x12, - 0x04, 0xa2, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x01, 0x12, 0x04, - 0xa2, 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x03, 0x12, 0x04, 0xa2, - 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x08, 0x12, 0x04, 0xa2, 0x01, - 0x1d, 0x31, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x09, 0x02, 0x01, 0x08, 0x06, 0x12, 0x04, 0xa2, 0x01, - 0x1e, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x02, 0x12, 0x04, 0xa3, 0x01, 0x02, 0x14, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x06, 0x12, 0x04, 0xa3, 0x01, 0x02, 0x0a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x01, 0x12, 0x04, 0xa3, 0x01, 0x0b, 0x0f, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x03, 0x12, 0x04, 0xa3, 0x01, 0x12, 0x13, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x09, 0x02, 0x03, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x09, 0x02, 0x03, 0x05, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, - 0x02, 0x03, 0x01, 0x12, 0x04, 0xa4, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, - 0x03, 0x03, 0x12, 0x04, 0xa4, 0x01, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x04, - 0x12, 0x04, 0xa5, 0x01, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, 0x05, 0x12, - 0x04, 0xa5, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, 0x01, 0x12, 0x04, - 0xa5, 0x01, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, 0x03, 0x12, 0x04, 0xa5, - 0x01, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0a, 0x12, 0x06, 0xa8, 0x01, 0x00, 0xb2, 0x01, - 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0a, 0x01, 0x12, 0x04, 0xa8, 0x01, 0x08, 0x17, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x00, 0x12, 0x04, 0xa9, 0x01, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa9, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa9, 0x01, 0x08, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, - 0x02, 0x00, 0x03, 0x12, 0x04, 0xa9, 0x01, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, - 0x01, 0x12, 0x04, 0xaa, 0x01, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x05, - 0x12, 0x04, 0xaa, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x01, 0x12, - 0x04, 0xaa, 0x01, 0x08, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x03, 0x12, 0x04, - 0xaa, 0x01, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x02, 0x12, 0x04, 0xab, 0x01, - 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x05, 0x12, 0x04, 0xab, 0x01, 0x02, - 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x01, 0x12, 0x04, 0xab, 0x01, 0x08, 0x17, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x03, 0x12, 0x04, 0xab, 0x01, 0x1a, 0x1b, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x03, 0x12, 0x04, 0xac, 0x01, 0x02, 0x2b, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x0a, 0x02, 0x03, 0x04, 0x12, 0x04, 0xac, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0a, 0x02, 0x03, 0x05, 0x12, 0x04, 0xac, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0a, 0x02, 0x03, 0x01, 0x12, 0x04, 0xac, 0x01, 0x11, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, - 0x02, 0x03, 0x03, 0x12, 0x04, 0xac, 0x01, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, - 0x04, 0x12, 0x04, 0xad, 0x01, 0x02, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, 0x05, - 0x12, 0x04, 0xad, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, 0x01, 0x12, - 0x04, 0xad, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, - 0xad, 0x01, 0x14, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, 0x08, 0x12, 0x04, 0xad, - 0x01, 0x16, 0x2a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0a, 0x02, 0x04, 0x08, 0x06, 0x12, 0x04, 0xad, - 0x01, 0x17, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x05, 0x12, 0x04, 0xae, 0x01, 0x02, - 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x05, 0x12, 0x04, 0xae, 0x01, 0x02, 0x06, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x01, 0x12, 0x04, 0xae, 0x01, 0x07, 0x0e, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x03, 0x12, 0x04, 0xae, 0x01, 0x11, 0x12, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x06, 0x12, 0x04, 0xaf, 0x01, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0a, 0x02, 0x06, 0x05, 0x12, 0x04, 0xaf, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0a, 0x02, 0x06, 0x01, 0x12, 0x04, 0xaf, 0x01, 0x09, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, - 0x02, 0x06, 0x03, 0x12, 0x04, 0xaf, 0x01, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, - 0x07, 0x12, 0x04, 0xb0, 0x01, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x07, 0x05, - 0x12, 0x04, 0xb0, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x07, 0x01, 0x12, - 0x04, 0xb0, 0x01, 0x08, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x07, 0x03, 0x12, 0x04, - 0xb0, 0x01, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x08, 0x12, 0x04, 0xb1, 0x01, - 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x04, 0x12, 0x04, 0xb1, 0x01, 0x02, - 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x06, 0x12, 0x04, 0xb1, 0x01, 0x0b, 0x19, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x01, 0x12, 0x04, 0xb1, 0x01, 0x1a, 0x21, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x03, 0x12, 0x04, 0xb1, 0x01, 0x24, 0x25, 0x0a, 0x0c, - 0x0a, 0x02, 0x04, 0x0b, 0x12, 0x06, 0xb4, 0x01, 0x00, 0xb7, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, - 0x04, 0x0b, 0x01, 0x12, 0x04, 0xb4, 0x01, 0x08, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0b, 0x02, - 0x00, 0x12, 0x04, 0xb5, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x05, - 0x12, 0x04, 0xb5, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x01, 0x12, - 0x04, 0xb5, 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x03, 0x12, 0x04, - 0xb5, 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x08, 0x12, 0x04, 0xb5, - 0x01, 0x1d, 0x31, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0b, 0x02, 0x00, 0x08, 0x06, 0x12, 0x04, 0xb5, - 0x01, 0x1e, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0b, 0x02, 0x01, 0x12, 0x04, 0xb6, 0x01, 0x02, - 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x05, 0x12, 0x04, 0xb6, 0x01, 0x02, 0x08, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb6, 0x01, 0x09, 0x18, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb6, 0x01, 0x1b, 0x1c, 0x0a, 0x0c, - 0x0a, 0x02, 0x04, 0x0c, 0x12, 0x06, 0xb9, 0x01, 0x00, 0xc1, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, - 0x04, 0x0c, 0x01, 0x12, 0x04, 0xb9, 0x01, 0x08, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, - 0x00, 0x12, 0x04, 0xba, 0x01, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x05, - 0x12, 0x04, 0xba, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x01, 0x12, - 0x04, 0xba, 0x01, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x03, 0x12, 0x04, - 0xba, 0x01, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x01, 0x12, 0x04, 0xbb, 0x01, - 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x05, 0x12, 0x04, 0xbb, 0x01, 0x02, - 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xbb, 0x01, 0x09, 0x18, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xbb, 0x01, 0x1b, 0x1c, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x12, 0x04, 0xbb, 0x01, 0x1d, 0x31, 0x0a, 0x0e, - 0x0a, 0x06, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x06, 0x12, 0x04, 0xbb, 0x01, 0x1e, 0x30, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x02, 0x12, 0x04, 0xbc, 0x01, 0x02, 0x31, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0c, 0x02, 0x02, 0x05, 0x12, 0x04, 0xbc, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0c, 0x02, 0x02, 0x01, 0x12, 0x04, 0xbc, 0x01, 0x09, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, - 0x02, 0x02, 0x03, 0x12, 0x04, 0xbc, 0x01, 0x1a, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, - 0x02, 0x08, 0x12, 0x04, 0xbc, 0x01, 0x1c, 0x30, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0c, 0x02, 0x02, - 0x08, 0x06, 0x12, 0x04, 0xbc, 0x01, 0x1d, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x03, - 0x12, 0x04, 0xbd, 0x01, 0x02, 0x31, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x05, 0x12, - 0x04, 0xbd, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x01, 0x12, 0x04, - 0xbd, 0x01, 0x09, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x03, 0x12, 0x04, 0xbd, - 0x01, 0x1a, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x08, 0x12, 0x04, 0xbd, 0x01, - 0x1c, 0x30, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0c, 0x02, 0x03, 0x08, 0x06, 0x12, 0x04, 0xbd, 0x01, - 0x1d, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x04, 0x12, 0x04, 0xbe, 0x01, 0x02, 0x3f, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x06, 0x12, 0x04, 0xbe, 0x01, 0x02, 0x20, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x01, 0x12, 0x04, 0xbe, 0x01, 0x21, 0x3a, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x03, 0x12, 0x04, 0xbe, 0x01, 0x3d, 0x3e, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x0c, 0x02, 0x05, 0x12, 0x04, 0xbf, 0x01, 0x02, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0c, 0x02, 0x05, 0x06, 0x12, 0x04, 0xbf, 0x01, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, - 0x02, 0x05, 0x01, 0x12, 0x04, 0xbf, 0x01, 0x15, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, - 0x05, 0x03, 0x12, 0x04, 0xbf, 0x01, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x06, - 0x12, 0x04, 0xc0, 0x01, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, 0x06, 0x12, - 0x04, 0xc0, 0x01, 0x02, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, 0x01, 0x12, 0x04, - 0xc0, 0x01, 0x0c, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, 0x03, 0x12, 0x04, 0xc0, - 0x01, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0d, 0x12, 0x06, 0xc3, 0x01, 0x00, 0xcf, 0x01, - 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0d, 0x01, 0x12, 0x04, 0xc3, 0x01, 0x08, 0x10, 0x0a, 0x0e, - 0x0a, 0x04, 0x04, 0x0d, 0x04, 0x00, 0x12, 0x06, 0xc4, 0x01, 0x02, 0xc8, 0x01, 0x03, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x0d, 0x04, 0x00, 0x01, 0x12, 0x04, 0xc4, 0x01, 0x07, 0x13, 0x0a, 0x0e, 0x0a, - 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xc5, 0x01, 0x04, 0x23, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc5, 0x01, 0x04, 0x1e, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xc5, 0x01, 0x21, 0x22, 0x0a, - 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xc6, 0x01, 0x04, 0x28, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc6, 0x01, 0x04, 0x23, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xc6, 0x01, 0x26, - 0x27, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xc7, 0x01, 0x04, - 0x28, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xc7, 0x01, - 0x04, 0x23, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xc7, - 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x00, 0x12, 0x04, 0xca, 0x01, 0x02, - 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x06, 0x12, 0x04, 0xca, 0x01, 0x02, 0x0e, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xca, 0x01, 0x0f, 0x1d, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xca, 0x01, 0x20, 0x21, 0x0a, 0x0e, - 0x0a, 0x04, 0x04, 0x0d, 0x08, 0x00, 0x12, 0x06, 0xcb, 0x01, 0x02, 0xce, 0x01, 0x03, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x0d, 0x08, 0x00, 0x01, 0x12, 0x04, 0xcb, 0x01, 0x08, 0x11, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x0d, 0x02, 0x01, 0x12, 0x04, 0xcc, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0d, 0x02, 0x01, 0x06, 0x12, 0x04, 0xcc, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xcc, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, - 0x01, 0x03, 0x12, 0x04, 0xcc, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x02, - 0x12, 0x04, 0xcd, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x06, 0x12, - 0x04, 0xcd, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x01, 0x12, 0x04, - 0xcd, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x03, 0x12, 0x04, 0xcd, - 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0e, 0x12, 0x06, 0xd1, 0x01, 0x00, 0xd4, 0x01, - 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0e, 0x01, 0x12, 0x04, 0xd1, 0x01, 0x08, 0x16, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x0e, 0x02, 0x00, 0x12, 0x04, 0xd2, 0x01, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd2, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd2, 0x01, 0x09, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, - 0x02, 0x00, 0x03, 0x12, 0x04, 0xd2, 0x01, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0e, 0x02, - 0x01, 0x12, 0x04, 0xd3, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x01, 0x06, - 0x12, 0x04, 0xd3, 0x01, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x01, 0x01, 0x12, - 0x04, 0xd3, 0x01, 0x10, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x01, 0x03, 0x12, 0x04, - 0xd3, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0f, 0x12, 0x06, 0xd6, 0x01, 0x00, 0xd9, - 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0f, 0x01, 0x12, 0x04, 0xd6, 0x01, 0x08, 0x16, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x0f, 0x02, 0x00, 0x12, 0x04, 0xd7, 0x01, 0x02, 0x2f, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x0f, 0x02, 0x00, 0x04, 0x12, 0x04, 0xd7, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x0f, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd7, 0x01, 0x0b, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x0f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd7, 0x01, 0x1a, 0x2a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, - 0x02, 0x00, 0x03, 0x12, 0x04, 0xd7, 0x01, 0x2d, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0f, 0x02, - 0x01, 0x12, 0x04, 0xd8, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, 0x04, - 0x12, 0x04, 0xd8, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, 0x06, 0x12, - 0x04, 0xd8, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, 0x01, 0x12, 0x04, - 0xd8, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, 0x03, 0x12, 0x04, 0xd8, - 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x10, 0x12, 0x06, 0xdb, 0x01, 0x00, 0xf0, 0x01, - 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x10, 0x01, 0x12, 0x04, 0xdb, 0x01, 0x08, 0x16, 0x0a, 0x0e, - 0x0a, 0x04, 0x04, 0x10, 0x04, 0x00, 0x12, 0x06, 0xdc, 0x01, 0x02, 0xe4, 0x01, 0x03, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x10, 0x04, 0x00, 0x01, 0x12, 0x04, 0xdc, 0x01, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, - 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xdd, 0x01, 0x04, 0x19, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xdd, 0x01, 0x04, 0x14, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xdd, 0x01, 0x17, 0x18, 0x0a, - 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xde, 0x01, 0x04, 0x1b, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xde, 0x01, 0x04, 0x16, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xde, 0x01, 0x19, - 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xdf, 0x01, 0x04, - 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xdf, 0x01, - 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xdf, - 0x01, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xe0, - 0x01, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, - 0xe0, 0x01, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, - 0x04, 0xe0, 0x01, 0x1d, 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x04, 0x12, - 0x04, 0xe1, 0x01, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x04, 0x01, - 0x12, 0x04, 0xe1, 0x01, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x04, - 0x02, 0x12, 0x04, 0xe1, 0x01, 0x18, 0x19, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, - 0x05, 0x12, 0x04, 0xe2, 0x01, 0x04, 0x1c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, - 0x05, 0x01, 0x12, 0x04, 0xe2, 0x01, 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, - 0x02, 0x05, 0x02, 0x12, 0x04, 0xe2, 0x01, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, - 0x00, 0x02, 0x06, 0x12, 0x04, 0xe3, 0x01, 0x04, 0x1e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, - 0x00, 0x02, 0x06, 0x01, 0x12, 0x04, 0xe3, 0x01, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, - 0x04, 0x00, 0x02, 0x06, 0x02, 0x12, 0x04, 0xe3, 0x01, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x10, 0x02, 0x00, 0x12, 0x04, 0xe6, 0x01, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, - 0x00, 0x06, 0x12, 0x04, 0xe6, 0x01, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x00, - 0x01, 0x12, 0x04, 0xe6, 0x01, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x00, 0x03, - 0x12, 0x04, 0xe6, 0x01, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x10, 0x08, 0x00, 0x12, 0x06, - 0xe8, 0x01, 0x02, 0xef, 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x08, 0x00, 0x01, 0x12, - 0x04, 0xe8, 0x01, 0x08, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x01, 0x12, 0x04, 0xe9, - 0x01, 0x04, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x06, 0x12, 0x04, 0xe9, 0x01, - 0x04, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe9, 0x01, 0x11, - 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x03, 0x12, 0x04, 0xe9, 0x01, 0x21, 0x22, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x02, 0x12, 0x04, 0xea, 0x01, 0x04, 0x27, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x06, 0x12, 0x04, 0xea, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x10, 0x02, 0x02, 0x01, 0x12, 0x04, 0xea, 0x01, 0x13, 0x22, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x10, 0x02, 0x02, 0x03, 0x12, 0x04, 0xea, 0x01, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x10, 0x02, 0x03, 0x12, 0x04, 0xeb, 0x01, 0x04, 0x2a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, - 0x03, 0x06, 0x12, 0x04, 0xeb, 0x01, 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x03, - 0x01, 0x12, 0x04, 0xeb, 0x01, 0x14, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x03, 0x03, - 0x12, 0x04, 0xeb, 0x01, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x04, 0x12, 0x04, - 0xec, 0x01, 0x04, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x06, 0x12, 0x04, 0xec, - 0x01, 0x04, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x01, 0x12, 0x04, 0xec, 0x01, - 0x10, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x03, 0x12, 0x04, 0xec, 0x01, 0x1f, - 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x05, 0x12, 0x04, 0xed, 0x01, 0x04, 0x25, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x06, 0x12, 0x04, 0xed, 0x01, 0x04, 0x11, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x01, 0x12, 0x04, 0xed, 0x01, 0x12, 0x20, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x10, 0x02, 0x05, 0x03, 0x12, 0x04, 0xed, 0x01, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x10, 0x02, 0x06, 0x12, 0x04, 0xee, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, - 0x02, 0x06, 0x06, 0x12, 0x04, 0xee, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, - 0x06, 0x01, 0x12, 0x04, 0xee, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x06, - 0x03, 0x12, 0x04, 0xee, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x11, 0x12, 0x06, 0xf2, - 0x01, 0x00, 0xf6, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x11, 0x01, 0x12, 0x04, 0xf2, 0x01, - 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x11, 0x02, 0x00, 0x12, 0x04, 0xf3, 0x01, 0x02, 0x15, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf3, 0x01, 0x02, 0x08, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf3, 0x01, 0x09, 0x10, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf3, 0x01, 0x13, 0x14, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x11, 0x02, 0x01, 0x12, 0x04, 0xf4, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x11, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf4, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xf4, 0x01, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, - 0x01, 0x03, 0x12, 0x04, 0xf4, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x11, 0x02, 0x02, - 0x12, 0x04, 0xf5, 0x01, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, 0x06, 0x12, - 0x04, 0xf5, 0x01, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, 0x01, 0x12, 0x04, - 0xf5, 0x01, 0x0f, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, 0x03, 0x12, 0x04, 0xf5, - 0x01, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x12, 0x12, 0x06, 0xf8, 0x01, 0x00, 0xfd, 0x01, - 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x12, 0x01, 0x12, 0x04, 0xf8, 0x01, 0x08, 0x16, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x12, 0x02, 0x00, 0x12, 0x04, 0xf9, 0x01, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x12, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf9, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x12, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf9, 0x01, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, - 0x02, 0x00, 0x03, 0x12, 0x04, 0xf9, 0x01, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, - 0x01, 0x12, 0x04, 0xfa, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x01, 0x05, - 0x12, 0x04, 0xfa, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x01, 0x01, 0x12, - 0x04, 0xfa, 0x01, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x01, 0x03, 0x12, 0x04, - 0xfa, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x02, 0x12, 0x04, 0xfb, 0x01, - 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x06, 0x12, 0x04, 0xfb, 0x01, 0x02, - 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x01, 0x12, 0x04, 0xfb, 0x01, 0x10, 0x14, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x03, 0x12, 0x04, 0xfb, 0x01, 0x17, 0x18, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x03, 0x12, 0x04, 0xfc, 0x01, 0x02, 0x16, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x12, 0x02, 0x03, 0x05, 0x12, 0x04, 0xfc, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x12, 0x02, 0x03, 0x01, 0x12, 0x04, 0xfc, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x12, 0x02, 0x03, 0x03, 0x12, 0x04, 0xfc, 0x01, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x13, - 0x12, 0x06, 0xff, 0x01, 0x00, 0x84, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x13, 0x01, 0x12, - 0x04, 0xff, 0x01, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x00, 0x12, 0x04, 0x80, - 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x05, 0x12, 0x04, 0x80, 0x02, - 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x01, 0x12, 0x04, 0x80, 0x02, 0x08, - 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x03, 0x12, 0x04, 0x80, 0x02, 0x19, 0x1a, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x01, 0x12, 0x04, 0x81, 0x02, 0x02, 0x14, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x13, 0x02, 0x01, 0x05, 0x12, 0x04, 0x81, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x13, 0x02, 0x01, 0x01, 0x12, 0x04, 0x81, 0x02, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x13, 0x02, 0x01, 0x03, 0x12, 0x04, 0x81, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x13, 0x02, 0x02, 0x12, 0x04, 0x82, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, - 0x02, 0x05, 0x12, 0x04, 0x82, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x02, - 0x01, 0x12, 0x04, 0x82, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x02, 0x03, - 0x12, 0x04, 0x82, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x03, 0x12, 0x04, - 0x83, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x06, 0x12, 0x04, 0x83, - 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x01, 0x12, 0x04, 0x83, 0x02, - 0x12, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x03, 0x12, 0x04, 0x83, 0x02, 0x19, - 0x1a, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x14, 0x12, 0x06, 0x86, 0x02, 0x00, 0x89, 0x02, 0x01, 0x0a, - 0x0b, 0x0a, 0x03, 0x04, 0x14, 0x01, 0x12, 0x04, 0x86, 0x02, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x14, 0x02, 0x00, 0x12, 0x04, 0x87, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, - 0x02, 0x00, 0x05, 0x12, 0x04, 0x87, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, - 0x00, 0x01, 0x12, 0x04, 0x87, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x00, - 0x03, 0x12, 0x04, 0x87, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x14, 0x02, 0x01, 0x12, - 0x04, 0x88, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x05, 0x12, 0x04, - 0x88, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x01, 0x12, 0x04, 0x88, - 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x03, 0x12, 0x04, 0x88, 0x02, - 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x15, 0x12, 0x06, 0x8b, 0x02, 0x00, 0x8f, 0x02, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x15, 0x01, 0x12, 0x04, 0x8b, 0x02, 0x08, 0x13, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x15, 0x02, 0x00, 0x12, 0x04, 0x8c, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x15, 0x02, 0x00, 0x05, 0x12, 0x04, 0x8c, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, - 0x02, 0x00, 0x01, 0x12, 0x04, 0x8c, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, - 0x00, 0x03, 0x12, 0x04, 0x8c, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x01, - 0x12, 0x04, 0x8d, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x05, 0x12, - 0x04, 0x8d, 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x01, 0x12, 0x04, - 0x8d, 0x02, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x03, 0x12, 0x04, 0x8d, - 0x02, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x02, 0x12, 0x04, 0x8e, 0x02, 0x02, - 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x06, 0x12, 0x04, 0x8e, 0x02, 0x02, 0x14, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x01, 0x12, 0x04, 0x8e, 0x02, 0x15, 0x19, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x03, 0x12, 0x04, 0x8e, 0x02, 0x1c, 0x1d, 0x0a, 0x0c, - 0x0a, 0x02, 0x04, 0x16, 0x12, 0x06, 0x91, 0x02, 0x00, 0x97, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, - 0x04, 0x16, 0x01, 0x12, 0x04, 0x91, 0x02, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, - 0x00, 0x12, 0x04, 0x92, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x00, 0x05, - 0x12, 0x04, 0x92, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x00, 0x01, 0x12, - 0x04, 0x92, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x00, 0x03, 0x12, 0x04, - 0x92, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x01, 0x12, 0x04, 0x93, 0x02, - 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x05, 0x12, 0x04, 0x93, 0x02, 0x02, - 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x01, 0x12, 0x04, 0x93, 0x02, 0x08, 0x16, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x03, 0x12, 0x04, 0x93, 0x02, 0x19, 0x1a, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x02, 0x12, 0x04, 0x94, 0x02, 0x02, 0x19, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x16, 0x02, 0x02, 0x06, 0x12, 0x04, 0x94, 0x02, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x16, 0x02, 0x02, 0x01, 0x12, 0x04, 0x94, 0x02, 0x10, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x16, 0x02, 0x02, 0x03, 0x12, 0x04, 0x94, 0x02, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, - 0x02, 0x03, 0x12, 0x04, 0x95, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x03, - 0x05, 0x12, 0x04, 0x95, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x03, 0x01, - 0x12, 0x04, 0x95, 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x03, 0x03, 0x12, - 0x04, 0x95, 0x02, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x04, 0x12, 0x04, 0x96, - 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x05, 0x12, 0x04, 0x96, 0x02, - 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x01, 0x12, 0x04, 0x96, 0x02, 0x09, - 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x03, 0x12, 0x04, 0x96, 0x02, 0x10, 0x11, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x17, 0x12, 0x06, 0x99, 0x02, 0x00, 0x9e, 0x02, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x17, 0x01, 0x12, 0x04, 0x99, 0x02, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x17, 0x02, 0x00, 0x12, 0x04, 0x9a, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, - 0x00, 0x05, 0x12, 0x04, 0x9a, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x00, - 0x01, 0x12, 0x04, 0x9a, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x00, 0x03, - 0x12, 0x04, 0x9a, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x17, 0x02, 0x01, 0x12, 0x04, - 0x9b, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x05, 0x12, 0x04, 0x9b, - 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x01, 0x12, 0x04, 0x9b, 0x02, - 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x03, 0x12, 0x04, 0x9b, 0x02, 0x14, - 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x17, 0x02, 0x02, 0x12, 0x04, 0x9c, 0x02, 0x02, 0x13, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x05, 0x12, 0x04, 0x9c, 0x02, 0x02, 0x08, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x01, 0x12, 0x04, 0x9c, 0x02, 0x09, 0x0e, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x17, 0x02, 0x02, 0x03, 0x12, 0x04, 0x9c, 0x02, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x17, 0x02, 0x03, 0x12, 0x04, 0x9d, 0x02, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, - 0x02, 0x03, 0x05, 0x12, 0x04, 0x9d, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, - 0x03, 0x01, 0x12, 0x04, 0x9d, 0x02, 0x09, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x03, - 0x03, 0x12, 0x04, 0x9d, 0x02, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x18, 0x12, 0x06, 0xa0, - 0x02, 0x00, 0xa5, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x18, 0x01, 0x12, 0x04, 0xa0, 0x02, - 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x00, 0x12, 0x04, 0xa1, 0x02, 0x02, 0x1b, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa1, 0x02, 0x02, 0x07, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa1, 0x02, 0x08, 0x16, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa1, 0x02, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x18, 0x02, 0x01, 0x12, 0x04, 0xa2, 0x02, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x18, 0x02, 0x01, 0x05, 0x12, 0x04, 0xa2, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xa2, 0x02, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, - 0x01, 0x03, 0x12, 0x04, 0xa2, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x02, - 0x12, 0x04, 0xa3, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, 0x05, 0x12, - 0x04, 0xa3, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, 0x01, 0x12, 0x04, - 0xa3, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, 0x03, 0x12, 0x04, 0xa3, - 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x03, 0x12, 0x04, 0xa4, 0x02, 0x02, - 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x06, 0x12, 0x04, 0xa4, 0x02, 0x02, 0x10, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa4, 0x02, 0x11, 0x15, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x03, 0x12, 0x04, 0xa4, 0x02, 0x18, 0x19, 0x0a, 0x0c, - 0x0a, 0x02, 0x04, 0x19, 0x12, 0x06, 0xa7, 0x02, 0x00, 0xba, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, - 0x04, 0x19, 0x01, 0x12, 0x04, 0xa7, 0x02, 0x08, 0x1a, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x19, 0x04, - 0x00, 0x12, 0x06, 0xa8, 0x02, 0x02, 0xaf, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x04, - 0x00, 0x01, 0x12, 0x04, 0xa8, 0x02, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, - 0x02, 0x00, 0x12, 0x04, 0xa9, 0x02, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xa9, 0x02, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, - 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xa9, 0x02, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, - 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xaa, 0x02, 0x04, 0x24, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, - 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xaa, 0x02, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x19, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xaa, 0x02, 0x22, 0x23, 0x0a, 0x0e, 0x0a, 0x06, - 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xab, 0x02, 0x04, 0x1c, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xab, 0x02, 0x04, 0x17, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xab, 0x02, 0x1a, 0x1b, 0x0a, 0x0e, - 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xac, 0x02, 0x04, 0x1f, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xac, 0x02, 0x04, 0x1a, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xac, 0x02, 0x1d, 0x1e, - 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0xad, 0x02, 0x04, 0x1e, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xad, 0x02, 0x04, - 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0xad, 0x02, - 0x1c, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x04, 0x00, 0x04, 0x12, 0x04, 0xae, 0x02, 0x04, - 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x04, 0x00, 0x12, 0x04, 0xae, 0x02, 0x0d, - 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x04, 0x00, 0x01, 0x12, 0x04, 0xae, 0x02, - 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x04, 0x00, 0x02, 0x12, 0x04, 0xae, - 0x02, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x00, 0x12, 0x04, 0xb1, 0x02, 0x02, - 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x00, 0x06, 0x12, 0x04, 0xb1, 0x02, 0x02, 0x06, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb1, 0x02, 0x07, 0x0b, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb1, 0x02, 0x0e, 0x0f, 0x0a, 0x0e, - 0x0a, 0x04, 0x04, 0x19, 0x08, 0x00, 0x12, 0x06, 0xb3, 0x02, 0x02, 0xb8, 0x02, 0x03, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x19, 0x08, 0x00, 0x01, 0x12, 0x04, 0xb3, 0x02, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x19, 0x02, 0x01, 0x12, 0x04, 0xb4, 0x02, 0x04, 0x34, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x19, 0x02, 0x01, 0x06, 0x12, 0x04, 0xb4, 0x02, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xb4, 0x02, 0x19, 0x2f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, - 0x01, 0x03, 0x12, 0x04, 0xb4, 0x02, 0x32, 0x33, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x02, - 0x12, 0x04, 0xb5, 0x02, 0x04, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x02, 0x06, 0x12, - 0x04, 0xb5, 0x02, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x02, 0x01, 0x12, 0x04, - 0xb5, 0x02, 0x12, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x02, 0x03, 0x12, 0x04, 0xb5, - 0x02, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x03, 0x12, 0x04, 0xb6, 0x02, 0x04, - 0x2a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x03, 0x06, 0x12, 0x04, 0xb6, 0x02, 0x04, 0x13, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x03, 0x01, 0x12, 0x04, 0xb6, 0x02, 0x14, 0x25, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x03, 0x03, 0x12, 0x04, 0xb6, 0x02, 0x28, 0x29, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x19, 0x02, 0x04, 0x12, 0x04, 0xb7, 0x02, 0x04, 0x29, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x19, 0x02, 0x04, 0x06, 0x12, 0x04, 0xb7, 0x02, 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x19, 0x02, 0x04, 0x01, 0x12, 0x04, 0xb7, 0x02, 0x14, 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, - 0x02, 0x04, 0x03, 0x12, 0x04, 0xb7, 0x02, 0x27, 0x28, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x19, 0x09, - 0x12, 0x04, 0xb9, 0x02, 0x02, 0x0d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x09, 0x00, 0x12, 0x04, - 0xb9, 0x02, 0x0b, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x09, 0x00, 0x01, 0x12, 0x04, 0xb9, - 0x02, 0x0b, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x09, 0x00, 0x02, 0x12, 0x04, 0xb9, 0x02, - 0x0b, 0x0c, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1a, 0x12, 0x06, 0xbc, 0x02, 0x00, 0xc1, 0x02, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1a, 0x01, 0x12, 0x04, 0xbc, 0x02, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x1a, 0x02, 0x00, 0x12, 0x04, 0xbd, 0x02, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1a, 0x02, 0x00, 0x06, 0x12, 0x04, 0xbd, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xbd, 0x02, 0x12, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xbd, 0x02, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1a, 0x02, 0x01, - 0x12, 0x04, 0xbe, 0x02, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x04, 0x12, - 0x04, 0xbe, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x06, 0x12, 0x04, - 0xbe, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x01, 0x12, 0x04, 0xbe, - 0x02, 0x14, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x03, 0x12, 0x04, 0xbe, 0x02, - 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1a, 0x02, 0x02, 0x12, 0x04, 0xbf, 0x02, 0x02, 0x20, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x02, 0x04, 0x12, 0x04, 0xbf, 0x02, 0x02, 0x0a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x02, 0x05, 0x12, 0x04, 0xbf, 0x02, 0x0b, 0x11, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x02, 0x01, 0x12, 0x04, 0xbf, 0x02, 0x12, 0x1b, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x1a, 0x02, 0x02, 0x03, 0x12, 0x04, 0xbf, 0x02, 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x1a, 0x02, 0x03, 0x12, 0x04, 0xc0, 0x02, 0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, - 0x02, 0x03, 0x05, 0x12, 0x04, 0xc0, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, - 0x03, 0x01, 0x12, 0x04, 0xc0, 0x02, 0x09, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x03, - 0x03, 0x12, 0x04, 0xc0, 0x02, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1b, 0x12, 0x06, 0xc3, - 0x02, 0x00, 0xc6, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1b, 0x01, 0x12, 0x04, 0xc3, 0x02, - 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1b, 0x02, 0x00, 0x12, 0x04, 0xc4, 0x02, 0x02, 0x15, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x00, 0x05, 0x12, 0x04, 0xc4, 0x02, 0x02, 0x07, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc4, 0x02, 0x08, 0x10, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc4, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x1b, 0x02, 0x01, 0x12, 0x04, 0xc5, 0x02, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1b, 0x02, 0x01, 0x06, 0x12, 0x04, 0xc5, 0x02, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xc5, 0x02, 0x0f, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, - 0x01, 0x03, 0x12, 0x04, 0xc5, 0x02, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1c, 0x12, 0x06, - 0xc8, 0x02, 0x00, 0xcc, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1c, 0x01, 0x12, 0x04, 0xc8, - 0x02, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1c, 0x02, 0x00, 0x12, 0x04, 0xc9, 0x02, 0x02, - 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x06, 0x12, 0x04, 0xc9, 0x02, 0x02, 0x14, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc9, 0x02, 0x15, 0x19, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc9, 0x02, 0x1c, 0x1d, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x1c, 0x02, 0x01, 0x12, 0x04, 0xca, 0x02, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x1c, 0x02, 0x01, 0x04, 0x12, 0x04, 0xca, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1c, 0x02, 0x01, 0x06, 0x12, 0x04, 0xca, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xca, 0x02, 0x14, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, - 0x01, 0x03, 0x12, 0x04, 0xca, 0x02, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1c, 0x02, 0x02, - 0x12, 0x04, 0xcb, 0x02, 0x02, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x02, 0x04, 0x12, - 0x04, 0xcb, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x02, 0x05, 0x12, 0x04, - 0xcb, 0x02, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x02, 0x01, 0x12, 0x04, 0xcb, - 0x02, 0x12, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x02, 0x03, 0x12, 0x04, 0xcb, 0x02, - 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1d, 0x12, 0x06, 0xce, 0x02, 0x00, 0xd1, 0x02, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1d, 0x01, 0x12, 0x04, 0xce, 0x02, 0x08, 0x17, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x1d, 0x02, 0x00, 0x12, 0x04, 0xcf, 0x02, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1d, 0x02, 0x00, 0x05, 0x12, 0x04, 0xcf, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xcf, 0x02, 0x09, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xcf, 0x02, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1d, 0x02, 0x01, - 0x12, 0x04, 0xd0, 0x02, 0x02, 0x3e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, 0x04, 0x12, - 0x04, 0xd0, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, 0x06, 0x12, 0x04, - 0xd0, 0x02, 0x0b, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd0, - 0x02, 0x26, 0x39, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, 0x03, 0x12, 0x04, 0xd0, 0x02, - 0x3c, 0x3d, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1e, 0x12, 0x06, 0xd3, 0x02, 0x00, 0xde, 0x02, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1e, 0x01, 0x12, 0x04, 0xd3, 0x02, 0x08, 0x22, 0x0a, 0x0e, 0x0a, - 0x04, 0x04, 0x1e, 0x04, 0x00, 0x12, 0x06, 0xd4, 0x02, 0x02, 0xd7, 0x02, 0x03, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x1e, 0x04, 0x00, 0x01, 0x12, 0x04, 0xd4, 0x02, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, - 0x04, 0x1e, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xd5, 0x02, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x1e, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd5, 0x02, 0x04, 0x14, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xd5, 0x02, 0x17, 0x18, 0x0a, 0x0e, - 0x0a, 0x06, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xd6, 0x02, 0x04, 0x24, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd6, 0x02, 0x04, 0x1f, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xd6, 0x02, 0x22, 0x23, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1e, 0x02, 0x00, 0x12, 0x04, 0xd9, 0x02, 0x02, 0x10, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd9, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x1e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd9, 0x02, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x1e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd9, 0x02, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, - 0x1e, 0x08, 0x00, 0x12, 0x06, 0xdb, 0x02, 0x02, 0xdd, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x1e, 0x08, 0x00, 0x01, 0x12, 0x04, 0xdb, 0x02, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1e, - 0x02, 0x01, 0x12, 0x04, 0xdc, 0x02, 0x04, 0x34, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, - 0x06, 0x12, 0x04, 0xdc, 0x02, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, 0x01, - 0x12, 0x04, 0xdc, 0x02, 0x19, 0x2f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, 0x03, 0x12, - 0x04, 0xdc, 0x02, 0x32, 0x33, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1f, 0x12, 0x06, 0xe0, 0x02, 0x00, - 0xe3, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1f, 0x01, 0x12, 0x04, 0xe0, 0x02, 0x08, 0x1a, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1f, 0x02, 0x00, 0x12, 0x04, 0xe1, 0x02, 0x02, 0x15, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x00, 0x05, 0x12, 0x04, 0xe1, 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x1f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe1, 0x02, 0x08, 0x10, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x1f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe1, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x1f, 0x02, 0x01, 0x12, 0x04, 0xe2, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, - 0x01, 0x06, 0x12, 0x04, 0xe2, 0x02, 0x02, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x01, - 0x01, 0x12, 0x04, 0xe2, 0x02, 0x0d, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x01, 0x03, - 0x12, 0x04, 0xe2, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x20, 0x12, 0x06, 0xe5, 0x02, - 0x00, 0xeb, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x20, 0x01, 0x12, 0x04, 0xe5, 0x02, 0x08, - 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x20, 0x02, 0x00, 0x12, 0x04, 0xe6, 0x02, 0x02, 0x15, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x00, 0x05, 0x12, 0x04, 0xe6, 0x02, 0x02, 0x08, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x20, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe6, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x20, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe6, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x20, 0x02, 0x01, 0x12, 0x04, 0xe7, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, - 0x02, 0x01, 0x05, 0x12, 0x04, 0xe7, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, - 0x01, 0x01, 0x12, 0x04, 0xe7, 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x01, - 0x03, 0x12, 0x04, 0xe7, 0x02, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x20, 0x02, 0x02, 0x12, - 0x04, 0xe8, 0x02, 0x02, 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x02, 0x04, 0x12, 0x04, - 0xe8, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x02, 0x06, 0x12, 0x04, 0xe8, - 0x02, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x02, 0x01, 0x12, 0x04, 0xe8, 0x02, - 0x18, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x02, 0x03, 0x12, 0x04, 0xe8, 0x02, 0x22, - 0x23, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x20, 0x02, 0x03, 0x12, 0x04, 0xe9, 0x02, 0x02, 0x2e, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x03, 0x04, 0x12, 0x04, 0xe9, 0x02, 0x02, 0x0a, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x20, 0x02, 0x03, 0x06, 0x12, 0x04, 0xe9, 0x02, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x20, 0x02, 0x03, 0x01, 0x12, 0x04, 0xe9, 0x02, 0x18, 0x29, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x20, 0x02, 0x03, 0x03, 0x12, 0x04, 0xe9, 0x02, 0x2c, 0x2d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x20, 0x02, 0x04, 0x12, 0x04, 0xea, 0x02, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, - 0x04, 0x04, 0x12, 0x04, 0xea, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x04, - 0x06, 0x12, 0x04, 0xea, 0x02, 0x0b, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x04, 0x01, - 0x12, 0x04, 0xea, 0x02, 0x16, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x04, 0x03, 0x12, - 0x04, 0xea, 0x02, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x21, 0x12, 0x06, 0xec, 0x02, 0x00, - 0xf9, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x21, 0x01, 0x12, 0x04, 0xec, 0x02, 0x08, 0x14, - 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x21, 0x04, 0x00, 0x12, 0x06, 0xed, 0x02, 0x02, 0xf2, 0x02, 0x03, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x04, 0x00, 0x01, 0x12, 0x04, 0xed, 0x02, 0x07, 0x11, 0x0a, - 0x0e, 0x0a, 0x06, 0x04, 0x21, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xee, 0x02, 0x04, 0x1f, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xee, 0x02, 0x04, 0x1a, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xee, 0x02, 0x1d, - 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x21, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xef, 0x02, 0x04, - 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xef, 0x02, - 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xef, - 0x02, 0x19, 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x21, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xf0, - 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, - 0xf0, 0x02, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, - 0x04, 0xf0, 0x02, 0x18, 0x19, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x21, 0x04, 0x00, 0x02, 0x03, 0x12, - 0x04, 0xf1, 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x03, 0x01, - 0x12, 0x04, 0xf1, 0x02, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x03, - 0x02, 0x12, 0x04, 0xf1, 0x02, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x00, 0x12, - 0x04, 0xf3, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x05, 0x12, 0x04, - 0xf3, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf3, - 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf3, 0x02, - 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x01, 0x12, 0x04, 0xf4, 0x02, 0x02, 0x29, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x01, 0x06, 0x12, 0x04, 0xf4, 0x02, 0x02, 0x19, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf4, 0x02, 0x1a, 0x24, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x21, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf4, 0x02, 0x27, 0x28, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x21, 0x02, 0x02, 0x12, 0x04, 0xf5, 0x02, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x21, 0x02, 0x02, 0x05, 0x12, 0x04, 0xf5, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, - 0x02, 0x02, 0x01, 0x12, 0x04, 0xf5, 0x02, 0x07, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, - 0x02, 0x03, 0x12, 0x04, 0xf5, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x03, - 0x12, 0x04, 0xf6, 0x02, 0x02, 0x40, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x04, 0x12, - 0x04, 0xf6, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x06, 0x12, 0x04, - 0xf6, 0x02, 0x0b, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x01, 0x12, 0x04, 0xf6, - 0x02, 0x28, 0x3b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x03, 0x12, 0x04, 0xf6, 0x02, - 0x3e, 0x3f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x04, 0x12, 0x04, 0xf7, 0x02, 0x02, 0x1f, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, 0x04, 0x12, 0x04, 0xf7, 0x02, 0x02, 0x0a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, 0x06, 0x12, 0x04, 0xf7, 0x02, 0x0b, 0x13, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, 0x01, 0x12, 0x04, 0xf7, 0x02, 0x14, 0x1a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x21, 0x02, 0x04, 0x03, 0x12, 0x04, 0xf7, 0x02, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x21, 0x02, 0x05, 0x12, 0x04, 0xf8, 0x02, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, - 0x02, 0x05, 0x04, 0x12, 0x04, 0xf8, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, - 0x05, 0x06, 0x12, 0x04, 0xf8, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x05, - 0x01, 0x12, 0x04, 0xf8, 0x02, 0x14, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x05, 0x03, - 0x12, 0x04, 0xf8, 0x02, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x22, 0x12, 0x06, 0xfb, 0x02, - 0x00, 0x82, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x22, 0x01, 0x12, 0x04, 0xfb, 0x02, 0x08, - 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x00, 0x12, 0x04, 0xfc, 0x02, 0x02, 0x12, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x05, 0x12, 0x04, 0xfc, 0x02, 0x02, 0x08, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x01, 0x12, 0x04, 0xfc, 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x22, 0x02, 0x00, 0x03, 0x12, 0x04, 0xfc, 0x02, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x22, 0x02, 0x01, 0x12, 0x04, 0xfd, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, - 0x02, 0x01, 0x05, 0x12, 0x04, 0xfd, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, - 0x01, 0x01, 0x12, 0x04, 0xfd, 0x02, 0x07, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x01, - 0x03, 0x12, 0x04, 0xfd, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x02, 0x12, - 0x04, 0xfe, 0x02, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x02, 0x05, 0x12, 0x04, - 0xfe, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x02, 0x01, 0x12, 0x04, 0xfe, - 0x02, 0x07, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x02, 0x03, 0x12, 0x04, 0xfe, 0x02, - 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x03, 0x12, 0x04, 0xff, 0x02, 0x02, 0x25, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x04, 0x12, 0x04, 0xff, 0x02, 0x02, 0x0a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x06, 0x12, 0x04, 0xff, 0x02, 0x0b, 0x16, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x01, 0x12, 0x04, 0xff, 0x02, 0x17, 0x20, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x22, 0x02, 0x03, 0x03, 0x12, 0x04, 0xff, 0x02, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x22, 0x02, 0x04, 0x12, 0x04, 0x80, 0x03, 0x02, 0x3e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, - 0x02, 0x04, 0x04, 0x12, 0x04, 0x80, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, - 0x04, 0x06, 0x12, 0x04, 0x80, 0x03, 0x0b, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x04, - 0x01, 0x12, 0x04, 0x80, 0x03, 0x26, 0x39, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x04, 0x03, - 0x12, 0x04, 0x80, 0x03, 0x3c, 0x3d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x05, 0x12, 0x04, - 0x81, 0x03, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, 0x04, 0x12, 0x04, 0x81, - 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, 0x06, 0x12, 0x04, 0x81, 0x03, - 0x0b, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, 0x01, 0x12, 0x04, 0x81, 0x03, 0x1b, - 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, 0x03, 0x12, 0x04, 0x81, 0x03, 0x24, 0x25, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x23, 0x12, 0x06, 0x84, 0x03, 0x00, 0x87, 0x03, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x23, 0x01, 0x12, 0x04, 0x84, 0x03, 0x08, 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x23, 0x02, 0x00, 0x12, 0x04, 0x85, 0x03, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, - 0x00, 0x04, 0x12, 0x04, 0x85, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x00, - 0x06, 0x12, 0x04, 0x85, 0x03, 0x0b, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x00, 0x01, - 0x12, 0x04, 0x85, 0x03, 0x17, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x00, 0x03, 0x12, - 0x04, 0x85, 0x03, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x01, 0x12, 0x04, 0x86, - 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x01, 0x05, 0x12, 0x04, 0x86, 0x03, - 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x01, 0x01, 0x12, 0x04, 0x86, 0x03, 0x07, - 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x01, 0x03, 0x12, 0x04, 0x86, 0x03, 0x14, 0x15, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x24, 0x12, 0x06, 0x89, 0x03, 0x00, 0x8c, 0x03, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x24, 0x01, 0x12, 0x04, 0x89, 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x24, 0x02, 0x00, 0x12, 0x04, 0x8a, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, - 0x00, 0x05, 0x12, 0x04, 0x8a, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x00, - 0x01, 0x12, 0x04, 0x8a, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x00, 0x03, - 0x12, 0x04, 0x8a, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x24, 0x02, 0x01, 0x12, 0x04, - 0x8b, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x06, 0x12, 0x04, 0x8b, - 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x01, 0x12, 0x04, 0x8b, 0x03, - 0x0b, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x03, 0x12, 0x04, 0x8b, 0x03, 0x12, - 0x13, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x25, 0x12, 0x06, 0x8e, 0x03, 0x00, 0x90, 0x03, 0x01, 0x0a, - 0x0b, 0x0a, 0x03, 0x04, 0x25, 0x01, 0x12, 0x04, 0x8e, 0x03, 0x08, 0x24, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x25, 0x02, 0x00, 0x12, 0x04, 0x8f, 0x03, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, - 0x02, 0x00, 0x04, 0x12, 0x04, 0x8f, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, - 0x00, 0x06, 0x12, 0x04, 0x8f, 0x03, 0x0b, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x00, - 0x01, 0x12, 0x04, 0x8f, 0x03, 0x17, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, 0x00, 0x03, - 0x12, 0x04, 0x8f, 0x03, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x06, 0x92, 0x03, - 0x00, 0xa2, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x04, 0x92, 0x03, 0x05, - 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x00, 0x12, 0x04, 0x93, 0x03, 0x02, 0x1d, 0x0a, - 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x93, 0x03, 0x02, 0x18, 0x0a, 0x0d, - 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0x93, 0x03, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, - 0x04, 0x05, 0x00, 0x02, 0x01, 0x12, 0x04, 0x94, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x94, 0x03, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, - 0x02, 0x01, 0x02, 0x12, 0x04, 0x94, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, - 0x02, 0x12, 0x04, 0x95, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x02, 0x01, - 0x12, 0x04, 0x95, 0x03, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x02, 0x02, 0x12, - 0x04, 0x95, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x03, 0x12, 0x04, 0x96, - 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0x96, 0x03, - 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0x96, 0x03, 0x13, - 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x04, 0x12, 0x04, 0x97, 0x03, 0x02, 0x16, 0x0a, - 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0x97, 0x03, 0x02, 0x10, 0x0a, 0x0d, - 0x0a, 0x05, 0x05, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0x97, 0x03, 0x13, 0x15, 0x0a, 0x0c, 0x0a, - 0x04, 0x05, 0x00, 0x02, 0x05, 0x12, 0x04, 0x98, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0x98, 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, - 0x02, 0x05, 0x02, 0x12, 0x04, 0x98, 0x03, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, - 0x06, 0x12, 0x04, 0x99, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x06, 0x01, - 0x12, 0x04, 0x99, 0x03, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x06, 0x02, 0x12, - 0x04, 0x99, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x07, 0x12, 0x04, 0x9a, - 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x07, 0x01, 0x12, 0x04, 0x9a, 0x03, - 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x07, 0x02, 0x12, 0x04, 0x9a, 0x03, 0x14, - 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x08, 0x12, 0x04, 0x9b, 0x03, 0x02, 0x19, 0x0a, - 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x08, 0x01, 0x12, 0x04, 0x9b, 0x03, 0x02, 0x14, 0x0a, 0x0d, - 0x0a, 0x05, 0x05, 0x00, 0x02, 0x08, 0x02, 0x12, 0x04, 0x9b, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, - 0x04, 0x05, 0x00, 0x02, 0x09, 0x12, 0x04, 0x9c, 0x03, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x09, 0x01, 0x12, 0x04, 0x9c, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, - 0x02, 0x09, 0x02, 0x12, 0x04, 0x9c, 0x03, 0x16, 0x17, 0x0a, 0x2b, 0x0a, 0x04, 0x05, 0x00, 0x02, - 0x0a, 0x12, 0x04, 0x9d, 0x03, 0x02, 0x18, 0x22, 0x1d, 0x20, 0x60, 0x7b, 0x20, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x3a, 0x20, 0x42, 0x6f, 0x78, 0x3c, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x3e, 0x20, 0x7d, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0a, 0x01, 0x12, - 0x04, 0x9d, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0a, 0x02, 0x12, 0x04, - 0x9d, 0x03, 0x16, 0x17, 0x0a, 0x22, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0b, 0x12, 0x04, 0x9e, 0x03, - 0x02, 0x18, 0x22, 0x14, 0x20, 0x60, 0x28, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x54, 0x61, 0x67, 0x29, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0b, - 0x01, 0x12, 0x04, 0x9e, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0b, 0x02, - 0x12, 0x04, 0x9e, 0x03, 0x16, 0x17, 0x0a, 0x22, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0c, 0x12, 0x04, - 0x9f, 0x03, 0x02, 0x24, 0x22, 0x14, 0x20, 0x60, 0x7b, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, - 0x20, 0x75, 0x31, 0x36, 0x20, 0x7d, 0x60, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, - 0x02, 0x0c, 0x01, 0x12, 0x04, 0x9f, 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, - 0x0c, 0x02, 0x12, 0x04, 0x9f, 0x03, 0x22, 0x23, 0x0a, 0x37, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0d, - 0x12, 0x04, 0xa0, 0x03, 0x02, 0x1c, 0x22, 0x29, 0x20, 0x60, 0x7b, 0x20, 0x6d, 0x75, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x2c, 0x20, 0x74, 0x6f, 0x3a, 0x20, 0x42, - 0x6f, 0x78, 0x3c, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3e, 0x20, 0x7d, 0x60, 0x2c, - 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0d, 0x01, 0x12, 0x04, 0xa0, 0x03, 0x02, 0x16, - 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0d, 0x02, 0x12, 0x04, 0xa0, 0x03, 0x19, 0x1b, 0x0a, - 0x1b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0e, 0x12, 0x04, 0xa1, 0x03, 0x02, 0x1d, 0x22, 0x0d, 0x20, - 0x60, 0x28, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x29, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, - 0x05, 0x00, 0x02, 0x0e, 0x01, 0x12, 0x04, 0xa1, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x0e, 0x02, 0x12, 0x04, 0xa1, 0x03, 0x1a, 0x1c, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x26, - 0x12, 0x06, 0xa4, 0x03, 0x00, 0xb2, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x26, 0x01, 0x12, - 0x04, 0xa4, 0x03, 0x08, 0x10, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x26, 0x03, 0x00, 0x12, 0x06, 0xa5, - 0x03, 0x02, 0xa8, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x03, 0x00, 0x01, 0x12, 0x04, - 0xa5, 0x03, 0x0a, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x26, 0x03, 0x00, 0x02, 0x00, 0x12, 0x04, - 0xa6, 0x03, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, - 0x04, 0xa6, 0x03, 0x04, 0x08, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, 0x00, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xa6, 0x03, 0x09, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, 0x00, 0x02, 0x00, - 0x03, 0x12, 0x04, 0xa6, 0x03, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x26, 0x03, 0x00, 0x02, - 0x01, 0x12, 0x04, 0xa7, 0x03, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, 0x00, 0x02, - 0x01, 0x06, 0x12, 0x04, 0xa7, 0x03, 0x04, 0x0c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, 0x00, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xa7, 0x03, 0x0d, 0x0f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, - 0x00, 0x02, 0x01, 0x03, 0x12, 0x04, 0xa7, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, - 0x02, 0x00, 0x12, 0x04, 0xaa, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, - 0x06, 0x12, 0x04, 0xaa, 0x03, 0x02, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xaa, 0x03, 0x0c, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xaa, 0x03, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x26, 0x08, 0x00, 0x12, 0x06, 0xab, - 0x03, 0x02, 0xb1, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x08, 0x00, 0x01, 0x12, 0x04, - 0xab, 0x03, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, 0x02, 0x01, 0x12, 0x04, 0xac, 0x03, - 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x01, 0x06, 0x12, 0x04, 0xac, 0x03, 0x04, - 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x01, 0x01, 0x12, 0x04, 0xac, 0x03, 0x0d, 0x13, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x01, 0x03, 0x12, 0x04, 0xac, 0x03, 0x16, 0x17, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x26, 0x02, 0x02, 0x12, 0x04, 0xad, 0x03, 0x04, 0x1d, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x26, 0x02, 0x02, 0x06, 0x12, 0x04, 0xad, 0x03, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x26, 0x02, 0x02, 0x01, 0x12, 0x04, 0xad, 0x03, 0x12, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x26, 0x02, 0x02, 0x03, 0x12, 0x04, 0xad, 0x03, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, - 0x02, 0x03, 0x12, 0x04, 0xae, 0x03, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x03, - 0x05, 0x12, 0x04, 0xae, 0x03, 0x04, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x03, 0x01, - 0x12, 0x04, 0xae, 0x03, 0x0b, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x03, 0x03, 0x12, - 0x04, 0xae, 0x03, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, 0x02, 0x04, 0x12, 0x04, 0xaf, - 0x03, 0x04, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x04, 0x06, 0x12, 0x04, 0xaf, 0x03, - 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x04, 0x01, 0x12, 0x04, 0xaf, 0x03, 0x12, - 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x04, 0x03, 0x12, 0x04, 0xaf, 0x03, 0x1e, 0x1f, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, 0x02, 0x05, 0x12, 0x04, 0xb0, 0x03, 0x04, 0x1a, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x26, 0x02, 0x05, 0x05, 0x12, 0x04, 0xb0, 0x03, 0x04, 0x0a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x26, 0x02, 0x05, 0x01, 0x12, 0x04, 0xb0, 0x03, 0x0b, 0x15, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x26, 0x02, 0x05, 0x03, 0x12, 0x04, 0xb0, 0x03, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x05, - 0x01, 0x12, 0x06, 0xb4, 0x03, 0x00, 0xba, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x05, 0x01, 0x01, - 0x12, 0x04, 0xb4, 0x03, 0x05, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x00, 0x12, 0x04, - 0xb5, 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb5, - 0x03, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x00, 0x02, 0x12, 0x04, 0xb5, 0x03, - 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x01, 0x12, 0x04, 0xb6, 0x03, 0x02, 0x18, - 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb6, 0x03, 0x02, 0x13, 0x0a, - 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x01, 0x02, 0x12, 0x04, 0xb6, 0x03, 0x16, 0x17, 0x0a, 0x0c, - 0x0a, 0x04, 0x05, 0x01, 0x02, 0x02, 0x12, 0x04, 0xb7, 0x03, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, - 0x05, 0x01, 0x02, 0x02, 0x01, 0x12, 0x04, 0xb7, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, - 0x01, 0x02, 0x02, 0x02, 0x12, 0x04, 0xb7, 0x03, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, - 0x02, 0x03, 0x12, 0x04, 0xb8, 0x03, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x03, - 0x01, 0x12, 0x04, 0xb8, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x03, 0x02, - 0x12, 0x04, 0xb8, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x04, 0x12, 0x04, - 0xb9, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x04, 0x01, 0x12, 0x04, 0xb9, - 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x04, 0x02, 0x12, 0x04, 0xb9, 0x03, - 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x27, 0x12, 0x06, 0xbc, 0x03, 0x00, 0xbe, 0x03, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x27, 0x01, 0x12, 0x04, 0xbc, 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x27, 0x02, 0x00, 0x12, 0x04, 0xbd, 0x03, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x27, 0x02, 0x00, 0x06, 0x12, 0x04, 0xbd, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xbd, 0x03, 0x0b, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x27, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xbd, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x28, 0x12, 0x06, - 0xc0, 0x03, 0x00, 0xc3, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x28, 0x01, 0x12, 0x04, 0xc0, - 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x28, 0x02, 0x00, 0x12, 0x04, 0xc1, 0x03, 0x02, - 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, 0x00, 0x06, 0x12, 0x04, 0xc1, 0x03, 0x02, 0x0e, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc1, 0x03, 0x0f, 0x15, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc1, 0x03, 0x18, 0x19, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x28, 0x02, 0x01, 0x12, 0x04, 0xc2, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x28, 0x02, 0x01, 0x05, 0x12, 0x04, 0xc2, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x28, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc2, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, - 0x02, 0x01, 0x03, 0x12, 0x04, 0xc2, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x29, 0x12, - 0x06, 0xc5, 0x03, 0x00, 0xc8, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x29, 0x01, 0x12, 0x04, - 0xc5, 0x03, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x29, 0x02, 0x00, 0x12, 0x04, 0xc6, 0x03, - 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x05, 0x12, 0x04, 0xc6, 0x03, 0x02, - 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc6, 0x03, 0x09, 0x10, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc6, 0x03, 0x13, 0x14, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x29, 0x02, 0x01, 0x12, 0x04, 0xc7, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x29, 0x02, 0x01, 0x05, 0x12, 0x04, 0xc7, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x29, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc7, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x29, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc7, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2a, - 0x12, 0x06, 0xca, 0x03, 0x00, 0xcf, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2a, 0x01, 0x12, - 0x04, 0xca, 0x03, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2a, 0x02, 0x00, 0x12, 0x04, 0xcb, - 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xcb, 0x03, - 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xcb, 0x03, 0x09, - 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xcb, 0x03, 0x13, 0x14, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2a, 0x02, 0x01, 0x12, 0x04, 0xcc, 0x03, 0x02, 0x14, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x01, 0x05, 0x12, 0x04, 0xcc, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2a, 0x02, 0x01, 0x01, 0x12, 0x04, 0xcc, 0x03, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2a, 0x02, 0x01, 0x03, 0x12, 0x04, 0xcc, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x2a, 0x02, 0x02, 0x12, 0x04, 0xcd, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, - 0x02, 0x05, 0x12, 0x04, 0xcd, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x02, - 0x01, 0x12, 0x04, 0xcd, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x02, 0x03, - 0x12, 0x04, 0xcd, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2a, 0x02, 0x03, 0x12, 0x04, - 0xce, 0x03, 0x02, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x03, 0x04, 0x12, 0x04, 0xce, - 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x03, 0x06, 0x12, 0x04, 0xce, 0x03, - 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x03, 0x01, 0x12, 0x04, 0xce, 0x03, 0x14, - 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x03, 0x03, 0x12, 0x04, 0xce, 0x03, 0x2a, 0x2b, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2b, 0x12, 0x06, 0xd1, 0x03, 0x00, 0xe5, 0x03, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x2b, 0x01, 0x12, 0x04, 0xd1, 0x03, 0x08, 0x11, 0x0a, 0x0e, 0x0a, 0x04, 0x04, - 0x2b, 0x04, 0x00, 0x12, 0x06, 0xd2, 0x03, 0x02, 0xda, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2b, 0x04, 0x00, 0x01, 0x12, 0x04, 0xd2, 0x03, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, - 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xd3, 0x03, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, - 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd3, 0x03, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x2b, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xd3, 0x03, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, - 0x04, 0x2b, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xd4, 0x03, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x2b, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd4, 0x03, 0x04, 0x10, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xd4, 0x03, 0x13, 0x14, 0x0a, 0x0e, - 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xd5, 0x03, 0x04, 0x1b, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xd5, 0x03, 0x04, 0x16, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xd5, 0x03, 0x19, 0x1a, - 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xd6, 0x03, 0x04, 0x19, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xd6, 0x03, 0x04, - 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xd6, 0x03, - 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0xd7, 0x03, - 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xd7, - 0x03, 0x04, 0x12, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, - 0xd7, 0x03, 0x15, 0x16, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x05, 0x12, 0x04, - 0xd8, 0x03, 0x04, 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, - 0x04, 0xd8, 0x03, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x05, 0x02, - 0x12, 0x04, 0xd8, 0x03, 0x19, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x04, 0x00, 0x04, 0x12, - 0x04, 0xd9, 0x03, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x04, 0x00, 0x12, - 0x04, 0xd9, 0x03, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x04, 0x00, 0x01, - 0x12, 0x04, 0xd9, 0x03, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x04, 0x00, - 0x02, 0x12, 0x04, 0xd9, 0x03, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x00, 0x12, - 0x04, 0xdc, 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x06, 0x12, 0x04, - 0xdc, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x01, 0x12, 0x04, 0xdc, - 0x03, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x03, 0x12, 0x04, 0xdc, 0x03, - 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x2b, 0x08, 0x00, 0x12, 0x06, 0xdd, 0x03, 0x02, 0xe4, - 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x08, 0x00, 0x01, 0x12, 0x04, 0xdd, 0x03, 0x08, - 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x01, 0x12, 0x04, 0xde, 0x03, 0x04, 0x21, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x01, 0x06, 0x12, 0x04, 0xde, 0x03, 0x04, 0x14, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xde, 0x03, 0x15, 0x1c, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xde, 0x03, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x2b, 0x02, 0x02, 0x12, 0x04, 0xdf, 0x03, 0x04, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, - 0x02, 0x02, 0x06, 0x12, 0x04, 0xdf, 0x03, 0x04, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, - 0x02, 0x01, 0x12, 0x04, 0xdf, 0x03, 0x1a, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x02, - 0x03, 0x12, 0x04, 0xdf, 0x03, 0x2a, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x03, 0x12, - 0x04, 0xe0, 0x03, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x06, 0x12, 0x04, - 0xe0, 0x03, 0x04, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x01, 0x12, 0x04, 0xe0, - 0x03, 0x18, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x03, 0x12, 0x04, 0xe0, 0x03, - 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x04, 0x12, 0x04, 0xe1, 0x03, 0x04, 0x24, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x04, 0x06, 0x12, 0x04, 0xe1, 0x03, 0x04, 0x15, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x04, 0x01, 0x12, 0x04, 0xe1, 0x03, 0x16, 0x1f, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x04, 0x03, 0x12, 0x04, 0xe1, 0x03, 0x22, 0x23, 0x0a, 0x1e, 0x0a, - 0x04, 0x04, 0x2b, 0x02, 0x05, 0x12, 0x04, 0xe3, 0x03, 0x04, 0x23, 0x1a, 0x10, 0x20, 0x36, 0x20, - 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2b, 0x02, 0x05, 0x06, 0x12, 0x04, 0xe3, 0x03, 0x04, 0x10, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2b, 0x02, 0x05, 0x01, 0x12, 0x04, 0xe3, 0x03, 0x11, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2b, 0x02, 0x05, 0x03, 0x12, 0x04, 0xe3, 0x03, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2c, - 0x12, 0x06, 0xe7, 0x03, 0x00, 0xea, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2c, 0x01, 0x12, - 0x04, 0xe7, 0x03, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x00, 0x12, 0x04, 0xe8, - 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x05, 0x12, 0x04, 0xe8, 0x03, - 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe8, 0x03, 0x08, - 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe8, 0x03, 0x15, 0x16, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x01, 0x12, 0x04, 0xe9, 0x03, 0x02, 0x16, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x01, 0x05, 0x12, 0x04, 0xe9, 0x03, 0x02, 0x07, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe9, 0x03, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xe9, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, - 0x2d, 0x12, 0x06, 0xec, 0x03, 0x00, 0xf1, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2d, 0x01, - 0x12, 0x04, 0xec, 0x03, 0x08, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x00, 0x12, 0x04, - 0xed, 0x03, 0x02, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x04, 0x12, 0x04, 0xed, - 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x05, 0x12, 0x04, 0xed, 0x03, - 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xed, 0x03, 0x11, - 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xed, 0x03, 0x1f, 0x20, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x01, 0x12, 0x04, 0xee, 0x03, 0x02, 0x20, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x01, 0x04, 0x12, 0x04, 0xee, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2d, 0x02, 0x01, 0x05, 0x12, 0x04, 0xee, 0x03, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xee, 0x03, 0x11, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2d, 0x02, 0x01, 0x03, 0x12, 0x04, 0xee, 0x03, 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, - 0x02, 0x02, 0x12, 0x04, 0xef, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x02, - 0x05, 0x12, 0x04, 0xef, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x02, 0x01, - 0x12, 0x04, 0xef, 0x03, 0x09, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x02, 0x03, 0x12, - 0x04, 0xef, 0x03, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x03, 0x12, 0x04, 0xf0, - 0x03, 0x02, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x03, 0x04, 0x12, 0x04, 0xf0, 0x03, - 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x03, 0x05, 0x12, 0x04, 0xf0, 0x03, 0x0b, - 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x03, 0x01, 0x12, 0x04, 0xf0, 0x03, 0x12, 0x24, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x03, 0x03, 0x12, 0x04, 0xf0, 0x03, 0x27, 0x28, 0x0a, - 0x0c, 0x0a, 0x02, 0x04, 0x2e, 0x12, 0x06, 0xf3, 0x03, 0x00, 0xf7, 0x03, 0x01, 0x0a, 0x0b, 0x0a, - 0x03, 0x04, 0x2e, 0x01, 0x12, 0x04, 0xf3, 0x03, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, - 0x02, 0x00, 0x12, 0x04, 0xf4, 0x03, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, - 0x06, 0x12, 0x04, 0xf4, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xf4, 0x03, 0x13, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xf4, 0x03, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x01, 0x12, 0x04, 0xf5, - 0x03, 0x02, 0x31, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x01, 0x04, 0x12, 0x04, 0xf5, 0x03, - 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf5, 0x03, 0x0b, - 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf5, 0x03, 0x12, 0x2c, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf5, 0x03, 0x2f, 0x30, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x02, 0x12, 0x04, 0xf6, 0x03, 0x02, 0x32, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2e, 0x02, 0x02, 0x04, 0x12, 0x04, 0xf6, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2e, 0x02, 0x02, 0x06, 0x12, 0x04, 0xf6, 0x03, 0x0b, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2e, 0x02, 0x02, 0x01, 0x12, 0x04, 0xf6, 0x03, 0x1c, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, - 0x02, 0x02, 0x03, 0x12, 0x04, 0xf6, 0x03, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2f, 0x12, - 0x06, 0xf9, 0x03, 0x00, 0xff, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2f, 0x01, 0x12, 0x04, - 0xf9, 0x03, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x00, 0x12, 0x04, 0xfa, 0x03, - 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x06, 0x12, 0x04, 0xfa, 0x03, 0x02, - 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xfa, 0x03, 0x13, 0x19, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xfa, 0x03, 0x1c, 0x1d, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x01, 0x12, 0x04, 0xfb, 0x03, 0x02, 0x31, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x2f, 0x02, 0x01, 0x04, 0x12, 0x04, 0xfb, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2f, 0x02, 0x01, 0x05, 0x12, 0x04, 0xfb, 0x03, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2f, 0x02, 0x01, 0x01, 0x12, 0x04, 0xfb, 0x03, 0x12, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, - 0x02, 0x01, 0x03, 0x12, 0x04, 0xfb, 0x03, 0x2f, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, - 0x02, 0x12, 0x04, 0xfc, 0x03, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x02, 0x04, - 0x12, 0x04, 0xfc, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x02, 0x06, 0x12, - 0x04, 0xfc, 0x03, 0x0b, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x02, 0x01, 0x12, 0x04, - 0xfc, 0x03, 0x1c, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x02, 0x03, 0x12, 0x04, 0xfc, - 0x03, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x03, 0x12, 0x04, 0xfd, 0x03, 0x02, - 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x03, 0x05, 0x12, 0x04, 0xfd, 0x03, 0x02, 0x08, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x03, 0x01, 0x12, 0x04, 0xfd, 0x03, 0x09, 0x1a, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x03, 0x03, 0x12, 0x04, 0xfd, 0x03, 0x1d, 0x1e, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x04, 0x12, 0x04, 0xfe, 0x03, 0x02, 0x28, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x2f, 0x02, 0x04, 0x06, 0x12, 0x04, 0xfe, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x2f, 0x02, 0x04, 0x01, 0x12, 0x04, 0xfe, 0x03, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, - 0x02, 0x04, 0x03, 0x12, 0x04, 0xfe, 0x03, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x30, 0x12, - 0x06, 0x81, 0x04, 0x00, 0x8d, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x30, 0x01, 0x12, 0x04, - 0x81, 0x04, 0x08, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x30, 0x04, 0x00, 0x12, 0x06, 0x82, 0x04, - 0x02, 0x89, 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x04, 0x00, 0x01, 0x12, 0x04, 0x82, - 0x04, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x30, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0x83, - 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, - 0x83, 0x04, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, - 0x04, 0x83, 0x04, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x30, 0x04, 0x00, 0x02, 0x01, 0x12, - 0x04, 0x84, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x01, 0x01, - 0x12, 0x04, 0x84, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x01, - 0x02, 0x12, 0x04, 0x84, 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x30, 0x04, 0x00, 0x02, - 0x02, 0x12, 0x04, 0x85, 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, - 0x02, 0x01, 0x12, 0x04, 0x85, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, - 0x02, 0x02, 0x02, 0x12, 0x04, 0x85, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x30, 0x04, - 0x00, 0x02, 0x03, 0x12, 0x04, 0x86, 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, - 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0x86, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, - 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0x86, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, - 0x30, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0x87, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x30, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0x87, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x30, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0x87, 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, - 0x06, 0x04, 0x30, 0x04, 0x00, 0x02, 0x05, 0x12, 0x04, 0x88, 0x04, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0x88, 0x04, 0x04, 0x1a, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x04, 0x88, 0x04, 0x1d, 0x1e, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x30, 0x02, 0x00, 0x12, 0x04, 0x8b, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x30, 0x02, 0x00, 0x06, 0x12, 0x04, 0x8b, 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x30, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8b, 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x30, 0x02, 0x00, 0x03, 0x12, 0x04, 0x8b, 0x04, 0x0e, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x30, - 0x02, 0x01, 0x12, 0x04, 0x8c, 0x04, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x01, - 0x05, 0x12, 0x04, 0x8c, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x01, 0x01, - 0x12, 0x04, 0x8c, 0x04, 0x08, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x01, 0x03, 0x12, - 0x04, 0x8c, 0x04, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x31, 0x12, 0x06, 0x8f, 0x04, 0x00, - 0xa5, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x31, 0x01, 0x12, 0x04, 0x8f, 0x04, 0x08, 0x14, - 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x31, 0x04, 0x00, 0x12, 0x06, 0x90, 0x04, 0x02, 0x96, 0x04, 0x03, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x04, 0x00, 0x01, 0x12, 0x04, 0x90, 0x04, 0x07, 0x0b, 0x0a, - 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0x91, 0x04, 0x04, 0x19, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x91, 0x04, 0x04, 0x14, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0x91, 0x04, 0x17, - 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0x92, 0x04, 0x04, - 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x92, 0x04, - 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0x92, - 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0x93, - 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, - 0x93, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, - 0x04, 0x93, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x03, 0x12, - 0x04, 0x94, 0x04, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x03, 0x01, - 0x12, 0x04, 0x94, 0x04, 0x04, 0x11, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x03, - 0x02, 0x12, 0x04, 0x94, 0x04, 0x14, 0x15, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, - 0x04, 0x12, 0x04, 0x95, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, - 0x04, 0x01, 0x12, 0x04, 0x95, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, - 0x02, 0x04, 0x02, 0x12, 0x04, 0x95, 0x04, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x31, 0x02, - 0x00, 0x12, 0x04, 0x98, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x00, 0x06, - 0x12, 0x04, 0x98, 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x00, 0x01, 0x12, - 0x04, 0x98, 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x00, 0x03, 0x12, 0x04, - 0x98, 0x04, 0x0e, 0x0f, 0x0a, 0x64, 0x0a, 0x04, 0x04, 0x31, 0x02, 0x01, 0x12, 0x04, 0x9c, 0x04, - 0x02, 0x2a, 0x1a, 0x56, 0x20, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x3a, - 0x20, 0x75, 0x73, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, - 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x2e, 0x0a, - 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, - 0x02, 0x01, 0x05, 0x12, 0x04, 0x9c, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, - 0x01, 0x01, 0x12, 0x04, 0x9c, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x01, - 0x03, 0x12, 0x04, 0x9c, 0x04, 0x14, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x01, 0x08, - 0x12, 0x04, 0x9c, 0x04, 0x16, 0x29, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x02, 0x01, 0x08, 0x03, - 0x12, 0x04, 0x9c, 0x04, 0x17, 0x28, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x31, 0x08, 0x00, 0x12, 0x06, - 0x9f, 0x04, 0x02, 0xa4, 0x04, 0x03, 0x1a, 0x13, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x3a, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x31, 0x08, 0x00, 0x01, 0x12, 0x04, 0x9f, 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x31, - 0x02, 0x02, 0x12, 0x04, 0xa0, 0x04, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x02, - 0x06, 0x12, 0x04, 0xa0, 0x04, 0x04, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x02, 0x01, - 0x12, 0x04, 0xa0, 0x04, 0x0c, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x02, 0x03, 0x12, - 0x04, 0xa0, 0x04, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x31, 0x02, 0x03, 0x12, 0x04, 0xa1, - 0x04, 0x04, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x03, 0x06, 0x12, 0x04, 0xa1, 0x04, - 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa1, 0x04, 0x13, - 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x03, 0x03, 0x12, 0x04, 0xa1, 0x04, 0x25, 0x26, - 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x31, 0x02, 0x04, 0x12, 0x04, 0xa2, 0x04, 0x04, 0x1a, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x31, 0x02, 0x04, 0x06, 0x12, 0x04, 0xa2, 0x04, 0x04, 0x0c, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x31, 0x02, 0x04, 0x01, 0x12, 0x04, 0xa2, 0x04, 0x0d, 0x15, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x31, 0x02, 0x04, 0x03, 0x12, 0x04, 0xa2, 0x04, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x31, 0x02, 0x05, 0x12, 0x04, 0xa3, 0x04, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, - 0x05, 0x06, 0x12, 0x04, 0xa3, 0x04, 0x04, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x05, - 0x01, 0x12, 0x04, 0xa3, 0x04, 0x0c, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x05, 0x03, - 0x12, 0x04, 0xa3, 0x04, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x32, 0x12, 0x06, 0xa7, 0x04, - 0x00, 0xa9, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x32, 0x01, 0x12, 0x04, 0xa7, 0x04, 0x08, - 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, 0x02, 0x00, 0x12, 0x04, 0xa8, 0x04, 0x02, 0x16, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa8, 0x04, 0x02, 0x07, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa8, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x32, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa8, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, - 0x04, 0x33, 0x12, 0x06, 0xab, 0x04, 0x00, 0xad, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x33, - 0x01, 0x12, 0x04, 0xab, 0x04, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x33, 0x02, 0x00, 0x12, - 0x04, 0xac, 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x33, 0x02, 0x00, 0x05, 0x12, 0x04, - 0xac, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x33, 0x02, 0x00, 0x01, 0x12, 0x04, 0xac, - 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x33, 0x02, 0x00, 0x03, 0x12, 0x04, 0xac, 0x04, - 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x34, 0x12, 0x06, 0xaf, 0x04, 0x00, 0xb1, 0x04, 0x01, - 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x34, 0x01, 0x12, 0x04, 0xaf, 0x04, 0x08, 0x10, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x34, 0x02, 0x00, 0x12, 0x04, 0xb0, 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x34, 0x02, 0x00, 0x05, 0x12, 0x04, 0xb0, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x34, - 0x02, 0x00, 0x01, 0x12, 0x04, 0xb0, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x34, 0x02, - 0x00, 0x03, 0x12, 0x04, 0xb0, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x35, 0x12, 0x06, - 0xb3, 0x04, 0x00, 0xb5, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x35, 0x01, 0x12, 0x04, 0xb3, - 0x04, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x35, 0x02, 0x00, 0x12, 0x04, 0xb4, 0x04, 0x02, - 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, 0x00, 0x05, 0x12, 0x04, 0xb4, 0x04, 0x02, 0x07, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb4, 0x04, 0x08, 0x11, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb4, 0x04, 0x14, 0x15, 0x0a, 0x0c, - 0x0a, 0x02, 0x04, 0x36, 0x12, 0x06, 0xb7, 0x04, 0x00, 0xba, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, - 0x04, 0x36, 0x01, 0x12, 0x04, 0xb7, 0x04, 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x36, 0x02, - 0x00, 0x12, 0x04, 0xb8, 0x04, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, 0x06, - 0x12, 0x04, 0xb8, 0x04, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, 0x01, 0x12, - 0x04, 0xb8, 0x04, 0x0f, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, 0x03, 0x12, 0x04, - 0xb8, 0x04, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x36, 0x02, 0x01, 0x12, 0x04, 0xb9, 0x04, - 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x01, 0x06, 0x12, 0x04, 0xb9, 0x04, 0x02, - 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb9, 0x04, 0x0f, 0x18, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb9, 0x04, 0x1b, 0x1c, 0x0a, - 0x0c, 0x0a, 0x02, 0x04, 0x37, 0x12, 0x06, 0xbc, 0x04, 0x00, 0xbf, 0x04, 0x01, 0x0a, 0x0b, 0x0a, - 0x03, 0x04, 0x37, 0x01, 0x12, 0x04, 0xbc, 0x04, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x37, - 0x02, 0x00, 0x12, 0x04, 0xbd, 0x04, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, - 0x05, 0x12, 0x04, 0xbd, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xbd, 0x04, 0x09, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xbd, 0x04, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x37, 0x02, 0x01, 0x12, 0x04, 0xbe, - 0x04, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x06, 0x12, 0x04, 0xbe, 0x04, - 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x01, 0x12, 0x04, 0xbe, 0x04, 0x0f, - 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x03, 0x12, 0x04, 0xbe, 0x04, 0x1b, 0x1c, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x38, 0x12, 0x06, 0xc1, 0x04, 0x00, 0xc5, 0x04, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x38, 0x01, 0x12, 0x04, 0xc1, 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x38, 0x02, 0x00, 0x12, 0x04, 0xc2, 0x04, 0x02, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, - 0x00, 0x04, 0x12, 0x04, 0xc2, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, - 0x06, 0x12, 0x04, 0xc2, 0x04, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, 0x01, - 0x12, 0x04, 0xc2, 0x04, 0x18, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, 0x03, 0x12, - 0x04, 0xc2, 0x04, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x38, 0x02, 0x01, 0x12, 0x04, 0xc3, - 0x04, 0x02, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x04, 0x12, 0x04, 0xc3, 0x04, - 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x06, 0x12, 0x04, 0xc3, 0x04, 0x0b, - 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc3, 0x04, 0x1c, 0x26, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc3, 0x04, 0x29, 0x2a, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x38, 0x02, 0x02, 0x12, 0x04, 0xc4, 0x04, 0x02, 0x21, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x38, 0x02, 0x02, 0x05, 0x12, 0x04, 0xc4, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x38, 0x02, 0x02, 0x01, 0x12, 0x04, 0xc4, 0x04, 0x09, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x38, 0x02, 0x02, 0x03, 0x12, 0x04, 0xc4, 0x04, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x39, - 0x12, 0x06, 0xc7, 0x04, 0x00, 0xc9, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x39, 0x01, 0x12, - 0x04, 0xc7, 0x04, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x39, 0x02, 0x00, 0x12, 0x04, 0xc8, - 0x04, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x06, 0x12, 0x04, 0xc8, 0x04, - 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc8, 0x04, 0x13, - 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc8, 0x04, 0x1c, 0x1d, - 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3a, 0x12, 0x06, 0xcb, 0x04, 0x00, 0xde, 0x04, 0x01, 0x0a, 0x0b, - 0x0a, 0x03, 0x04, 0x3a, 0x01, 0x12, 0x04, 0xcb, 0x04, 0x08, 0x18, 0x0a, 0x0e, 0x0a, 0x04, 0x04, - 0x3a, 0x04, 0x00, 0x12, 0x06, 0xcc, 0x04, 0x02, 0xd4, 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x3a, 0x04, 0x00, 0x01, 0x12, 0x04, 0xcc, 0x04, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3a, - 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xcd, 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3a, - 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xcd, 0x04, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, - 0x3a, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xcd, 0x04, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, - 0x04, 0x3a, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xce, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, - 0x04, 0x3a, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xce, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, - 0x07, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xce, 0x04, 0x13, 0x14, 0x0a, 0x0e, - 0x0a, 0x06, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xcf, 0x04, 0x04, 0x1b, 0x0a, 0x0f, - 0x0a, 0x07, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xcf, 0x04, 0x04, 0x16, 0x0a, - 0x0f, 0x0a, 0x07, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xcf, 0x04, 0x19, 0x1a, - 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xd0, 0x04, 0x04, 0x18, - 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xd0, 0x04, 0x04, - 0x13, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xd0, 0x04, - 0x16, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0xd1, 0x04, - 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xd1, - 0x04, 0x04, 0x12, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3a, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, - 0xd1, 0x04, 0x15, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x04, 0x00, 0x04, 0x12, 0x04, 0xd3, - 0x04, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3a, 0x04, 0x00, 0x04, 0x00, 0x12, 0x04, 0xd3, - 0x04, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3a, 0x04, 0x00, 0x04, 0x00, 0x01, 0x12, 0x04, - 0xd3, 0x04, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3a, 0x04, 0x00, 0x04, 0x00, 0x02, 0x12, - 0x04, 0xd3, 0x04, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3a, 0x02, 0x00, 0x12, 0x04, 0xd6, - 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd6, 0x04, - 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd6, 0x04, 0x07, - 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd6, 0x04, 0x0e, 0x0f, - 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x3a, 0x08, 0x00, 0x12, 0x06, 0xd7, 0x04, 0x02, 0xdd, 0x04, 0x03, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x08, 0x00, 0x01, 0x12, 0x04, 0xd7, 0x04, 0x08, 0x11, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x3a, 0x02, 0x01, 0x12, 0x04, 0xd8, 0x04, 0x04, 0x21, 0x0a, 0x0d, 0x0a, - 0x05, 0x04, 0x3a, 0x02, 0x01, 0x06, 0x12, 0x04, 0xd8, 0x04, 0x04, 0x14, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x3a, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd8, 0x04, 0x15, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x3a, 0x02, 0x01, 0x03, 0x12, 0x04, 0xd8, 0x04, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3a, - 0x02, 0x02, 0x12, 0x04, 0xd9, 0x04, 0x04, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x02, - 0x06, 0x12, 0x04, 0xd9, 0x04, 0x04, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x02, 0x01, - 0x12, 0x04, 0xd9, 0x04, 0x1a, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x02, 0x03, 0x12, - 0x04, 0xd9, 0x04, 0x2a, 0x2b, 0x0a, 0x1e, 0x0a, 0x04, 0x04, 0x3a, 0x02, 0x03, 0x12, 0x04, 0xdb, - 0x04, 0x04, 0x30, 0x1a, 0x10, 0x20, 0x34, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x03, 0x06, 0x12, 0x04, - 0xdb, 0x04, 0x04, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x03, 0x01, 0x12, 0x04, 0xdb, - 0x04, 0x17, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x03, 0x03, 0x12, 0x04, 0xdb, 0x04, - 0x2e, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3a, 0x02, 0x04, 0x12, 0x04, 0xdc, 0x04, 0x04, 0x2e, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x04, 0x06, 0x12, 0x04, 0xdc, 0x04, 0x04, 0x15, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x04, 0x01, 0x12, 0x04, 0xdc, 0x04, 0x16, 0x29, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x04, 0x03, 0x12, 0x04, 0xdc, 0x04, 0x2c, 0x2d, 0x0a, 0x0c, 0x0a, - 0x02, 0x04, 0x3b, 0x12, 0x06, 0xe0, 0x04, 0x00, 0xe4, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, - 0x3b, 0x01, 0x12, 0x04, 0xe0, 0x04, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3b, 0x02, 0x00, - 0x12, 0x04, 0xe1, 0x04, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x05, 0x12, - 0x04, 0xe1, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x01, 0x12, 0x04, - 0xe1, 0x04, 0x09, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe1, - 0x04, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3b, 0x02, 0x01, 0x12, 0x04, 0xe2, 0x04, 0x02, - 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x01, 0x04, 0x12, 0x04, 0xe2, 0x04, 0x02, 0x0a, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x01, 0x06, 0x12, 0x04, 0xe2, 0x04, 0x0b, 0x18, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe2, 0x04, 0x19, 0x28, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xe2, 0x04, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x3b, 0x02, 0x02, 0x12, 0x04, 0xe3, 0x04, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x3b, 0x02, 0x02, 0x04, 0x12, 0x04, 0xe3, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, - 0x02, 0x02, 0x06, 0x12, 0x04, 0xe3, 0x04, 0x0b, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, - 0x02, 0x01, 0x12, 0x04, 0xe3, 0x04, 0x1b, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x02, - 0x03, 0x12, 0x04, 0xe3, 0x04, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3c, 0x12, 0x06, 0xe6, - 0x04, 0x00, 0xe9, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3c, 0x01, 0x12, 0x04, 0xe6, 0x04, - 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x00, 0x12, 0x04, 0xe7, 0x04, 0x02, 0x1c, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x05, 0x12, 0x04, 0xe7, 0x04, 0x02, 0x08, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe7, 0x04, 0x09, 0x17, 0x0a, 0x0d, - 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe7, 0x04, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x3c, 0x02, 0x01, 0x12, 0x04, 0xe8, 0x04, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x3c, 0x02, 0x01, 0x05, 0x12, 0x04, 0xe8, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, - 0x02, 0x01, 0x01, 0x12, 0x04, 0xe8, 0x04, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, - 0x01, 0x03, 0x12, 0x04, 0xe8, 0x04, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3d, 0x12, 0x06, - 0xeb, 0x04, 0x00, 0xee, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3d, 0x01, 0x12, 0x04, 0xeb, - 0x04, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3d, 0x02, 0x00, 0x12, 0x04, 0xec, 0x04, 0x02, - 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x05, 0x12, 0x04, 0xec, 0x04, 0x02, 0x08, - 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xec, 0x04, 0x09, 0x12, 0x0a, - 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xec, 0x04, 0x15, 0x16, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x3d, 0x02, 0x01, 0x12, 0x04, 0xed, 0x04, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, - 0x04, 0x3d, 0x02, 0x01, 0x05, 0x12, 0x04, 0xed, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, - 0x3d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xed, 0x04, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, - 0x02, 0x01, 0x03, 0x12, 0x04, 0xed, 0x04, 0x17, 0x18, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x02, 0x02, 0x05, 0x12, 0x03, 0x68, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x68, 0x11, 0x14, 0x0a, 0x14, + 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x03, 0x12, + 0x03, 0x68, 0x17, 0x18, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x02, 0x03, 0x12, 0x03, 0x69, 0x0a, 0x17, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, + 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x03, 0x05, 0x12, 0x03, 0x69, 0x0a, 0x10, 0x0a, + 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x03, 0x01, + 0x12, 0x03, 0x69, 0x11, 0x12, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x69, 0x15, 0x16, 0x0a, 0x13, 0x0a, 0x0c, 0x04, + 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x12, 0x03, 0x6a, 0x0a, 0x17, + 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, + 0x05, 0x12, 0x03, 0x6a, 0x0a, 0x10, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x01, 0x12, 0x03, 0x6a, 0x11, 0x12, 0x0a, 0x14, 0x0a, 0x0d, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x04, 0x03, 0x12, 0x03, 0x6a, + 0x15, 0x16, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, + 0x12, 0x04, 0x6c, 0x08, 0x6f, 0x09, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x01, 0x01, 0x12, 0x03, 0x6c, 0x10, 0x1e, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x12, 0x03, 0x6d, 0x0a, 0x17, 0x0a, + 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x05, + 0x12, 0x03, 0x6d, 0x0a, 0x0f, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x6d, 0x10, 0x12, 0x0a, 0x14, 0x0a, 0x0d, 0x04, + 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x6d, 0x15, + 0x16, 0x0a, 0x13, 0x0a, 0x0c, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, + 0x01, 0x12, 0x03, 0x6e, 0x0a, 0x1c, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x6e, 0x0a, 0x0f, 0x0a, 0x14, 0x0a, 0x0d, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x6e, + 0x10, 0x17, 0x0a, 0x14, 0x0a, 0x0d, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x01, + 0x02, 0x01, 0x03, 0x12, 0x03, 0x6e, 0x1a, 0x1b, 0x0a, 0x12, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x08, 0x00, 0x12, 0x04, 0x70, 0x08, 0x73, 0x09, 0x0a, 0x12, 0x0a, 0x0b, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x70, 0x0e, 0x15, + 0x0a, 0x11, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, + 0x71, 0x0a, 0x2d, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, + 0x00, 0x06, 0x12, 0x03, 0x71, 0x0a, 0x18, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x71, 0x19, 0x28, 0x0a, 0x12, 0x0a, 0x0b, 0x04, + 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x71, 0x2b, 0x2c, 0x0a, + 0x11, 0x0a, 0x0a, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x72, + 0x0a, 0x16, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, + 0x06, 0x12, 0x03, 0x72, 0x0a, 0x0d, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x72, 0x0e, 0x11, 0x0a, 0x12, 0x0a, 0x0b, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x72, 0x14, 0x15, 0x0a, 0x0f, + 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x12, 0x03, 0x76, 0x06, 0x1c, 0x0a, + 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x04, 0x12, 0x03, 0x76, 0x06, + 0x0e, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, + 0x76, 0x0f, 0x12, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, 0x02, 0x01, + 0x12, 0x03, 0x76, 0x13, 0x17, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x00, 0x02, + 0x02, 0x03, 0x12, 0x03, 0x76, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x01, 0x12, 0x04, 0x78, 0x04, 0x7c, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x01, 0x01, 0x12, 0x03, 0x78, 0x0c, 0x26, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x01, 0x02, 0x00, 0x12, 0x03, 0x79, 0x06, 0x29, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x79, 0x06, 0x0e, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, 0x79, 0x0f, 0x15, 0x0a, 0x10, 0x0a, 0x09, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x79, 0x16, 0x24, 0x0a, 0x10, + 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x79, 0x27, 0x28, + 0x0a, 0x1e, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x12, 0x03, 0x7b, 0x06, + 0x14, 0x1a, 0x0d, 0x20, 0x48, 0x65, 0x78, 0x54, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x0a, + 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x7b, + 0x06, 0x0b, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, 0x01, 0x12, + 0x03, 0x7b, 0x0c, 0x0f, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x01, 0x02, 0x01, + 0x03, 0x12, 0x03, 0x7b, 0x12, 0x13, 0x0a, 0x0f, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, + 0x12, 0x05, 0x7d, 0x04, 0x80, 0x01, 0x05, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x02, 0x01, 0x12, 0x03, 0x7d, 0x0c, 0x21, 0x0a, 0x0f, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, + 0x02, 0x02, 0x00, 0x12, 0x03, 0x7e, 0x06, 0x26, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, + 0x03, 0x02, 0x02, 0x00, 0x06, 0x12, 0x03, 0x7e, 0x06, 0x1a, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, + 0x03, 0x00, 0x03, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x7e, 0x1b, 0x21, 0x0a, 0x10, 0x0a, 0x09, + 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x7e, 0x24, 0x25, 0x0a, 0x0f, + 0x0a, 0x08, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x12, 0x03, 0x7f, 0x06, 0x2f, 0x0a, + 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x06, 0x12, 0x03, 0x7f, 0x06, + 0x20, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x01, 0x12, 0x03, + 0x7f, 0x21, 0x2a, 0x0a, 0x10, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x00, 0x03, 0x02, 0x02, 0x01, 0x03, + 0x12, 0x03, 0x7f, 0x2d, 0x2e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x12, + 0x04, 0x81, 0x01, 0x04, 0x36, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x06, + 0x12, 0x04, 0x81, 0x01, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, + 0x01, 0x12, 0x04, 0x81, 0x01, 0x1a, 0x31, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, + 0x00, 0x03, 0x12, 0x04, 0x81, 0x01, 0x34, 0x35, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x05, 0x03, 0x01, + 0x12, 0x06, 0x84, 0x01, 0x02, 0x8b, 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x03, 0x01, + 0x01, 0x12, 0x04, 0x84, 0x01, 0x0a, 0x13, 0x0a, 0x10, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x01, 0x03, + 0x00, 0x12, 0x06, 0x85, 0x01, 0x04, 0x89, 0x01, 0x05, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x05, 0x03, + 0x01, 0x03, 0x00, 0x01, 0x12, 0x04, 0x85, 0x01, 0x0c, 0x19, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, + 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x12, 0x04, 0x86, 0x01, 0x06, 0x17, 0x0a, 0x11, 0x0a, 0x09, + 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x04, 0x86, 0x01, 0x06, 0x0c, 0x0a, + 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x86, 0x01, + 0x0d, 0x12, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, + 0x04, 0x86, 0x01, 0x15, 0x16, 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, + 0x01, 0x12, 0x04, 0x87, 0x01, 0x06, 0x18, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, + 0x00, 0x02, 0x01, 0x05, 0x12, 0x04, 0x87, 0x01, 0x06, 0x0c, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, + 0x03, 0x01, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x87, 0x01, 0x0d, 0x13, 0x0a, 0x11, 0x0a, + 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x04, 0x87, 0x01, 0x16, 0x17, + 0x0a, 0x10, 0x0a, 0x08, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, 0x12, 0x04, 0x88, 0x01, + 0x06, 0x18, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, 0x02, 0x05, 0x12, + 0x04, 0x88, 0x01, 0x06, 0x0b, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, 0x03, 0x00, 0x02, + 0x02, 0x01, 0x12, 0x04, 0x88, 0x01, 0x0c, 0x13, 0x0a, 0x11, 0x0a, 0x09, 0x04, 0x05, 0x03, 0x01, + 0x03, 0x00, 0x02, 0x02, 0x03, 0x12, 0x04, 0x88, 0x01, 0x16, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, + 0x05, 0x03, 0x01, 0x02, 0x00, 0x12, 0x04, 0x8a, 0x01, 0x04, 0x25, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x05, 0x03, 0x01, 0x02, 0x00, 0x06, 0x12, 0x04, 0x8a, 0x01, 0x04, 0x11, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x05, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8a, 0x01, 0x12, 0x20, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x05, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x04, 0x8a, 0x01, 0x23, 0x24, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x05, 0x02, 0x02, 0x12, 0x04, 0x8d, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x05, 0x02, 0x02, 0x04, 0x12, 0x04, 0x8d, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x05, 0x02, 0x02, 0x06, 0x12, 0x04, 0x8d, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, + 0x02, 0x02, 0x01, 0x12, 0x04, 0x8d, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x05, 0x02, + 0x02, 0x03, 0x12, 0x04, 0x8d, 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x06, 0x12, 0x06, + 0x90, 0x01, 0x00, 0x92, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x06, 0x01, 0x12, 0x04, 0x90, + 0x01, 0x08, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x06, 0x02, 0x00, 0x12, 0x04, 0x91, 0x01, 0x02, + 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x04, 0x12, 0x04, 0x91, 0x01, 0x02, 0x0a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x06, 0x12, 0x04, 0x91, 0x01, 0x0b, 0x17, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x01, 0x12, 0x04, 0x91, 0x01, 0x18, 0x26, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x03, 0x12, 0x04, 0x91, 0x01, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, + 0x02, 0x04, 0x07, 0x12, 0x06, 0x94, 0x01, 0x00, 0x99, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, + 0x07, 0x01, 0x12, 0x04, 0x94, 0x01, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x00, + 0x12, 0x04, 0x95, 0x01, 0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x05, 0x12, + 0x04, 0x95, 0x01, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x01, 0x12, 0x04, + 0x95, 0x01, 0x07, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x03, 0x12, 0x04, 0x95, + 0x01, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x01, 0x12, 0x04, 0x96, 0x01, 0x02, + 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x05, 0x12, 0x04, 0x96, 0x01, 0x02, 0x06, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x01, 0x12, 0x04, 0x96, 0x01, 0x07, 0x21, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x03, 0x12, 0x04, 0x96, 0x01, 0x24, 0x25, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x07, 0x02, 0x02, 0x12, 0x04, 0x97, 0x01, 0x02, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x07, 0x02, 0x02, 0x05, 0x12, 0x04, 0x97, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x07, 0x02, 0x02, 0x01, 0x12, 0x04, 0x97, 0x01, 0x09, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, + 0x02, 0x02, 0x03, 0x12, 0x04, 0x97, 0x01, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x07, 0x02, + 0x03, 0x12, 0x04, 0x98, 0x01, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x05, + 0x12, 0x04, 0x98, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x01, 0x12, + 0x04, 0x98, 0x01, 0x09, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x03, 0x12, 0x04, + 0x98, 0x01, 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x08, 0x12, 0x06, 0x9b, 0x01, 0x00, 0x9e, + 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x08, 0x01, 0x12, 0x04, 0x9b, 0x01, 0x08, 0x17, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x00, 0x12, 0x04, 0x9c, 0x01, 0x02, 0x25, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x08, 0x02, 0x00, 0x06, 0x12, 0x04, 0x9c, 0x01, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x08, 0x02, 0x00, 0x01, 0x12, 0x04, 0x9c, 0x01, 0x19, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x08, 0x02, 0x00, 0x03, 0x12, 0x04, 0x9c, 0x01, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x08, + 0x02, 0x01, 0x12, 0x04, 0x9d, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, + 0x04, 0x12, 0x04, 0x9d, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x06, + 0x12, 0x04, 0x9d, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x01, 0x12, + 0x04, 0x9d, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x03, 0x12, 0x04, + 0x9d, 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x09, 0x12, 0x06, 0xa0, 0x01, 0x00, 0xa6, + 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x09, 0x01, 0x12, 0x04, 0xa0, 0x01, 0x08, 0x0d, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x00, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x13, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x09, 0x02, 0x00, 0x06, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x09, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa1, 0x01, 0x0b, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x09, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa1, 0x01, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, + 0x02, 0x01, 0x12, 0x04, 0xa2, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, + 0x05, 0x12, 0x04, 0xa2, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x01, + 0x12, 0x04, 0xa2, 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x03, 0x12, + 0x04, 0xa2, 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x08, 0x12, 0x04, + 0xa2, 0x01, 0x1d, 0x31, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x09, 0x02, 0x01, 0x08, 0x06, 0x12, 0x04, + 0xa2, 0x01, 0x1e, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x02, 0x12, 0x04, 0xa3, 0x01, + 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x06, 0x12, 0x04, 0xa3, 0x01, 0x02, + 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x01, 0x12, 0x04, 0xa3, 0x01, 0x0b, 0x0f, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x02, 0x03, 0x12, 0x04, 0xa3, 0x01, 0x12, 0x13, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x03, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x16, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x09, 0x02, 0x03, 0x05, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x09, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa4, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x09, 0x02, 0x03, 0x03, 0x12, 0x04, 0xa4, 0x01, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x09, + 0x02, 0x04, 0x12, 0x04, 0xa5, 0x01, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, + 0x05, 0x12, 0x04, 0xa5, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, 0x01, + 0x12, 0x04, 0xa5, 0x01, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x04, 0x03, 0x12, + 0x04, 0xa5, 0x01, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0a, 0x12, 0x06, 0xa8, 0x01, 0x00, + 0xb2, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0a, 0x01, 0x12, 0x04, 0xa8, 0x01, 0x08, 0x17, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x00, 0x12, 0x04, 0xa9, 0x01, 0x02, 0x11, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa9, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa9, 0x01, 0x08, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x0a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa9, 0x01, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x0a, 0x02, 0x01, 0x12, 0x04, 0xaa, 0x01, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, + 0x01, 0x05, 0x12, 0x04, 0xaa, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, + 0x01, 0x12, 0x04, 0xaa, 0x01, 0x08, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x03, + 0x12, 0x04, 0xaa, 0x01, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x02, 0x12, 0x04, + 0xab, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x05, 0x12, 0x04, 0xab, + 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x01, 0x12, 0x04, 0xab, 0x01, + 0x08, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x03, 0x12, 0x04, 0xab, 0x01, 0x1a, + 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x03, 0x12, 0x04, 0xac, 0x01, 0x02, 0x2b, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x03, 0x04, 0x12, 0x04, 0xac, 0x01, 0x02, 0x0a, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x03, 0x05, 0x12, 0x04, 0xac, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0a, 0x02, 0x03, 0x01, 0x12, 0x04, 0xac, 0x01, 0x11, 0x26, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x0a, 0x02, 0x03, 0x03, 0x12, 0x04, 0xac, 0x01, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x0a, 0x02, 0x04, 0x12, 0x04, 0xad, 0x01, 0x02, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, + 0x04, 0x05, 0x12, 0x04, 0xad, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, + 0x01, 0x12, 0x04, 0xad, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, 0x03, + 0x12, 0x04, 0xad, 0x01, 0x14, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x04, 0x08, 0x12, + 0x04, 0xad, 0x01, 0x16, 0x2a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0a, 0x02, 0x04, 0x08, 0x06, 0x12, + 0x04, 0xad, 0x01, 0x17, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x05, 0x12, 0x04, 0xae, + 0x01, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x05, 0x12, 0x04, 0xae, 0x01, + 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x01, 0x12, 0x04, 0xae, 0x01, 0x07, + 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x05, 0x03, 0x12, 0x04, 0xae, 0x01, 0x11, 0x12, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x06, 0x12, 0x04, 0xaf, 0x01, 0x02, 0x17, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x06, 0x05, 0x12, 0x04, 0xaf, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0a, 0x02, 0x06, 0x01, 0x12, 0x04, 0xaf, 0x01, 0x09, 0x12, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x0a, 0x02, 0x06, 0x03, 0x12, 0x04, 0xaf, 0x01, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x0a, 0x02, 0x07, 0x12, 0x04, 0xb0, 0x01, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, + 0x07, 0x05, 0x12, 0x04, 0xb0, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x07, + 0x01, 0x12, 0x04, 0xb0, 0x01, 0x08, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x07, 0x03, + 0x12, 0x04, 0xb0, 0x01, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x08, 0x12, 0x04, + 0xb1, 0x01, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x04, 0x12, 0x04, 0xb1, + 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x06, 0x12, 0x04, 0xb1, 0x01, + 0x0b, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x01, 0x12, 0x04, 0xb1, 0x01, 0x1a, + 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x08, 0x03, 0x12, 0x04, 0xb1, 0x01, 0x24, 0x25, + 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0b, 0x12, 0x06, 0xb4, 0x01, 0x00, 0xb7, 0x01, 0x01, 0x0a, 0x0b, + 0x0a, 0x03, 0x04, 0x0b, 0x01, 0x12, 0x04, 0xb4, 0x01, 0x08, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x0b, 0x02, 0x00, 0x12, 0x04, 0xb5, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, + 0x00, 0x05, 0x12, 0x04, 0xb5, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, + 0x01, 0x12, 0x04, 0xb5, 0x01, 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x03, + 0x12, 0x04, 0xb5, 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x08, 0x12, + 0x04, 0xb5, 0x01, 0x1d, 0x31, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0b, 0x02, 0x00, 0x08, 0x06, 0x12, + 0x04, 0xb5, 0x01, 0x1e, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0b, 0x02, 0x01, 0x12, 0x04, 0xb6, + 0x01, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x05, 0x12, 0x04, 0xb6, 0x01, + 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb6, 0x01, 0x09, + 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb6, 0x01, 0x1b, 0x1c, + 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0c, 0x12, 0x06, 0xb9, 0x01, 0x00, 0xc1, 0x01, 0x01, 0x0a, 0x0b, + 0x0a, 0x03, 0x04, 0x0c, 0x01, 0x12, 0x04, 0xb9, 0x01, 0x08, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x0c, 0x02, 0x00, 0x12, 0x04, 0xba, 0x01, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, + 0x00, 0x05, 0x12, 0x04, 0xba, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, + 0x01, 0x12, 0x04, 0xba, 0x01, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x00, 0x03, + 0x12, 0x04, 0xba, 0x01, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x01, 0x12, 0x04, + 0xbb, 0x01, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x05, 0x12, 0x04, 0xbb, + 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xbb, 0x01, + 0x09, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xbb, 0x01, 0x1b, + 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x12, 0x04, 0xbb, 0x01, 0x1d, 0x31, + 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0c, 0x02, 0x01, 0x08, 0x06, 0x12, 0x04, 0xbb, 0x01, 0x1e, 0x30, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x02, 0x12, 0x04, 0xbc, 0x01, 0x02, 0x31, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x02, 0x05, 0x12, 0x04, 0xbc, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0c, 0x02, 0x02, 0x01, 0x12, 0x04, 0xbc, 0x01, 0x09, 0x17, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x0c, 0x02, 0x02, 0x03, 0x12, 0x04, 0xbc, 0x01, 0x1a, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0c, 0x02, 0x02, 0x08, 0x12, 0x04, 0xbc, 0x01, 0x1c, 0x30, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0c, + 0x02, 0x02, 0x08, 0x06, 0x12, 0x04, 0xbc, 0x01, 0x1d, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, + 0x02, 0x03, 0x12, 0x04, 0xbd, 0x01, 0x02, 0x31, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, + 0x05, 0x12, 0x04, 0xbd, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x01, + 0x12, 0x04, 0xbd, 0x01, 0x09, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x03, 0x12, + 0x04, 0xbd, 0x01, 0x1a, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x03, 0x08, 0x12, 0x04, + 0xbd, 0x01, 0x1c, 0x30, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0c, 0x02, 0x03, 0x08, 0x06, 0x12, 0x04, + 0xbd, 0x01, 0x1d, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x04, 0x12, 0x04, 0xbe, 0x01, + 0x02, 0x3f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x06, 0x12, 0x04, 0xbe, 0x01, 0x02, + 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x01, 0x12, 0x04, 0xbe, 0x01, 0x21, 0x3a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x04, 0x03, 0x12, 0x04, 0xbe, 0x01, 0x3d, 0x3e, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x0c, 0x02, 0x05, 0x12, 0x04, 0xbf, 0x01, 0x02, 0x21, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0c, 0x02, 0x05, 0x06, 0x12, 0x04, 0xbf, 0x01, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x0c, 0x02, 0x05, 0x01, 0x12, 0x04, 0xbf, 0x01, 0x15, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0c, 0x02, 0x05, 0x03, 0x12, 0x04, 0xbf, 0x01, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0c, + 0x02, 0x06, 0x12, 0x04, 0xc0, 0x01, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, + 0x06, 0x12, 0x04, 0xc0, 0x01, 0x02, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, 0x01, + 0x12, 0x04, 0xc0, 0x01, 0x0c, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0c, 0x02, 0x06, 0x03, 0x12, + 0x04, 0xc0, 0x01, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0d, 0x12, 0x06, 0xc3, 0x01, 0x00, + 0xcf, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0d, 0x01, 0x12, 0x04, 0xc3, 0x01, 0x08, 0x10, + 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x0d, 0x04, 0x00, 0x12, 0x06, 0xc4, 0x01, 0x02, 0xc8, 0x01, 0x03, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x04, 0x00, 0x01, 0x12, 0x04, 0xc4, 0x01, 0x07, 0x13, 0x0a, + 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xc5, 0x01, 0x04, 0x23, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc5, 0x01, 0x04, 0x1e, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xc5, 0x01, 0x21, + 0x22, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xc6, 0x01, 0x04, + 0x28, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc6, 0x01, + 0x04, 0x23, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xc6, + 0x01, 0x26, 0x27, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xc7, + 0x01, 0x04, 0x28, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, + 0xc7, 0x01, 0x04, 0x23, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x0d, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, + 0x04, 0xc7, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x00, 0x12, 0x04, 0xca, + 0x01, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x06, 0x12, 0x04, 0xca, 0x01, + 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xca, 0x01, 0x0f, + 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xca, 0x01, 0x20, 0x21, + 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x0d, 0x08, 0x00, 0x12, 0x06, 0xcb, 0x01, 0x02, 0xce, 0x01, 0x03, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x08, 0x00, 0x01, 0x12, 0x04, 0xcb, 0x01, 0x08, 0x11, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x01, 0x12, 0x04, 0xcc, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0d, 0x02, 0x01, 0x06, 0x12, 0x04, 0xcc, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x0d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xcc, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x0d, 0x02, 0x01, 0x03, 0x12, 0x04, 0xcc, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0d, + 0x02, 0x02, 0x12, 0x04, 0xcd, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, + 0x06, 0x12, 0x04, 0xcd, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xcd, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x03, 0x12, + 0x04, 0xcd, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0e, 0x12, 0x06, 0xd1, 0x01, 0x00, + 0xd4, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0e, 0x01, 0x12, 0x04, 0xd1, 0x01, 0x08, 0x16, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0e, 0x02, 0x00, 0x12, 0x04, 0xd2, 0x01, 0x02, 0x18, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xd2, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd2, 0x01, 0x09, 0x13, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x0e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd2, 0x01, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x0e, 0x02, 0x01, 0x12, 0x04, 0xd3, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, + 0x01, 0x06, 0x12, 0x04, 0xd3, 0x01, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x01, + 0x01, 0x12, 0x04, 0xd3, 0x01, 0x10, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x01, 0x03, + 0x12, 0x04, 0xd3, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0f, 0x12, 0x06, 0xd6, 0x01, + 0x00, 0xd9, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0f, 0x01, 0x12, 0x04, 0xd6, 0x01, 0x08, + 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0f, 0x02, 0x00, 0x12, 0x04, 0xd7, 0x01, 0x02, 0x2f, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x04, 0x12, 0x04, 0xd7, 0x01, 0x02, 0x0a, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd7, 0x01, 0x0b, 0x19, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x0f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd7, 0x01, 0x1a, 0x2a, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x0f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd7, 0x01, 0x2d, 0x2e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x0f, 0x02, 0x01, 0x12, 0x04, 0xd8, 0x01, 0x02, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, + 0x01, 0x04, 0x12, 0x04, 0xd8, 0x01, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, + 0x06, 0x12, 0x04, 0xd8, 0x01, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, 0x01, + 0x12, 0x04, 0xd8, 0x01, 0x11, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x01, 0x03, 0x12, + 0x04, 0xd8, 0x01, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x10, 0x12, 0x06, 0xdb, 0x01, 0x00, + 0xf0, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x10, 0x01, 0x12, 0x04, 0xdb, 0x01, 0x08, 0x16, + 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x10, 0x04, 0x00, 0x12, 0x06, 0xdc, 0x01, 0x02, 0xe4, 0x01, 0x03, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x04, 0x00, 0x01, 0x12, 0x04, 0xdc, 0x01, 0x07, 0x0b, 0x0a, + 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xdd, 0x01, 0x04, 0x19, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xdd, 0x01, 0x04, 0x14, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xdd, 0x01, 0x17, + 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xde, 0x01, 0x04, + 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xde, 0x01, + 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xde, + 0x01, 0x19, 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xdf, + 0x01, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, + 0xdf, 0x01, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, + 0x04, 0xdf, 0x01, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, 0x03, 0x12, + 0x04, 0xe0, 0x01, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x03, 0x01, + 0x12, 0x04, 0xe0, 0x01, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, 0x03, + 0x02, 0x12, 0x04, 0xe0, 0x01, 0x1d, 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, 0x00, 0x02, + 0x04, 0x12, 0x04, 0xe1, 0x01, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, 0x02, + 0x04, 0x01, 0x12, 0x04, 0xe1, 0x01, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, 0x00, + 0x02, 0x04, 0x02, 0x12, 0x04, 0xe1, 0x01, 0x18, 0x19, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x10, 0x04, + 0x00, 0x02, 0x05, 0x12, 0x04, 0xe2, 0x01, 0x04, 0x1c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, 0x04, + 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0xe2, 0x01, 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x10, + 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x04, 0xe2, 0x01, 0x1a, 0x1b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, + 0x10, 0x04, 0x00, 0x02, 0x06, 0x12, 0x04, 0xe3, 0x01, 0x04, 0x1e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x10, 0x04, 0x00, 0x02, 0x06, 0x01, 0x12, 0x04, 0xe3, 0x01, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x10, 0x04, 0x00, 0x02, 0x06, 0x02, 0x12, 0x04, 0xe3, 0x01, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x10, 0x02, 0x00, 0x12, 0x04, 0xe6, 0x01, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x10, 0x02, 0x00, 0x06, 0x12, 0x04, 0xe6, 0x01, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, + 0x02, 0x00, 0x01, 0x12, 0x04, 0xe6, 0x01, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, + 0x00, 0x03, 0x12, 0x04, 0xe6, 0x01, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x10, 0x08, 0x00, + 0x12, 0x06, 0xe8, 0x01, 0x02, 0xef, 0x01, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x08, 0x00, + 0x01, 0x12, 0x04, 0xe8, 0x01, 0x08, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x01, 0x12, + 0x04, 0xe9, 0x01, 0x04, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x06, 0x12, 0x04, + 0xe9, 0x01, 0x04, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe9, + 0x01, 0x11, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x03, 0x12, 0x04, 0xe9, 0x01, + 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x02, 0x12, 0x04, 0xea, 0x01, 0x04, 0x27, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x06, 0x12, 0x04, 0xea, 0x01, 0x04, 0x12, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x01, 0x12, 0x04, 0xea, 0x01, 0x13, 0x22, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x03, 0x12, 0x04, 0xea, 0x01, 0x25, 0x26, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x10, 0x02, 0x03, 0x12, 0x04, 0xeb, 0x01, 0x04, 0x2a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x10, 0x02, 0x03, 0x06, 0x12, 0x04, 0xeb, 0x01, 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, + 0x02, 0x03, 0x01, 0x12, 0x04, 0xeb, 0x01, 0x14, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, + 0x03, 0x03, 0x12, 0x04, 0xeb, 0x01, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x04, + 0x12, 0x04, 0xec, 0x01, 0x04, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x06, 0x12, + 0x04, 0xec, 0x01, 0x04, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x01, 0x12, 0x04, + 0xec, 0x01, 0x10, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x03, 0x12, 0x04, 0xec, + 0x01, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x05, 0x12, 0x04, 0xed, 0x01, 0x04, + 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x06, 0x12, 0x04, 0xed, 0x01, 0x04, 0x11, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x01, 0x12, 0x04, 0xed, 0x01, 0x12, 0x20, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x03, 0x12, 0x04, 0xed, 0x01, 0x23, 0x24, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x10, 0x02, 0x06, 0x12, 0x04, 0xee, 0x01, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x10, 0x02, 0x06, 0x06, 0x12, 0x04, 0xee, 0x01, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x10, 0x02, 0x06, 0x01, 0x12, 0x04, 0xee, 0x01, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, + 0x02, 0x06, 0x03, 0x12, 0x04, 0xee, 0x01, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x11, 0x12, + 0x06, 0xf2, 0x01, 0x00, 0xf6, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x11, 0x01, 0x12, 0x04, + 0xf2, 0x01, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x11, 0x02, 0x00, 0x12, 0x04, 0xf3, 0x01, + 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf3, 0x01, 0x02, + 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf3, 0x01, 0x09, 0x10, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf3, 0x01, 0x13, 0x14, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x11, 0x02, 0x01, 0x12, 0x04, 0xf4, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x11, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf4, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x11, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf4, 0x01, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x11, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf4, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x11, + 0x02, 0x02, 0x12, 0x04, 0xf5, 0x01, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, + 0x06, 0x12, 0x04, 0xf5, 0x01, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xf5, 0x01, 0x0f, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x02, 0x03, 0x12, + 0x04, 0xf5, 0x01, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x12, 0x12, 0x06, 0xf8, 0x01, 0x00, + 0xfd, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x12, 0x01, 0x12, 0x04, 0xf8, 0x01, 0x08, 0x16, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x00, 0x12, 0x04, 0xf9, 0x01, 0x02, 0x15, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x12, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf9, 0x01, 0x02, 0x08, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x12, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf9, 0x01, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x12, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf9, 0x01, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x12, 0x02, 0x01, 0x12, 0x04, 0xfa, 0x01, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, + 0x01, 0x05, 0x12, 0x04, 0xfa, 0x01, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x01, + 0x01, 0x12, 0x04, 0xfa, 0x01, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x01, 0x03, + 0x12, 0x04, 0xfa, 0x01, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x02, 0x12, 0x04, + 0xfb, 0x01, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x06, 0x12, 0x04, 0xfb, + 0x01, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x01, 0x12, 0x04, 0xfb, 0x01, + 0x10, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x02, 0x03, 0x12, 0x04, 0xfb, 0x01, 0x17, + 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x03, 0x12, 0x04, 0xfc, 0x01, 0x02, 0x16, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x12, 0x02, 0x03, 0x05, 0x12, 0x04, 0xfc, 0x01, 0x02, 0x08, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x12, 0x02, 0x03, 0x01, 0x12, 0x04, 0xfc, 0x01, 0x09, 0x11, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x12, 0x02, 0x03, 0x03, 0x12, 0x04, 0xfc, 0x01, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, + 0x04, 0x13, 0x12, 0x06, 0xff, 0x01, 0x00, 0x84, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x13, + 0x01, 0x12, 0x04, 0xff, 0x01, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x00, 0x12, + 0x04, 0x80, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x05, 0x12, 0x04, + 0x80, 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x01, 0x12, 0x04, 0x80, + 0x02, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x03, 0x12, 0x04, 0x80, 0x02, + 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x01, 0x12, 0x04, 0x81, 0x02, 0x02, 0x14, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x01, 0x05, 0x12, 0x04, 0x81, 0x02, 0x02, 0x08, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x01, 0x01, 0x12, 0x04, 0x81, 0x02, 0x09, 0x0f, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x13, 0x02, 0x01, 0x03, 0x12, 0x04, 0x81, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x13, 0x02, 0x02, 0x12, 0x04, 0x82, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x13, 0x02, 0x02, 0x05, 0x12, 0x04, 0x82, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, + 0x02, 0x02, 0x01, 0x12, 0x04, 0x82, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, + 0x02, 0x03, 0x12, 0x04, 0x82, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x03, + 0x12, 0x04, 0x83, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x06, 0x12, + 0x04, 0x83, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x01, 0x12, 0x04, + 0x83, 0x02, 0x12, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x03, 0x03, 0x12, 0x04, 0x83, + 0x02, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x14, 0x12, 0x06, 0x86, 0x02, 0x00, 0x89, 0x02, + 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x14, 0x01, 0x12, 0x04, 0x86, 0x02, 0x08, 0x17, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x14, 0x02, 0x00, 0x12, 0x04, 0x87, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x14, 0x02, 0x00, 0x05, 0x12, 0x04, 0x87, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x14, 0x02, 0x00, 0x01, 0x12, 0x04, 0x87, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, + 0x02, 0x00, 0x03, 0x12, 0x04, 0x87, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x14, 0x02, + 0x01, 0x12, 0x04, 0x88, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x05, + 0x12, 0x04, 0x88, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x01, 0x12, + 0x04, 0x88, 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x03, 0x12, 0x04, + 0x88, 0x02, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x15, 0x12, 0x06, 0x8b, 0x02, 0x00, 0x8f, + 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x15, 0x01, 0x12, 0x04, 0x8b, 0x02, 0x08, 0x13, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x00, 0x12, 0x04, 0x8c, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x15, 0x02, 0x00, 0x05, 0x12, 0x04, 0x8c, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x15, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8c, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x15, 0x02, 0x00, 0x03, 0x12, 0x04, 0x8c, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x15, + 0x02, 0x01, 0x12, 0x04, 0x8d, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, + 0x05, 0x12, 0x04, 0x8d, 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x01, + 0x12, 0x04, 0x8d, 0x02, 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x03, 0x12, + 0x04, 0x8d, 0x02, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x02, 0x12, 0x04, 0x8e, + 0x02, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x06, 0x12, 0x04, 0x8e, 0x02, + 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x01, 0x12, 0x04, 0x8e, 0x02, 0x15, + 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x03, 0x12, 0x04, 0x8e, 0x02, 0x1c, 0x1d, + 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x16, 0x12, 0x06, 0x91, 0x02, 0x00, 0x97, 0x02, 0x01, 0x0a, 0x0b, + 0x0a, 0x03, 0x04, 0x16, 0x01, 0x12, 0x04, 0x91, 0x02, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x16, 0x02, 0x00, 0x12, 0x04, 0x92, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, + 0x00, 0x05, 0x12, 0x04, 0x92, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x00, + 0x01, 0x12, 0x04, 0x92, 0x02, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x00, 0x03, + 0x12, 0x04, 0x92, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x01, 0x12, 0x04, + 0x93, 0x02, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x05, 0x12, 0x04, 0x93, + 0x02, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x01, 0x12, 0x04, 0x93, 0x02, + 0x08, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x01, 0x03, 0x12, 0x04, 0x93, 0x02, 0x19, + 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x02, 0x12, 0x04, 0x94, 0x02, 0x02, 0x19, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x02, 0x06, 0x12, 0x04, 0x94, 0x02, 0x02, 0x0f, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x16, 0x02, 0x02, 0x01, 0x12, 0x04, 0x94, 0x02, 0x10, 0x14, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x16, 0x02, 0x02, 0x03, 0x12, 0x04, 0x94, 0x02, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x16, 0x02, 0x03, 0x12, 0x04, 0x95, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, + 0x02, 0x03, 0x05, 0x12, 0x04, 0x95, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, + 0x03, 0x01, 0x12, 0x04, 0x95, 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x03, + 0x03, 0x12, 0x04, 0x95, 0x02, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x16, 0x02, 0x04, 0x12, + 0x04, 0x96, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x05, 0x12, 0x04, + 0x96, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x01, 0x12, 0x04, 0x96, + 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x16, 0x02, 0x04, 0x03, 0x12, 0x04, 0x96, 0x02, + 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x17, 0x12, 0x06, 0x99, 0x02, 0x00, 0x9e, 0x02, 0x01, + 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x17, 0x01, 0x12, 0x04, 0x99, 0x02, 0x08, 0x16, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x17, 0x02, 0x00, 0x12, 0x04, 0x9a, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x17, 0x02, 0x00, 0x05, 0x12, 0x04, 0x9a, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, + 0x02, 0x00, 0x01, 0x12, 0x04, 0x9a, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, + 0x00, 0x03, 0x12, 0x04, 0x9a, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x17, 0x02, 0x01, + 0x12, 0x04, 0x9b, 0x02, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x05, 0x12, + 0x04, 0x9b, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x01, 0x12, 0x04, + 0x9b, 0x02, 0x09, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x01, 0x03, 0x12, 0x04, 0x9b, + 0x02, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x17, 0x02, 0x02, 0x12, 0x04, 0x9c, 0x02, 0x02, + 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x05, 0x12, 0x04, 0x9c, 0x02, 0x02, 0x08, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x01, 0x12, 0x04, 0x9c, 0x02, 0x09, 0x0e, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x17, 0x02, 0x02, 0x03, 0x12, 0x04, 0x9c, 0x02, 0x11, 0x12, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x17, 0x02, 0x03, 0x12, 0x04, 0x9d, 0x02, 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x17, 0x02, 0x03, 0x05, 0x12, 0x04, 0x9d, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x17, 0x02, 0x03, 0x01, 0x12, 0x04, 0x9d, 0x02, 0x09, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x17, + 0x02, 0x03, 0x03, 0x12, 0x04, 0x9d, 0x02, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x18, 0x12, + 0x06, 0xa0, 0x02, 0x00, 0xa5, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x18, 0x01, 0x12, 0x04, + 0xa0, 0x02, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x00, 0x12, 0x04, 0xa1, 0x02, + 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa1, 0x02, 0x02, + 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa1, 0x02, 0x08, 0x16, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa1, 0x02, 0x19, 0x1a, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x01, 0x12, 0x04, 0xa2, 0x02, 0x02, 0x14, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x18, 0x02, 0x01, 0x05, 0x12, 0x04, 0xa2, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x18, 0x02, 0x01, 0x01, 0x12, 0x04, 0xa2, 0x02, 0x09, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x18, 0x02, 0x01, 0x03, 0x12, 0x04, 0xa2, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, + 0x02, 0x02, 0x12, 0x04, 0xa3, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, + 0x05, 0x12, 0x04, 0xa3, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xa3, 0x02, 0x09, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x02, 0x03, 0x12, + 0x04, 0xa3, 0x02, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x18, 0x02, 0x03, 0x12, 0x04, 0xa4, + 0x02, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x06, 0x12, 0x04, 0xa4, 0x02, + 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa4, 0x02, 0x11, + 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x18, 0x02, 0x03, 0x03, 0x12, 0x04, 0xa4, 0x02, 0x18, 0x19, + 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x19, 0x12, 0x06, 0xa7, 0x02, 0x00, 0xba, 0x02, 0x01, 0x0a, 0x0b, + 0x0a, 0x03, 0x04, 0x19, 0x01, 0x12, 0x04, 0xa7, 0x02, 0x08, 0x1a, 0x0a, 0x0e, 0x0a, 0x04, 0x04, + 0x19, 0x04, 0x00, 0x12, 0x06, 0xa8, 0x02, 0x02, 0xaf, 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x19, 0x04, 0x00, 0x01, 0x12, 0x04, 0xa8, 0x02, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, + 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xa9, 0x02, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, + 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa9, 0x02, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x19, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xa9, 0x02, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, + 0x04, 0x19, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xaa, 0x02, 0x04, 0x24, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x19, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xaa, 0x02, 0x04, 0x1f, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xaa, 0x02, 0x22, 0x23, 0x0a, 0x0e, + 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xab, 0x02, 0x04, 0x1c, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xab, 0x02, 0x04, 0x17, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xab, 0x02, 0x1a, 0x1b, + 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xac, 0x02, 0x04, 0x1f, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xac, 0x02, 0x04, + 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0xac, 0x02, + 0x1d, 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0xad, 0x02, + 0x04, 0x1e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0xad, + 0x02, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, + 0xad, 0x02, 0x1c, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x04, 0x00, 0x04, 0x12, 0x04, 0xae, + 0x02, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x19, 0x04, 0x00, 0x04, 0x00, 0x12, 0x04, 0xae, + 0x02, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x04, 0x00, 0x01, 0x12, 0x04, + 0xae, 0x02, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x19, 0x04, 0x00, 0x04, 0x00, 0x02, 0x12, + 0x04, 0xae, 0x02, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x00, 0x12, 0x04, 0xb1, + 0x02, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x00, 0x06, 0x12, 0x04, 0xb1, 0x02, + 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb1, 0x02, 0x07, + 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb1, 0x02, 0x0e, 0x0f, + 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x19, 0x08, 0x00, 0x12, 0x06, 0xb3, 0x02, 0x02, 0xb8, 0x02, 0x03, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x08, 0x00, 0x01, 0x12, 0x04, 0xb3, 0x02, 0x08, 0x0f, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x01, 0x12, 0x04, 0xb4, 0x02, 0x04, 0x34, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x19, 0x02, 0x01, 0x06, 0x12, 0x04, 0xb4, 0x02, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x19, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb4, 0x02, 0x19, 0x2f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x19, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb4, 0x02, 0x32, 0x33, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, + 0x02, 0x02, 0x12, 0x04, 0xb5, 0x02, 0x04, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x02, + 0x06, 0x12, 0x04, 0xb5, 0x02, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xb5, 0x02, 0x12, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x02, 0x03, 0x12, + 0x04, 0xb5, 0x02, 0x23, 0x24, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x03, 0x12, 0x04, 0xb6, + 0x02, 0x04, 0x2a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x03, 0x06, 0x12, 0x04, 0xb6, 0x02, + 0x04, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x03, 0x01, 0x12, 0x04, 0xb6, 0x02, 0x14, + 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x02, 0x03, 0x03, 0x12, 0x04, 0xb6, 0x02, 0x28, 0x29, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x02, 0x04, 0x12, 0x04, 0xb7, 0x02, 0x04, 0x29, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x19, 0x02, 0x04, 0x06, 0x12, 0x04, 0xb7, 0x02, 0x04, 0x13, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x19, 0x02, 0x04, 0x01, 0x12, 0x04, 0xb7, 0x02, 0x14, 0x24, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x19, 0x02, 0x04, 0x03, 0x12, 0x04, 0xb7, 0x02, 0x27, 0x28, 0x0a, 0x0b, 0x0a, 0x03, 0x04, + 0x19, 0x09, 0x12, 0x04, 0xb9, 0x02, 0x02, 0x0d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x19, 0x09, 0x00, + 0x12, 0x04, 0xb9, 0x02, 0x0b, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x09, 0x00, 0x01, 0x12, + 0x04, 0xb9, 0x02, 0x0b, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x19, 0x09, 0x00, 0x02, 0x12, 0x04, + 0xb9, 0x02, 0x0b, 0x0c, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1a, 0x12, 0x06, 0xbc, 0x02, 0x00, 0xc1, + 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1a, 0x01, 0x12, 0x04, 0xbc, 0x02, 0x08, 0x1c, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x1a, 0x02, 0x00, 0x12, 0x04, 0xbd, 0x02, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1a, 0x02, 0x00, 0x06, 0x12, 0x04, 0xbd, 0x02, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xbd, 0x02, 0x12, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x1a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xbd, 0x02, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1a, + 0x02, 0x01, 0x12, 0x04, 0xbe, 0x02, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, + 0x04, 0x12, 0x04, 0xbe, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x06, + 0x12, 0x04, 0xbe, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x01, 0x12, + 0x04, 0xbe, 0x02, 0x14, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x01, 0x03, 0x12, 0x04, + 0xbe, 0x02, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1a, 0x02, 0x02, 0x12, 0x04, 0xbf, 0x02, + 0x02, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x02, 0x04, 0x12, 0x04, 0xbf, 0x02, 0x02, + 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x02, 0x05, 0x12, 0x04, 0xbf, 0x02, 0x0b, 0x11, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x02, 0x01, 0x12, 0x04, 0xbf, 0x02, 0x12, 0x1b, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x1a, 0x02, 0x02, 0x03, 0x12, 0x04, 0xbf, 0x02, 0x1e, 0x1f, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x1a, 0x02, 0x03, 0x12, 0x04, 0xc0, 0x02, 0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1a, 0x02, 0x03, 0x05, 0x12, 0x04, 0xc0, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x1a, 0x02, 0x03, 0x01, 0x12, 0x04, 0xc0, 0x02, 0x09, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1a, + 0x02, 0x03, 0x03, 0x12, 0x04, 0xc0, 0x02, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1b, 0x12, + 0x06, 0xc3, 0x02, 0x00, 0xc6, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1b, 0x01, 0x12, 0x04, + 0xc3, 0x02, 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1b, 0x02, 0x00, 0x12, 0x04, 0xc4, 0x02, + 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x00, 0x05, 0x12, 0x04, 0xc4, 0x02, 0x02, + 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc4, 0x02, 0x08, 0x10, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1b, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc4, 0x02, 0x13, 0x14, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x1b, 0x02, 0x01, 0x12, 0x04, 0xc5, 0x02, 0x02, 0x17, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1b, 0x02, 0x01, 0x06, 0x12, 0x04, 0xc5, 0x02, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc5, 0x02, 0x0f, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x1b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc5, 0x02, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1c, + 0x12, 0x06, 0xc8, 0x02, 0x00, 0xcc, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1c, 0x01, 0x12, + 0x04, 0xc8, 0x02, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1c, 0x02, 0x00, 0x12, 0x04, 0xc9, + 0x02, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x06, 0x12, 0x04, 0xc9, 0x02, + 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc9, 0x02, 0x15, + 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc9, 0x02, 0x1c, 0x1d, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1c, 0x02, 0x01, 0x12, 0x04, 0xca, 0x02, 0x02, 0x27, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x01, 0x04, 0x12, 0x04, 0xca, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1c, 0x02, 0x01, 0x06, 0x12, 0x04, 0xca, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xca, 0x02, 0x14, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x1c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xca, 0x02, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1c, + 0x02, 0x02, 0x12, 0x04, 0xcb, 0x02, 0x02, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x02, + 0x04, 0x12, 0x04, 0xcb, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x02, 0x05, + 0x12, 0x04, 0xcb, 0x02, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x02, 0x01, 0x12, + 0x04, 0xcb, 0x02, 0x12, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1c, 0x02, 0x02, 0x03, 0x12, 0x04, + 0xcb, 0x02, 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1d, 0x12, 0x06, 0xce, 0x02, 0x00, 0xd1, + 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1d, 0x01, 0x12, 0x04, 0xce, 0x02, 0x08, 0x17, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x1d, 0x02, 0x00, 0x12, 0x04, 0xcf, 0x02, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1d, 0x02, 0x00, 0x05, 0x12, 0x04, 0xcf, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x1d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xcf, 0x02, 0x09, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x1d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xcf, 0x02, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1d, + 0x02, 0x01, 0x12, 0x04, 0xd0, 0x02, 0x02, 0x3e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, + 0x04, 0x12, 0x04, 0xd0, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, 0x06, + 0x12, 0x04, 0xd0, 0x02, 0x0b, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, 0x01, 0x12, + 0x04, 0xd0, 0x02, 0x26, 0x39, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1d, 0x02, 0x01, 0x03, 0x12, 0x04, + 0xd0, 0x02, 0x3c, 0x3d, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1e, 0x12, 0x06, 0xd3, 0x02, 0x00, 0xde, + 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1e, 0x01, 0x12, 0x04, 0xd3, 0x02, 0x08, 0x22, 0x0a, + 0x0e, 0x0a, 0x04, 0x04, 0x1e, 0x04, 0x00, 0x12, 0x06, 0xd4, 0x02, 0x02, 0xd7, 0x02, 0x03, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x04, 0x00, 0x01, 0x12, 0x04, 0xd4, 0x02, 0x07, 0x0b, 0x0a, 0x0e, + 0x0a, 0x06, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xd5, 0x02, 0x04, 0x19, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd5, 0x02, 0x04, 0x14, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xd5, 0x02, 0x17, 0x18, + 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xd6, 0x02, 0x04, 0x24, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd6, 0x02, 0x04, + 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x1e, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xd6, 0x02, + 0x22, 0x23, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1e, 0x02, 0x00, 0x12, 0x04, 0xd9, 0x02, 0x02, 0x10, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x00, 0x06, 0x12, 0x04, 0xd9, 0x02, 0x02, 0x06, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd9, 0x02, 0x07, 0x0b, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xd9, 0x02, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, + 0x04, 0x04, 0x1e, 0x08, 0x00, 0x12, 0x06, 0xdb, 0x02, 0x02, 0xdd, 0x02, 0x03, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x1e, 0x08, 0x00, 0x01, 0x12, 0x04, 0xdb, 0x02, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x1e, 0x02, 0x01, 0x12, 0x04, 0xdc, 0x02, 0x04, 0x34, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, + 0x02, 0x01, 0x06, 0x12, 0x04, 0xdc, 0x02, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, + 0x01, 0x01, 0x12, 0x04, 0xdc, 0x02, 0x19, 0x2f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1e, 0x02, 0x01, + 0x03, 0x12, 0x04, 0xdc, 0x02, 0x32, 0x33, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x1f, 0x12, 0x06, 0xe0, + 0x02, 0x00, 0xe3, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x1f, 0x01, 0x12, 0x04, 0xe0, 0x02, + 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x1f, 0x02, 0x00, 0x12, 0x04, 0xe1, 0x02, 0x02, 0x15, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x00, 0x05, 0x12, 0x04, 0xe1, 0x02, 0x02, 0x07, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe1, 0x02, 0x08, 0x10, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x1f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe1, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x1f, 0x02, 0x01, 0x12, 0x04, 0xe2, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x1f, 0x02, 0x01, 0x06, 0x12, 0x04, 0xe2, 0x02, 0x02, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, + 0x02, 0x01, 0x01, 0x12, 0x04, 0xe2, 0x02, 0x0d, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x1f, 0x02, + 0x01, 0x03, 0x12, 0x04, 0xe2, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x20, 0x12, 0x06, + 0xe5, 0x02, 0x00, 0xeb, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x20, 0x01, 0x12, 0x04, 0xe5, + 0x02, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x20, 0x02, 0x00, 0x12, 0x04, 0xe6, 0x02, 0x02, + 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x00, 0x05, 0x12, 0x04, 0xe6, 0x02, 0x02, 0x08, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe6, 0x02, 0x09, 0x10, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe6, 0x02, 0x13, 0x14, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x20, 0x02, 0x01, 0x12, 0x04, 0xe7, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x20, 0x02, 0x01, 0x05, 0x12, 0x04, 0xe7, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x20, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe7, 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, + 0x02, 0x01, 0x03, 0x12, 0x04, 0xe7, 0x02, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x20, 0x02, + 0x02, 0x12, 0x04, 0xe8, 0x02, 0x02, 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x02, 0x04, + 0x12, 0x04, 0xe8, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x02, 0x06, 0x12, + 0x04, 0xe8, 0x02, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x02, 0x01, 0x12, 0x04, + 0xe8, 0x02, 0x18, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x02, 0x03, 0x12, 0x04, 0xe8, + 0x02, 0x22, 0x23, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x20, 0x02, 0x03, 0x12, 0x04, 0xe9, 0x02, 0x02, + 0x2e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x03, 0x04, 0x12, 0x04, 0xe9, 0x02, 0x02, 0x0a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x03, 0x06, 0x12, 0x04, 0xe9, 0x02, 0x0b, 0x17, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x03, 0x01, 0x12, 0x04, 0xe9, 0x02, 0x18, 0x29, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x20, 0x02, 0x03, 0x03, 0x12, 0x04, 0xe9, 0x02, 0x2c, 0x2d, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x20, 0x02, 0x04, 0x12, 0x04, 0xea, 0x02, 0x02, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x20, 0x02, 0x04, 0x04, 0x12, 0x04, 0xea, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, + 0x02, 0x04, 0x06, 0x12, 0x04, 0xea, 0x02, 0x0b, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, + 0x04, 0x01, 0x12, 0x04, 0xea, 0x02, 0x16, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x20, 0x02, 0x04, + 0x03, 0x12, 0x04, 0xea, 0x02, 0x20, 0x21, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x21, 0x12, 0x06, 0xec, + 0x02, 0x00, 0xf9, 0x02, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x21, 0x01, 0x12, 0x04, 0xec, 0x02, + 0x08, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x21, 0x04, 0x00, 0x12, 0x06, 0xed, 0x02, 0x02, 0xf2, + 0x02, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x04, 0x00, 0x01, 0x12, 0x04, 0xed, 0x02, 0x07, + 0x11, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x21, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xee, 0x02, 0x04, + 0x1f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xee, 0x02, + 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xee, + 0x02, 0x1d, 0x1e, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x21, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xef, + 0x02, 0x04, 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, + 0xef, 0x02, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, + 0x04, 0xef, 0x02, 0x19, 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x21, 0x04, 0x00, 0x02, 0x02, 0x12, + 0x04, 0xf0, 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xf0, 0x02, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, 0x02, + 0x02, 0x12, 0x04, 0xf0, 0x02, 0x18, 0x19, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x21, 0x04, 0x00, 0x02, + 0x03, 0x12, 0x04, 0xf1, 0x02, 0x04, 0x1a, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, 0x02, + 0x03, 0x01, 0x12, 0x04, 0xf1, 0x02, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x21, 0x04, 0x00, + 0x02, 0x03, 0x02, 0x12, 0x04, 0xf1, 0x02, 0x18, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, + 0x00, 0x12, 0x04, 0xf3, 0x02, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x05, + 0x12, 0x04, 0xf3, 0x02, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x01, 0x12, + 0x04, 0xf3, 0x02, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x00, 0x03, 0x12, 0x04, + 0xf3, 0x02, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x01, 0x12, 0x04, 0xf4, 0x02, + 0x02, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x01, 0x06, 0x12, 0x04, 0xf4, 0x02, 0x02, + 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf4, 0x02, 0x1a, 0x24, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf4, 0x02, 0x27, 0x28, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x02, 0x12, 0x04, 0xf5, 0x02, 0x02, 0x14, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x21, 0x02, 0x02, 0x05, 0x12, 0x04, 0xf5, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x21, 0x02, 0x02, 0x01, 0x12, 0x04, 0xf5, 0x02, 0x07, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x21, 0x02, 0x02, 0x03, 0x12, 0x04, 0xf5, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, + 0x02, 0x03, 0x12, 0x04, 0xf6, 0x02, 0x02, 0x40, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, + 0x04, 0x12, 0x04, 0xf6, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x06, + 0x12, 0x04, 0xf6, 0x02, 0x0b, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x01, 0x12, + 0x04, 0xf6, 0x02, 0x28, 0x3b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x03, 0x03, 0x12, 0x04, + 0xf6, 0x02, 0x3e, 0x3f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x21, 0x02, 0x04, 0x12, 0x04, 0xf7, 0x02, + 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, 0x04, 0x12, 0x04, 0xf7, 0x02, 0x02, + 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, 0x06, 0x12, 0x04, 0xf7, 0x02, 0x0b, 0x13, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, 0x01, 0x12, 0x04, 0xf7, 0x02, 0x14, 0x1a, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, 0x04, 0x03, 0x12, 0x04, 0xf7, 0x02, 0x1d, 0x1e, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x21, 0x02, 0x05, 0x12, 0x04, 0xf8, 0x02, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x21, 0x02, 0x05, 0x04, 0x12, 0x04, 0xf8, 0x02, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x21, 0x02, 0x05, 0x06, 0x12, 0x04, 0xf8, 0x02, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, + 0x02, 0x05, 0x01, 0x12, 0x04, 0xf8, 0x02, 0x14, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x21, 0x02, + 0x05, 0x03, 0x12, 0x04, 0xf8, 0x02, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x22, 0x12, 0x06, + 0xfb, 0x02, 0x00, 0x82, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x22, 0x01, 0x12, 0x04, 0xfb, + 0x02, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x00, 0x12, 0x04, 0xfc, 0x02, 0x02, + 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x05, 0x12, 0x04, 0xfc, 0x02, 0x02, 0x08, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x01, 0x12, 0x04, 0xfc, 0x02, 0x09, 0x0d, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x00, 0x03, 0x12, 0x04, 0xfc, 0x02, 0x10, 0x11, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x22, 0x02, 0x01, 0x12, 0x04, 0xfd, 0x02, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x22, 0x02, 0x01, 0x05, 0x12, 0x04, 0xfd, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x22, 0x02, 0x01, 0x01, 0x12, 0x04, 0xfd, 0x02, 0x07, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, + 0x02, 0x01, 0x03, 0x12, 0x04, 0xfd, 0x02, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, + 0x02, 0x12, 0x04, 0xfe, 0x02, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x02, 0x05, + 0x12, 0x04, 0xfe, 0x02, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x02, 0x01, 0x12, + 0x04, 0xfe, 0x02, 0x07, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x02, 0x03, 0x12, 0x04, + 0xfe, 0x02, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x03, 0x12, 0x04, 0xff, 0x02, + 0x02, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x04, 0x12, 0x04, 0xff, 0x02, 0x02, + 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x06, 0x12, 0x04, 0xff, 0x02, 0x0b, 0x16, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x01, 0x12, 0x04, 0xff, 0x02, 0x17, 0x20, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x03, 0x03, 0x12, 0x04, 0xff, 0x02, 0x23, 0x24, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x22, 0x02, 0x04, 0x12, 0x04, 0x80, 0x03, 0x02, 0x3e, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x22, 0x02, 0x04, 0x04, 0x12, 0x04, 0x80, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x22, 0x02, 0x04, 0x06, 0x12, 0x04, 0x80, 0x03, 0x0b, 0x25, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, + 0x02, 0x04, 0x01, 0x12, 0x04, 0x80, 0x03, 0x26, 0x39, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, + 0x04, 0x03, 0x12, 0x04, 0x80, 0x03, 0x3c, 0x3d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x22, 0x02, 0x05, + 0x12, 0x04, 0x81, 0x03, 0x02, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, 0x04, 0x12, + 0x04, 0x81, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, 0x06, 0x12, 0x04, + 0x81, 0x03, 0x0b, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, 0x01, 0x12, 0x04, 0x81, + 0x03, 0x1b, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x22, 0x02, 0x05, 0x03, 0x12, 0x04, 0x81, 0x03, + 0x24, 0x25, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x23, 0x12, 0x06, 0x84, 0x03, 0x00, 0x87, 0x03, 0x01, + 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x23, 0x01, 0x12, 0x04, 0x84, 0x03, 0x08, 0x22, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x23, 0x02, 0x00, 0x12, 0x04, 0x85, 0x03, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x23, 0x02, 0x00, 0x04, 0x12, 0x04, 0x85, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, + 0x02, 0x00, 0x06, 0x12, 0x04, 0x85, 0x03, 0x0b, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, + 0x00, 0x01, 0x12, 0x04, 0x85, 0x03, 0x17, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x00, + 0x03, 0x12, 0x04, 0x85, 0x03, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x23, 0x02, 0x01, 0x12, + 0x04, 0x86, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x01, 0x05, 0x12, 0x04, + 0x86, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x01, 0x01, 0x12, 0x04, 0x86, + 0x03, 0x07, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x23, 0x02, 0x01, 0x03, 0x12, 0x04, 0x86, 0x03, + 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x24, 0x12, 0x06, 0x89, 0x03, 0x00, 0x8c, 0x03, 0x01, + 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x24, 0x01, 0x12, 0x04, 0x89, 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x24, 0x02, 0x00, 0x12, 0x04, 0x8a, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x24, 0x02, 0x00, 0x05, 0x12, 0x04, 0x8a, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, + 0x02, 0x00, 0x01, 0x12, 0x04, 0x8a, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, + 0x00, 0x03, 0x12, 0x04, 0x8a, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x24, 0x02, 0x01, + 0x12, 0x04, 0x8b, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x06, 0x12, + 0x04, 0x8b, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x01, 0x12, 0x04, + 0x8b, 0x03, 0x0b, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x24, 0x02, 0x01, 0x03, 0x12, 0x04, 0x8b, + 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x25, 0x12, 0x06, 0x8e, 0x03, 0x00, 0x90, 0x03, + 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x25, 0x01, 0x12, 0x04, 0x8e, 0x03, 0x08, 0x24, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x25, 0x02, 0x00, 0x12, 0x04, 0x8f, 0x03, 0x02, 0x27, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x25, 0x02, 0x00, 0x04, 0x12, 0x04, 0x8f, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x25, 0x02, 0x00, 0x06, 0x12, 0x04, 0x8f, 0x03, 0x0b, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, + 0x02, 0x00, 0x01, 0x12, 0x04, 0x8f, 0x03, 0x17, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x25, 0x02, + 0x00, 0x03, 0x12, 0x04, 0x8f, 0x03, 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x06, + 0x92, 0x03, 0x00, 0xa2, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x04, 0x92, + 0x03, 0x05, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x00, 0x12, 0x04, 0x93, 0x03, 0x02, + 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x93, 0x03, 0x02, 0x18, + 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0x93, 0x03, 0x1b, 0x1c, 0x0a, + 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x01, 0x12, 0x04, 0x94, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, + 0x05, 0x05, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0x94, 0x03, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, + 0x05, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0x94, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, + 0x00, 0x02, 0x02, 0x12, 0x04, 0x95, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, + 0x02, 0x01, 0x12, 0x04, 0x95, 0x03, 0x02, 0x0f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x02, + 0x02, 0x12, 0x04, 0x95, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x03, 0x12, + 0x04, 0x96, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, + 0x96, 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0x96, + 0x03, 0x13, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x04, 0x12, 0x04, 0x97, 0x03, 0x02, + 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0x97, 0x03, 0x02, 0x10, + 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0x97, 0x03, 0x13, 0x15, 0x0a, + 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x05, 0x12, 0x04, 0x98, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, + 0x05, 0x05, 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0x98, 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, + 0x05, 0x00, 0x02, 0x05, 0x02, 0x12, 0x04, 0x98, 0x03, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x05, + 0x00, 0x02, 0x06, 0x12, 0x04, 0x99, 0x03, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, + 0x06, 0x01, 0x12, 0x04, 0x99, 0x03, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x06, + 0x02, 0x12, 0x04, 0x99, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x07, 0x12, + 0x04, 0x9a, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x07, 0x01, 0x12, 0x04, + 0x9a, 0x03, 0x02, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x07, 0x02, 0x12, 0x04, 0x9a, + 0x03, 0x14, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x08, 0x12, 0x04, 0x9b, 0x03, 0x02, + 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x08, 0x01, 0x12, 0x04, 0x9b, 0x03, 0x02, 0x14, + 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x08, 0x02, 0x12, 0x04, 0x9b, 0x03, 0x17, 0x18, 0x0a, + 0x0c, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x09, 0x12, 0x04, 0x9c, 0x03, 0x02, 0x18, 0x0a, 0x0d, 0x0a, + 0x05, 0x05, 0x00, 0x02, 0x09, 0x01, 0x12, 0x04, 0x9c, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, + 0x05, 0x00, 0x02, 0x09, 0x02, 0x12, 0x04, 0x9c, 0x03, 0x16, 0x17, 0x0a, 0x2b, 0x0a, 0x04, 0x05, + 0x00, 0x02, 0x0a, 0x12, 0x04, 0x9d, 0x03, 0x02, 0x18, 0x22, 0x1d, 0x20, 0x60, 0x7b, 0x20, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x3a, 0x20, 0x42, 0x6f, 0x78, 0x3c, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x3e, 0x20, 0x7d, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0a, + 0x01, 0x12, 0x04, 0x9d, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0a, 0x02, + 0x12, 0x04, 0x9d, 0x03, 0x16, 0x17, 0x0a, 0x22, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0b, 0x12, 0x04, + 0x9e, 0x03, 0x02, 0x18, 0x22, 0x14, 0x20, 0x60, 0x28, 0x4d, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x54, 0x61, 0x67, 0x29, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, + 0x02, 0x0b, 0x01, 0x12, 0x04, 0x9e, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, + 0x0b, 0x02, 0x12, 0x04, 0x9e, 0x03, 0x16, 0x17, 0x0a, 0x22, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0c, + 0x12, 0x04, 0x9f, 0x03, 0x02, 0x24, 0x22, 0x14, 0x20, 0x60, 0x7b, 0x20, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x3a, 0x20, 0x75, 0x31, 0x36, 0x20, 0x7d, 0x60, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, + 0x05, 0x00, 0x02, 0x0c, 0x01, 0x12, 0x04, 0x9f, 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, + 0x00, 0x02, 0x0c, 0x02, 0x12, 0x04, 0x9f, 0x03, 0x22, 0x23, 0x0a, 0x37, 0x0a, 0x04, 0x05, 0x00, + 0x02, 0x0d, 0x12, 0x04, 0xa0, 0x03, 0x02, 0x1c, 0x22, 0x29, 0x20, 0x60, 0x7b, 0x20, 0x6d, 0x75, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x2c, 0x20, 0x74, 0x6f, 0x3a, + 0x20, 0x42, 0x6f, 0x78, 0x3c, 0x4d, 0x6f, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3e, 0x20, 0x7d, + 0x60, 0x2c, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0d, 0x01, 0x12, 0x04, 0xa0, 0x03, + 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0d, 0x02, 0x12, 0x04, 0xa0, 0x03, 0x19, + 0x1b, 0x0a, 0x1b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x0e, 0x12, 0x04, 0xa1, 0x03, 0x02, 0x1d, 0x22, + 0x0d, 0x20, 0x60, 0x28, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x29, 0x60, 0x2c, 0x0a, 0x0a, 0x0d, + 0x0a, 0x05, 0x05, 0x00, 0x02, 0x0e, 0x01, 0x12, 0x04, 0xa1, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, + 0x05, 0x05, 0x00, 0x02, 0x0e, 0x02, 0x12, 0x04, 0xa1, 0x03, 0x1a, 0x1c, 0x0a, 0x0c, 0x0a, 0x02, + 0x04, 0x26, 0x12, 0x06, 0xa4, 0x03, 0x00, 0xb2, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x26, + 0x01, 0x12, 0x04, 0xa4, 0x03, 0x08, 0x10, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x26, 0x03, 0x00, 0x12, + 0x06, 0xa5, 0x03, 0x02, 0xa8, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x03, 0x00, 0x01, + 0x12, 0x04, 0xa5, 0x03, 0x0a, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x26, 0x03, 0x00, 0x02, 0x00, + 0x12, 0x04, 0xa6, 0x03, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, 0x00, 0x02, 0x00, + 0x05, 0x12, 0x04, 0xa6, 0x03, 0x04, 0x08, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, 0x00, 0x02, + 0x00, 0x01, 0x12, 0x04, 0xa6, 0x03, 0x09, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, 0x00, + 0x02, 0x00, 0x03, 0x12, 0x04, 0xa6, 0x03, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x26, 0x03, + 0x00, 0x02, 0x01, 0x12, 0x04, 0xa7, 0x03, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, 0x03, + 0x00, 0x02, 0x01, 0x06, 0x12, 0x04, 0xa7, 0x03, 0x04, 0x0c, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x26, + 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xa7, 0x03, 0x0d, 0x0f, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x26, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x04, 0xa7, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x26, 0x02, 0x00, 0x12, 0x04, 0xaa, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, + 0x02, 0x00, 0x06, 0x12, 0x04, 0xaa, 0x03, 0x02, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, + 0x00, 0x01, 0x12, 0x04, 0xaa, 0x03, 0x0c, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x00, + 0x03, 0x12, 0x04, 0xaa, 0x03, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x26, 0x08, 0x00, 0x12, + 0x06, 0xab, 0x03, 0x02, 0xb1, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x08, 0x00, 0x01, + 0x12, 0x04, 0xab, 0x03, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, 0x02, 0x01, 0x12, 0x04, + 0xac, 0x03, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x01, 0x06, 0x12, 0x04, 0xac, + 0x03, 0x04, 0x0c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x01, 0x01, 0x12, 0x04, 0xac, 0x03, + 0x0d, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x01, 0x03, 0x12, 0x04, 0xac, 0x03, 0x16, + 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, 0x02, 0x02, 0x12, 0x04, 0xad, 0x03, 0x04, 0x1d, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x02, 0x06, 0x12, 0x04, 0xad, 0x03, 0x04, 0x11, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x26, 0x02, 0x02, 0x01, 0x12, 0x04, 0xad, 0x03, 0x12, 0x18, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x26, 0x02, 0x02, 0x03, 0x12, 0x04, 0xad, 0x03, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x26, 0x02, 0x03, 0x12, 0x04, 0xae, 0x03, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, + 0x02, 0x03, 0x05, 0x12, 0x04, 0xae, 0x03, 0x04, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, + 0x03, 0x01, 0x12, 0x04, 0xae, 0x03, 0x0b, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x03, + 0x03, 0x12, 0x04, 0xae, 0x03, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, 0x02, 0x04, 0x12, + 0x04, 0xaf, 0x03, 0x04, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x04, 0x06, 0x12, 0x04, + 0xaf, 0x03, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x04, 0x01, 0x12, 0x04, 0xaf, + 0x03, 0x12, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x04, 0x03, 0x12, 0x04, 0xaf, 0x03, + 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x26, 0x02, 0x05, 0x12, 0x04, 0xb0, 0x03, 0x04, 0x1a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x05, 0x05, 0x12, 0x04, 0xb0, 0x03, 0x04, 0x0a, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x26, 0x02, 0x05, 0x01, 0x12, 0x04, 0xb0, 0x03, 0x0b, 0x15, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x26, 0x02, 0x05, 0x03, 0x12, 0x04, 0xb0, 0x03, 0x18, 0x19, 0x0a, 0x0c, 0x0a, + 0x02, 0x05, 0x01, 0x12, 0x06, 0xb4, 0x03, 0x00, 0xba, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x05, + 0x01, 0x01, 0x12, 0x04, 0xb4, 0x03, 0x05, 0x10, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x00, + 0x12, 0x04, 0xb5, 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x00, 0x01, 0x12, + 0x04, 0xb5, 0x03, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x00, 0x02, 0x12, 0x04, + 0xb5, 0x03, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x01, 0x12, 0x04, 0xb6, 0x03, + 0x02, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb6, 0x03, 0x02, + 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x01, 0x02, 0x12, 0x04, 0xb6, 0x03, 0x16, 0x17, + 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x02, 0x12, 0x04, 0xb7, 0x03, 0x02, 0x18, 0x0a, 0x0d, + 0x0a, 0x05, 0x05, 0x01, 0x02, 0x02, 0x01, 0x12, 0x04, 0xb7, 0x03, 0x02, 0x13, 0x0a, 0x0d, 0x0a, + 0x05, 0x05, 0x01, 0x02, 0x02, 0x02, 0x12, 0x04, 0xb7, 0x03, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, + 0x05, 0x01, 0x02, 0x03, 0x12, 0x04, 0xb8, 0x03, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, + 0x02, 0x03, 0x01, 0x12, 0x04, 0xb8, 0x03, 0x02, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, + 0x03, 0x02, 0x12, 0x04, 0xb8, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x05, 0x01, 0x02, 0x04, + 0x12, 0x04, 0xb9, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x04, 0x01, 0x12, + 0x04, 0xb9, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x05, 0x01, 0x02, 0x04, 0x02, 0x12, 0x04, + 0xb9, 0x03, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x27, 0x12, 0x06, 0xbc, 0x03, 0x00, 0xbe, + 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x27, 0x01, 0x12, 0x04, 0xbc, 0x03, 0x08, 0x17, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x27, 0x02, 0x00, 0x12, 0x04, 0xbd, 0x03, 0x02, 0x19, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x27, 0x02, 0x00, 0x06, 0x12, 0x04, 0xbd, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x27, 0x02, 0x00, 0x01, 0x12, 0x04, 0xbd, 0x03, 0x0b, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x27, 0x02, 0x00, 0x03, 0x12, 0x04, 0xbd, 0x03, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x28, + 0x12, 0x06, 0xc0, 0x03, 0x00, 0xc3, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x28, 0x01, 0x12, + 0x04, 0xc0, 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x28, 0x02, 0x00, 0x12, 0x04, 0xc1, + 0x03, 0x02, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, 0x00, 0x06, 0x12, 0x04, 0xc1, 0x03, + 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc1, 0x03, 0x0f, + 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x28, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc1, 0x03, 0x18, 0x19, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x28, 0x02, 0x01, 0x12, 0x04, 0xc2, 0x03, 0x02, 0x12, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x28, 0x02, 0x01, 0x05, 0x12, 0x04, 0xc2, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x28, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc2, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x28, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc2, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, 0x04, + 0x29, 0x12, 0x06, 0xc5, 0x03, 0x00, 0xc8, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x29, 0x01, + 0x12, 0x04, 0xc5, 0x03, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x29, 0x02, 0x00, 0x12, 0x04, + 0xc6, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x05, 0x12, 0x04, 0xc6, + 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc6, 0x03, + 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc6, 0x03, 0x13, + 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x29, 0x02, 0x01, 0x12, 0x04, 0xc7, 0x03, 0x02, 0x12, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x29, 0x02, 0x01, 0x05, 0x12, 0x04, 0xc7, 0x03, 0x02, 0x08, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x29, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc7, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x29, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc7, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x02, + 0x04, 0x2a, 0x12, 0x06, 0xca, 0x03, 0x00, 0xcf, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2a, + 0x01, 0x12, 0x04, 0xca, 0x03, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2a, 0x02, 0x00, 0x12, + 0x04, 0xcb, 0x03, 0x02, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x05, 0x12, 0x04, + 0xcb, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x01, 0x12, 0x04, 0xcb, + 0x03, 0x09, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xcb, 0x03, + 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2a, 0x02, 0x01, 0x12, 0x04, 0xcc, 0x03, 0x02, 0x14, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x01, 0x05, 0x12, 0x04, 0xcc, 0x03, 0x02, 0x08, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x01, 0x01, 0x12, 0x04, 0xcc, 0x03, 0x09, 0x0f, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x01, 0x03, 0x12, 0x04, 0xcc, 0x03, 0x12, 0x13, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x2a, 0x02, 0x02, 0x12, 0x04, 0xcd, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x2a, 0x02, 0x02, 0x05, 0x12, 0x04, 0xcd, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, + 0x02, 0x02, 0x01, 0x12, 0x04, 0xcd, 0x03, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, + 0x02, 0x03, 0x12, 0x04, 0xcd, 0x03, 0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2a, 0x02, 0x03, + 0x12, 0x04, 0xce, 0x03, 0x02, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x03, 0x04, 0x12, + 0x04, 0xce, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x03, 0x06, 0x12, 0x04, + 0xce, 0x03, 0x0b, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x03, 0x01, 0x12, 0x04, 0xce, + 0x03, 0x14, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2a, 0x02, 0x03, 0x03, 0x12, 0x04, 0xce, 0x03, + 0x2a, 0x2b, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2b, 0x12, 0x06, 0xd1, 0x03, 0x00, 0xe5, 0x03, 0x01, + 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2b, 0x01, 0x12, 0x04, 0xd1, 0x03, 0x08, 0x11, 0x0a, 0x0e, 0x0a, + 0x04, 0x04, 0x2b, 0x04, 0x00, 0x12, 0x06, 0xd2, 0x03, 0x02, 0xda, 0x03, 0x03, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x2b, 0x04, 0x00, 0x01, 0x12, 0x04, 0xd2, 0x03, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, + 0x04, 0x2b, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xd3, 0x03, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x2b, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd3, 0x03, 0x04, 0x14, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xd3, 0x03, 0x17, 0x18, 0x0a, 0x0e, + 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xd4, 0x03, 0x04, 0x15, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd4, 0x03, 0x04, 0x10, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xd4, 0x03, 0x13, 0x14, + 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xd5, 0x03, 0x04, 0x1b, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xd5, 0x03, 0x04, + 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xd5, 0x03, + 0x19, 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xd6, 0x03, + 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0xd6, + 0x03, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, + 0xd6, 0x03, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, + 0xd7, 0x03, 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, + 0x04, 0xd7, 0x03, 0x04, 0x12, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x04, 0x02, + 0x12, 0x04, 0xd7, 0x03, 0x15, 0x16, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x05, + 0x12, 0x04, 0xd8, 0x03, 0x04, 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, 0x05, + 0x01, 0x12, 0x04, 0xd8, 0x03, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x02, + 0x05, 0x02, 0x12, 0x04, 0xd8, 0x03, 0x19, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x04, 0x00, + 0x04, 0x12, 0x04, 0xd9, 0x03, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x2b, 0x04, 0x00, 0x04, + 0x00, 0x12, 0x04, 0xd9, 0x03, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, 0x04, + 0x00, 0x01, 0x12, 0x04, 0xd9, 0x03, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x2b, 0x04, 0x00, + 0x04, 0x00, 0x02, 0x12, 0x04, 0xd9, 0x03, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, + 0x00, 0x12, 0x04, 0xdc, 0x03, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x06, + 0x12, 0x04, 0xdc, 0x03, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x01, 0x12, + 0x04, 0xdc, 0x03, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x00, 0x03, 0x12, 0x04, + 0xdc, 0x03, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x2b, 0x08, 0x00, 0x12, 0x06, 0xdd, 0x03, + 0x02, 0xe4, 0x03, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x08, 0x00, 0x01, 0x12, 0x04, 0xdd, + 0x03, 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x01, 0x12, 0x04, 0xde, 0x03, 0x04, + 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x01, 0x06, 0x12, 0x04, 0xde, 0x03, 0x04, 0x14, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xde, 0x03, 0x15, 0x1c, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xde, 0x03, 0x1f, 0x20, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x02, 0x12, 0x04, 0xdf, 0x03, 0x04, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x2b, 0x02, 0x02, 0x06, 0x12, 0x04, 0xdf, 0x03, 0x04, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x2b, 0x02, 0x02, 0x01, 0x12, 0x04, 0xdf, 0x03, 0x1a, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, + 0x02, 0x02, 0x03, 0x12, 0x04, 0xdf, 0x03, 0x2a, 0x2b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, + 0x03, 0x12, 0x04, 0xe0, 0x03, 0x04, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x06, + 0x12, 0x04, 0xe0, 0x03, 0x04, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x01, 0x12, + 0x04, 0xe0, 0x03, 0x18, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x03, 0x03, 0x12, 0x04, + 0xe0, 0x03, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x04, 0x12, 0x04, 0xe1, 0x03, + 0x04, 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x04, 0x06, 0x12, 0x04, 0xe1, 0x03, 0x04, + 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x04, 0x01, 0x12, 0x04, 0xe1, 0x03, 0x16, 0x1f, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x04, 0x03, 0x12, 0x04, 0xe1, 0x03, 0x22, 0x23, 0x0a, + 0x1e, 0x0a, 0x04, 0x04, 0x2b, 0x02, 0x05, 0x12, 0x04, 0xe3, 0x03, 0x04, 0x23, 0x1a, 0x10, 0x20, + 0x36, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x05, 0x06, 0x12, 0x04, 0xe3, 0x03, 0x04, 0x10, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2b, 0x02, 0x05, 0x01, 0x12, 0x04, 0xe3, 0x03, 0x11, 0x1e, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x2b, 0x02, 0x05, 0x03, 0x12, 0x04, 0xe3, 0x03, 0x21, 0x22, 0x0a, 0x0c, 0x0a, 0x02, + 0x04, 0x2c, 0x12, 0x06, 0xe7, 0x03, 0x00, 0xea, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2c, + 0x01, 0x12, 0x04, 0xe7, 0x03, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x00, 0x12, + 0x04, 0xe8, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x05, 0x12, 0x04, + 0xe8, 0x03, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x01, 0x12, 0x04, 0xe8, + 0x03, 0x08, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe8, 0x03, + 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2c, 0x02, 0x01, 0x12, 0x04, 0xe9, 0x03, 0x02, 0x16, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x01, 0x05, 0x12, 0x04, 0xe9, 0x03, 0x02, 0x07, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe9, 0x03, 0x08, 0x11, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xe9, 0x03, 0x14, 0x15, 0x0a, 0x0c, 0x0a, + 0x02, 0x04, 0x2d, 0x12, 0x06, 0xec, 0x03, 0x00, 0xf1, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, + 0x2d, 0x01, 0x12, 0x04, 0xec, 0x03, 0x08, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x00, + 0x12, 0x04, 0xed, 0x03, 0x02, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x04, 0x12, + 0x04, 0xed, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x05, 0x12, 0x04, + 0xed, 0x03, 0x0b, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xed, + 0x03, 0x11, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xed, 0x03, + 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x01, 0x12, 0x04, 0xee, 0x03, 0x02, 0x20, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x01, 0x04, 0x12, 0x04, 0xee, 0x03, 0x02, 0x0a, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x01, 0x05, 0x12, 0x04, 0xee, 0x03, 0x0b, 0x10, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x01, 0x01, 0x12, 0x04, 0xee, 0x03, 0x11, 0x1b, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x2d, 0x02, 0x01, 0x03, 0x12, 0x04, 0xee, 0x03, 0x1e, 0x1f, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x2d, 0x02, 0x02, 0x12, 0x04, 0xef, 0x03, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, + 0x02, 0x02, 0x05, 0x12, 0x04, 0xef, 0x03, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, + 0x02, 0x01, 0x12, 0x04, 0xef, 0x03, 0x09, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x02, + 0x03, 0x12, 0x04, 0xef, 0x03, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2d, 0x02, 0x03, 0x12, + 0x04, 0xf0, 0x03, 0x02, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x03, 0x04, 0x12, 0x04, + 0xf0, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x03, 0x05, 0x12, 0x04, 0xf0, + 0x03, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x03, 0x01, 0x12, 0x04, 0xf0, 0x03, + 0x12, 0x24, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2d, 0x02, 0x03, 0x03, 0x12, 0x04, 0xf0, 0x03, 0x27, + 0x28, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x2e, 0x12, 0x06, 0xf3, 0x03, 0x00, 0xf7, 0x03, 0x01, 0x0a, + 0x0b, 0x0a, 0x03, 0x04, 0x2e, 0x01, 0x12, 0x04, 0xf3, 0x03, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x2e, 0x02, 0x00, 0x12, 0x04, 0xf4, 0x03, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, + 0x02, 0x00, 0x06, 0x12, 0x04, 0xf4, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, + 0x00, 0x01, 0x12, 0x04, 0xf4, 0x03, 0x13, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x00, + 0x03, 0x12, 0x04, 0xf4, 0x03, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x01, 0x12, + 0x04, 0xf5, 0x03, 0x02, 0x31, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x01, 0x04, 0x12, 0x04, + 0xf5, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf5, + 0x03, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf5, 0x03, + 0x12, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x01, 0x03, 0x12, 0x04, 0xf5, 0x03, 0x2f, + 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2e, 0x02, 0x02, 0x12, 0x04, 0xf6, 0x03, 0x02, 0x32, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x02, 0x04, 0x12, 0x04, 0xf6, 0x03, 0x02, 0x0a, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2e, 0x02, 0x02, 0x06, 0x12, 0x04, 0xf6, 0x03, 0x0b, 0x1b, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x2e, 0x02, 0x02, 0x01, 0x12, 0x04, 0xf6, 0x03, 0x1c, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x2e, 0x02, 0x02, 0x03, 0x12, 0x04, 0xf6, 0x03, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x02, 0x04, + 0x2f, 0x12, 0x06, 0xf9, 0x03, 0x00, 0xff, 0x03, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x2f, 0x01, + 0x12, 0x04, 0xf9, 0x03, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x00, 0x12, 0x04, + 0xfa, 0x03, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x06, 0x12, 0x04, 0xfa, + 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x01, 0x12, 0x04, 0xfa, 0x03, + 0x13, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x00, 0x03, 0x12, 0x04, 0xfa, 0x03, 0x1c, + 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x01, 0x12, 0x04, 0xfb, 0x03, 0x02, 0x31, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x04, 0x12, 0x04, 0xfb, 0x03, 0x02, 0x0a, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x01, 0x05, 0x12, 0x04, 0xfb, 0x03, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x2f, 0x02, 0x01, 0x01, 0x12, 0x04, 0xfb, 0x03, 0x12, 0x2c, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x2f, 0x02, 0x01, 0x03, 0x12, 0x04, 0xfb, 0x03, 0x2f, 0x30, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x2f, 0x02, 0x02, 0x12, 0x04, 0xfc, 0x03, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, + 0x02, 0x04, 0x12, 0x04, 0xfc, 0x03, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x02, + 0x06, 0x12, 0x04, 0xfc, 0x03, 0x0b, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x02, 0x01, + 0x12, 0x04, 0xfc, 0x03, 0x1c, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x02, 0x03, 0x12, + 0x04, 0xfc, 0x03, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x03, 0x12, 0x04, 0xfd, + 0x03, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x03, 0x05, 0x12, 0x04, 0xfd, 0x03, + 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x03, 0x01, 0x12, 0x04, 0xfd, 0x03, 0x09, + 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x03, 0x03, 0x12, 0x04, 0xfd, 0x03, 0x1d, 0x1e, + 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x2f, 0x02, 0x04, 0x12, 0x04, 0xfe, 0x03, 0x02, 0x28, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x2f, 0x02, 0x04, 0x06, 0x12, 0x04, 0xfe, 0x03, 0x02, 0x12, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x2f, 0x02, 0x04, 0x01, 0x12, 0x04, 0xfe, 0x03, 0x13, 0x23, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x2f, 0x02, 0x04, 0x03, 0x12, 0x04, 0xfe, 0x03, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x02, 0x04, + 0x30, 0x12, 0x06, 0x81, 0x04, 0x00, 0x8d, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x30, 0x01, + 0x12, 0x04, 0x81, 0x04, 0x08, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x30, 0x04, 0x00, 0x12, 0x06, + 0x82, 0x04, 0x02, 0x89, 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x04, 0x00, 0x01, 0x12, + 0x04, 0x82, 0x04, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x30, 0x04, 0x00, 0x02, 0x00, 0x12, + 0x04, 0x83, 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x00, 0x01, + 0x12, 0x04, 0x83, 0x04, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x00, + 0x02, 0x12, 0x04, 0x83, 0x04, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x30, 0x04, 0x00, 0x02, + 0x01, 0x12, 0x04, 0x84, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, + 0x01, 0x01, 0x12, 0x04, 0x84, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, + 0x02, 0x01, 0x02, 0x12, 0x04, 0x84, 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x30, 0x04, + 0x00, 0x02, 0x02, 0x12, 0x04, 0x85, 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, + 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0x85, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, + 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0x85, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, + 0x30, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0x86, 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, + 0x30, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, 0x86, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, + 0x04, 0x30, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x04, 0x86, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, + 0x06, 0x04, 0x30, 0x04, 0x00, 0x02, 0x04, 0x12, 0x04, 0x87, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0x87, 0x04, 0x04, 0x10, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0x87, 0x04, 0x13, 0x14, 0x0a, + 0x0e, 0x0a, 0x06, 0x04, 0x30, 0x04, 0x00, 0x02, 0x05, 0x12, 0x04, 0x88, 0x04, 0x04, 0x1f, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x05, 0x01, 0x12, 0x04, 0x88, 0x04, 0x04, 0x1a, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x30, 0x04, 0x00, 0x02, 0x05, 0x02, 0x12, 0x04, 0x88, 0x04, 0x1d, + 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x30, 0x02, 0x00, 0x12, 0x04, 0x8b, 0x04, 0x02, 0x10, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x00, 0x06, 0x12, 0x04, 0x8b, 0x04, 0x02, 0x06, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x30, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8b, 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x30, 0x02, 0x00, 0x03, 0x12, 0x04, 0x8b, 0x04, 0x0e, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x30, 0x02, 0x01, 0x12, 0x04, 0x8c, 0x04, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, + 0x02, 0x01, 0x05, 0x12, 0x04, 0x8c, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, + 0x01, 0x01, 0x12, 0x04, 0x8c, 0x04, 0x08, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x30, 0x02, 0x01, + 0x03, 0x12, 0x04, 0x8c, 0x04, 0x15, 0x16, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x31, 0x12, 0x06, 0x8f, + 0x04, 0x00, 0xa5, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x31, 0x01, 0x12, 0x04, 0x8f, 0x04, + 0x08, 0x14, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x31, 0x04, 0x00, 0x12, 0x06, 0x90, 0x04, 0x02, 0x96, + 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x04, 0x00, 0x01, 0x12, 0x04, 0x90, 0x04, 0x07, + 0x0b, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0x91, 0x04, 0x04, + 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0x91, 0x04, + 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0x91, + 0x04, 0x17, 0x18, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0x92, + 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, + 0x92, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, + 0x04, 0x92, 0x04, 0x13, 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, 0x02, 0x12, + 0x04, 0x93, 0x04, 0x04, 0x1d, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x02, 0x01, + 0x12, 0x04, 0x93, 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, 0x02, + 0x02, 0x12, 0x04, 0x93, 0x04, 0x1b, 0x1c, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, 0x00, 0x02, + 0x03, 0x12, 0x04, 0x94, 0x04, 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, 0x02, + 0x03, 0x01, 0x12, 0x04, 0x94, 0x04, 0x04, 0x11, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, 0x00, + 0x02, 0x03, 0x02, 0x12, 0x04, 0x94, 0x04, 0x14, 0x15, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x04, + 0x00, 0x02, 0x04, 0x12, 0x04, 0x95, 0x04, 0x04, 0x15, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, 0x04, + 0x00, 0x02, 0x04, 0x01, 0x12, 0x04, 0x95, 0x04, 0x04, 0x10, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x31, + 0x04, 0x00, 0x02, 0x04, 0x02, 0x12, 0x04, 0x95, 0x04, 0x13, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x31, 0x02, 0x00, 0x12, 0x04, 0x98, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, + 0x00, 0x06, 0x12, 0x04, 0x98, 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x00, + 0x01, 0x12, 0x04, 0x98, 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x00, 0x03, + 0x12, 0x04, 0x98, 0x04, 0x0e, 0x0f, 0x0a, 0x64, 0x0a, 0x04, 0x04, 0x31, 0x02, 0x01, 0x12, 0x04, + 0x9c, 0x04, 0x02, 0x2a, 0x1a, 0x56, 0x20, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x3a, 0x20, 0x75, 0x73, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, + 0x2e, 0x0a, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x30, + 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x69, 0x73, 0x20, + 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x31, 0x02, 0x01, 0x05, 0x12, 0x04, 0x9c, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x31, 0x02, 0x01, 0x01, 0x12, 0x04, 0x9c, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, + 0x02, 0x01, 0x03, 0x12, 0x04, 0x9c, 0x04, 0x14, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, + 0x01, 0x08, 0x12, 0x04, 0x9c, 0x04, 0x16, 0x29, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x31, 0x02, 0x01, + 0x08, 0x03, 0x12, 0x04, 0x9c, 0x04, 0x17, 0x28, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x31, 0x08, 0x00, + 0x12, 0x06, 0x9f, 0x04, 0x02, 0xa4, 0x04, 0x03, 0x1a, 0x13, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x3a, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x2e, 0x31, 0x30, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x31, 0x08, 0x00, 0x01, 0x12, 0x04, 0x9f, 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x31, 0x02, 0x02, 0x12, 0x04, 0xa0, 0x04, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, + 0x02, 0x02, 0x06, 0x12, 0x04, 0xa0, 0x04, 0x04, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, + 0x02, 0x01, 0x12, 0x04, 0xa0, 0x04, 0x0c, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x02, + 0x03, 0x12, 0x04, 0xa0, 0x04, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x31, 0x02, 0x03, 0x12, + 0x04, 0xa1, 0x04, 0x04, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x03, 0x06, 0x12, 0x04, + 0xa1, 0x04, 0x04, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x03, 0x01, 0x12, 0x04, 0xa1, + 0x04, 0x13, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x03, 0x03, 0x12, 0x04, 0xa1, 0x04, + 0x25, 0x26, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x31, 0x02, 0x04, 0x12, 0x04, 0xa2, 0x04, 0x04, 0x1a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x04, 0x06, 0x12, 0x04, 0xa2, 0x04, 0x04, 0x0c, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, 0x04, 0x01, 0x12, 0x04, 0xa2, 0x04, 0x0d, 0x15, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x31, 0x02, 0x04, 0x03, 0x12, 0x04, 0xa2, 0x04, 0x18, 0x19, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x31, 0x02, 0x05, 0x12, 0x04, 0xa3, 0x04, 0x04, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x31, 0x02, 0x05, 0x06, 0x12, 0x04, 0xa3, 0x04, 0x04, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, + 0x02, 0x05, 0x01, 0x12, 0x04, 0xa3, 0x04, 0x0c, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x31, 0x02, + 0x05, 0x03, 0x12, 0x04, 0xa3, 0x04, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x32, 0x12, 0x06, + 0xa7, 0x04, 0x00, 0xa9, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x32, 0x01, 0x12, 0x04, 0xa7, + 0x04, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x32, 0x02, 0x00, 0x12, 0x04, 0xa8, 0x04, 0x02, + 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x05, 0x12, 0x04, 0xa8, 0x04, 0x02, 0x07, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x01, 0x12, 0x04, 0xa8, 0x04, 0x08, 0x11, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x32, 0x02, 0x00, 0x03, 0x12, 0x04, 0xa8, 0x04, 0x14, 0x15, 0x0a, 0x0c, + 0x0a, 0x02, 0x04, 0x33, 0x12, 0x06, 0xab, 0x04, 0x00, 0xad, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, + 0x04, 0x33, 0x01, 0x12, 0x04, 0xab, 0x04, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x33, 0x02, + 0x00, 0x12, 0x04, 0xac, 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x33, 0x02, 0x00, 0x05, + 0x12, 0x04, 0xac, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x33, 0x02, 0x00, 0x01, 0x12, + 0x04, 0xac, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x33, 0x02, 0x00, 0x03, 0x12, 0x04, + 0xac, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x34, 0x12, 0x06, 0xaf, 0x04, 0x00, 0xb1, + 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x34, 0x01, 0x12, 0x04, 0xaf, 0x04, 0x08, 0x10, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x34, 0x02, 0x00, 0x12, 0x04, 0xb0, 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x34, 0x02, 0x00, 0x05, 0x12, 0x04, 0xb0, 0x04, 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x34, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb0, 0x04, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x34, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb0, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x35, + 0x12, 0x06, 0xb3, 0x04, 0x00, 0xb5, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x35, 0x01, 0x12, + 0x04, 0xb3, 0x04, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x35, 0x02, 0x00, 0x12, 0x04, 0xb4, + 0x04, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, 0x00, 0x05, 0x12, 0x04, 0xb4, 0x04, + 0x02, 0x07, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, 0x00, 0x01, 0x12, 0x04, 0xb4, 0x04, 0x08, + 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x35, 0x02, 0x00, 0x03, 0x12, 0x04, 0xb4, 0x04, 0x14, 0x15, + 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x36, 0x12, 0x06, 0xb7, 0x04, 0x00, 0xba, 0x04, 0x01, 0x0a, 0x0b, + 0x0a, 0x03, 0x04, 0x36, 0x01, 0x12, 0x04, 0xb7, 0x04, 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x36, 0x02, 0x00, 0x12, 0x04, 0xb8, 0x04, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, + 0x00, 0x06, 0x12, 0x04, 0xb8, 0x04, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, + 0x01, 0x12, 0x04, 0xb8, 0x04, 0x0f, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x00, 0x03, + 0x12, 0x04, 0xb8, 0x04, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x36, 0x02, 0x01, 0x12, 0x04, + 0xb9, 0x04, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x01, 0x06, 0x12, 0x04, 0xb9, + 0x04, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x01, 0x01, 0x12, 0x04, 0xb9, 0x04, + 0x0f, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x36, 0x02, 0x01, 0x03, 0x12, 0x04, 0xb9, 0x04, 0x1b, + 0x1c, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x37, 0x12, 0x06, 0xbc, 0x04, 0x00, 0xbf, 0x04, 0x01, 0x0a, + 0x0b, 0x0a, 0x03, 0x04, 0x37, 0x01, 0x12, 0x04, 0xbc, 0x04, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x37, 0x02, 0x00, 0x12, 0x04, 0xbd, 0x04, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, + 0x02, 0x00, 0x05, 0x12, 0x04, 0xbd, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, + 0x00, 0x01, 0x12, 0x04, 0xbd, 0x04, 0x09, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x00, + 0x03, 0x12, 0x04, 0xbd, 0x04, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x37, 0x02, 0x01, 0x12, + 0x04, 0xbe, 0x04, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x06, 0x12, 0x04, + 0xbe, 0x04, 0x02, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x01, 0x12, 0x04, 0xbe, + 0x04, 0x0f, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x37, 0x02, 0x01, 0x03, 0x12, 0x04, 0xbe, 0x04, + 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x38, 0x12, 0x06, 0xc1, 0x04, 0x00, 0xc5, 0x04, 0x01, + 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x38, 0x01, 0x12, 0x04, 0xc1, 0x04, 0x08, 0x19, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x38, 0x02, 0x00, 0x12, 0x04, 0xc2, 0x04, 0x02, 0x28, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x38, 0x02, 0x00, 0x04, 0x12, 0x04, 0xc2, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, + 0x02, 0x00, 0x06, 0x12, 0x04, 0xc2, 0x04, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, + 0x00, 0x01, 0x12, 0x04, 0xc2, 0x04, 0x18, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x00, + 0x03, 0x12, 0x04, 0xc2, 0x04, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x38, 0x02, 0x01, 0x12, + 0x04, 0xc3, 0x04, 0x02, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x04, 0x12, 0x04, + 0xc3, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x06, 0x12, 0x04, 0xc3, + 0x04, 0x0b, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc3, 0x04, + 0x1c, 0x26, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc3, 0x04, 0x29, + 0x2a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x38, 0x02, 0x02, 0x12, 0x04, 0xc4, 0x04, 0x02, 0x21, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x38, 0x02, 0x02, 0x05, 0x12, 0x04, 0xc4, 0x04, 0x02, 0x08, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x38, 0x02, 0x02, 0x01, 0x12, 0x04, 0xc4, 0x04, 0x09, 0x1c, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x38, 0x02, 0x02, 0x03, 0x12, 0x04, 0xc4, 0x04, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x02, + 0x04, 0x39, 0x12, 0x06, 0xc7, 0x04, 0x00, 0xca, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x39, + 0x01, 0x12, 0x04, 0xc7, 0x04, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x39, 0x02, 0x00, 0x12, + 0x04, 0xc8, 0x04, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x05, 0x12, 0x04, + 0xc8, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x01, 0x12, 0x04, 0xc8, + 0x04, 0x09, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x00, 0x03, 0x12, 0x04, 0xc8, 0x04, + 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x39, 0x02, 0x01, 0x12, 0x04, 0xc9, 0x04, 0x02, 0x16, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x05, 0x12, 0x04, 0xc9, 0x04, 0x02, 0x07, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x01, 0x12, 0x04, 0xc9, 0x04, 0x08, 0x11, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x39, 0x02, 0x01, 0x03, 0x12, 0x04, 0xc9, 0x04, 0x14, 0x15, 0x0a, 0x0c, 0x0a, + 0x02, 0x04, 0x3a, 0x12, 0x06, 0xcc, 0x04, 0x00, 0xce, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, + 0x3a, 0x01, 0x12, 0x04, 0xcc, 0x04, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3a, 0x02, 0x00, + 0x12, 0x04, 0xcd, 0x04, 0x02, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x06, 0x12, + 0x04, 0xcd, 0x04, 0x02, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x01, 0x12, 0x04, + 0xcd, 0x04, 0x13, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3a, 0x02, 0x00, 0x03, 0x12, 0x04, 0xcd, + 0x04, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3b, 0x12, 0x06, 0xd0, 0x04, 0x00, 0xe5, 0x04, + 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3b, 0x01, 0x12, 0x04, 0xd0, 0x04, 0x08, 0x18, 0x0a, 0x0e, + 0x0a, 0x04, 0x04, 0x3b, 0x04, 0x00, 0x12, 0x06, 0xd1, 0x04, 0x02, 0xda, 0x04, 0x03, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x3b, 0x04, 0x00, 0x01, 0x12, 0x04, 0xd1, 0x04, 0x07, 0x0b, 0x0a, 0x0e, 0x0a, + 0x06, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x00, 0x12, 0x04, 0xd2, 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, + 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x04, 0xd2, 0x04, 0x04, 0x14, 0x0a, 0x0f, + 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x04, 0xd2, 0x04, 0x17, 0x18, 0x0a, + 0x0e, 0x0a, 0x06, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x01, 0x12, 0x04, 0xd3, 0x04, 0x04, 0x15, 0x0a, + 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x04, 0xd3, 0x04, 0x04, 0x10, + 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x04, 0xd3, 0x04, 0x13, + 0x14, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x02, 0x12, 0x04, 0xd4, 0x04, 0x04, + 0x1b, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x04, 0xd4, 0x04, + 0x04, 0x16, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x04, 0xd4, + 0x04, 0x19, 0x1a, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x03, 0x12, 0x04, 0xd5, + 0x04, 0x04, 0x18, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x04, + 0xd5, 0x04, 0x04, 0x13, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, + 0x04, 0xd5, 0x04, 0x16, 0x17, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x04, 0x12, + 0x04, 0xd6, 0x04, 0x04, 0x17, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x04, 0x01, + 0x12, 0x04, 0xd6, 0x04, 0x04, 0x12, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, 0x04, + 0x02, 0x12, 0x04, 0xd6, 0x04, 0x15, 0x16, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3b, 0x04, 0x00, 0x02, + 0x05, 0x12, 0x04, 0xd7, 0x04, 0x04, 0x19, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, 0x02, + 0x05, 0x01, 0x12, 0x04, 0xd7, 0x04, 0x04, 0x14, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, + 0x02, 0x05, 0x02, 0x12, 0x04, 0xd7, 0x04, 0x17, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x04, + 0x00, 0x04, 0x12, 0x04, 0xd9, 0x04, 0x04, 0x0f, 0x0a, 0x0e, 0x0a, 0x06, 0x04, 0x3b, 0x04, 0x00, + 0x04, 0x00, 0x12, 0x04, 0xd9, 0x04, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, 0x00, + 0x04, 0x00, 0x01, 0x12, 0x04, 0xd9, 0x04, 0x0d, 0x0e, 0x0a, 0x0f, 0x0a, 0x07, 0x04, 0x3b, 0x04, + 0x00, 0x04, 0x00, 0x02, 0x12, 0x04, 0xd9, 0x04, 0x0d, 0x0e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3b, + 0x02, 0x00, 0x12, 0x04, 0xdc, 0x04, 0x02, 0x10, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, + 0x06, 0x12, 0x04, 0xdc, 0x04, 0x02, 0x06, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x01, + 0x12, 0x04, 0xdc, 0x04, 0x07, 0x0b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x00, 0x03, 0x12, + 0x04, 0xdc, 0x04, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x04, 0x04, 0x3b, 0x08, 0x00, 0x12, 0x06, 0xdd, + 0x04, 0x02, 0xe4, 0x04, 0x03, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x08, 0x00, 0x01, 0x12, 0x04, + 0xdd, 0x04, 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3b, 0x02, 0x01, 0x12, 0x04, 0xde, 0x04, + 0x04, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x01, 0x06, 0x12, 0x04, 0xde, 0x04, 0x04, + 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x01, 0x01, 0x12, 0x04, 0xde, 0x04, 0x15, 0x1c, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x01, 0x03, 0x12, 0x04, 0xde, 0x04, 0x1f, 0x20, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x3b, 0x02, 0x02, 0x12, 0x04, 0xdf, 0x04, 0x04, 0x2c, 0x0a, 0x0d, 0x0a, + 0x05, 0x04, 0x3b, 0x02, 0x02, 0x06, 0x12, 0x04, 0xdf, 0x04, 0x04, 0x19, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x3b, 0x02, 0x02, 0x01, 0x12, 0x04, 0xdf, 0x04, 0x1a, 0x27, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x3b, 0x02, 0x02, 0x03, 0x12, 0x04, 0xdf, 0x04, 0x2a, 0x2b, 0x0a, 0x1e, 0x0a, 0x04, 0x04, 0x3b, + 0x02, 0x03, 0x12, 0x04, 0xe1, 0x04, 0x04, 0x30, 0x1a, 0x10, 0x20, 0x34, 0x20, 0x69, 0x73, 0x20, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, + 0x02, 0x03, 0x06, 0x12, 0x04, 0xe1, 0x04, 0x04, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, + 0x03, 0x01, 0x12, 0x04, 0xe1, 0x04, 0x17, 0x2b, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x03, + 0x03, 0x12, 0x04, 0xe1, 0x04, 0x2e, 0x2f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3b, 0x02, 0x04, 0x12, + 0x04, 0xe2, 0x04, 0x04, 0x2e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x04, 0x06, 0x12, 0x04, + 0xe2, 0x04, 0x04, 0x15, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x04, 0x01, 0x12, 0x04, 0xe2, + 0x04, 0x16, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x04, 0x03, 0x12, 0x04, 0xe2, 0x04, + 0x2c, 0x2d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3b, 0x02, 0x05, 0x12, 0x04, 0xe3, 0x04, 0x04, 0x29, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x05, 0x06, 0x12, 0x04, 0xe3, 0x04, 0x04, 0x18, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x05, 0x01, 0x12, 0x04, 0xe3, 0x04, 0x19, 0x24, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x3b, 0x02, 0x05, 0x03, 0x12, 0x04, 0xe3, 0x04, 0x27, 0x28, 0x0a, 0x0c, 0x0a, + 0x02, 0x04, 0x3c, 0x12, 0x06, 0xe7, 0x04, 0x00, 0xeb, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, + 0x3c, 0x01, 0x12, 0x04, 0xe7, 0x04, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x00, + 0x12, 0x04, 0xe8, 0x04, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x05, 0x12, + 0x04, 0xe8, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x01, 0x12, 0x04, + 0xe8, 0x04, 0x09, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x00, 0x03, 0x12, 0x04, 0xe8, + 0x04, 0x1d, 0x1e, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3c, 0x02, 0x01, 0x12, 0x04, 0xe9, 0x04, 0x02, + 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x01, 0x04, 0x12, 0x04, 0xe9, 0x04, 0x02, 0x0a, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x01, 0x06, 0x12, 0x04, 0xe9, 0x04, 0x0b, 0x18, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x01, 0x01, 0x12, 0x04, 0xe9, 0x04, 0x19, 0x28, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x01, 0x03, 0x12, 0x04, 0xe9, 0x04, 0x2b, 0x2c, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x3c, 0x02, 0x02, 0x12, 0x04, 0xea, 0x04, 0x02, 0x32, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x3c, 0x02, 0x02, 0x04, 0x12, 0x04, 0xea, 0x04, 0x02, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, + 0x02, 0x02, 0x06, 0x12, 0x04, 0xea, 0x04, 0x0b, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, + 0x02, 0x01, 0x12, 0x04, 0xea, 0x04, 0x1b, 0x2d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3c, 0x02, 0x02, + 0x03, 0x12, 0x04, 0xea, 0x04, 0x30, 0x31, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3d, 0x12, 0x06, 0xed, + 0x04, 0x00, 0xf0, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3d, 0x01, 0x12, 0x04, 0xed, 0x04, + 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3d, 0x02, 0x00, 0x12, 0x04, 0xee, 0x04, 0x02, 0x1c, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x05, 0x12, 0x04, 0xee, 0x04, 0x02, 0x08, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x01, 0x12, 0x04, 0xee, 0x04, 0x09, 0x17, 0x0a, 0x0d, + 0x0a, 0x05, 0x04, 0x3d, 0x02, 0x00, 0x03, 0x12, 0x04, 0xee, 0x04, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x3d, 0x02, 0x01, 0x12, 0x04, 0xef, 0x04, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x3d, 0x02, 0x01, 0x05, 0x12, 0x04, 0xef, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, + 0x02, 0x01, 0x01, 0x12, 0x04, 0xef, 0x04, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3d, 0x02, + 0x01, 0x03, 0x12, 0x04, 0xef, 0x04, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x3e, 0x12, 0x06, + 0xf2, 0x04, 0x00, 0xf5, 0x04, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x3e, 0x01, 0x12, 0x04, 0xf2, + 0x04, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x3e, 0x02, 0x00, 0x12, 0x04, 0xf3, 0x04, 0x02, + 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, 0x02, 0x00, 0x05, 0x12, 0x04, 0xf3, 0x04, 0x02, 0x08, + 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, 0x02, 0x00, 0x01, 0x12, 0x04, 0xf3, 0x04, 0x09, 0x12, 0x0a, + 0x0d, 0x0a, 0x05, 0x04, 0x3e, 0x02, 0x00, 0x03, 0x12, 0x04, 0xf3, 0x04, 0x15, 0x16, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x3e, 0x02, 0x01, 0x12, 0x04, 0xf4, 0x04, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, + 0x04, 0x3e, 0x02, 0x01, 0x05, 0x12, 0x04, 0xf4, 0x04, 0x02, 0x08, 0x0a, 0x0d, 0x0a, 0x05, 0x04, + 0x3e, 0x02, 0x01, 0x01, 0x12, 0x04, 0xf4, 0x04, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x3e, + 0x02, 0x01, 0x03, 0x12, 0x04, 0xf4, 0x04, 0x17, 0x18, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, ]; include!("aptos.transaction.v1.serde.rs"); diff --git a/protos/rust/src/pb/aptos.transaction.v1.serde.rs b/protos/rust/src/pb/aptos.transaction.v1.serde.rs index 8465f85af84db..bf9261c30a9d3 100644 --- a/protos/rust/src/pb/aptos.transaction.v1.serde.rs +++ b/protos/rust/src/pb/aptos.transaction.v1.serde.rs @@ -2,6 +2,117 @@ // SPDX-License-Identifier: Apache-2.0 // @generated +impl serde::Serialize for AbstractionSignature { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.function_info.is_empty() { + len += 1; + } + if !self.signature.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("aptos.transaction.v1.AbstractionSignature", len)?; + if !self.function_info.is_empty() { + struct_ser.serialize_field("functionInfo", &self.function_info)?; + } + if !self.signature.is_empty() { + struct_ser.serialize_field("signature", pbjson::private::base64::encode(&self.signature).as_str())?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for AbstractionSignature { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "function_info", + "functionInfo", + "signature", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + FunctionInfo, + Signature, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "functionInfo" | "function_info" => Ok(GeneratedField::FunctionInfo), + "signature" => Ok(GeneratedField::Signature), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = AbstractionSignature; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct aptos.transaction.v1.AbstractionSignature") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut function_info__ = None; + let mut signature__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::FunctionInfo => { + if function_info__.is_some() { + return Err(serde::de::Error::duplicate_field("functionInfo")); + } + function_info__ = Some(map.next_value()?); + } + GeneratedField::Signature => { + if signature__.is_some() { + return Err(serde::de::Error::duplicate_field("signature")); + } + signature__ = + Some(map.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + } + } + Ok(AbstractionSignature { + function_info: function_info__.unwrap_or_default(), + signature: signature__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("aptos.transaction.v1.AbstractionSignature", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for AccountSignature { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -36,6 +147,9 @@ impl serde::Serialize for AccountSignature { account_signature::Signature::MultiKeySignature(v) => { struct_ser.serialize_field("multiKeySignature", v)?; } + account_signature::Signature::Abstraction(v) => { + struct_ser.serialize_field("abstraction", v)?; + } } } struct_ser.end() @@ -56,6 +170,7 @@ impl<'de> serde::Deserialize<'de> for AccountSignature { "singleKeySignature", "multi_key_signature", "multiKeySignature", + "abstraction", ]; #[allow(clippy::enum_variant_names)] @@ -65,6 +180,7 @@ impl<'de> serde::Deserialize<'de> for AccountSignature { MultiEd25519, SingleKeySignature, MultiKeySignature, + Abstraction, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -91,6 +207,7 @@ impl<'de> serde::Deserialize<'de> for AccountSignature { "multiEd25519" | "multi_ed25519" => Ok(GeneratedField::MultiEd25519), "singleKeySignature" | "single_key_signature" => Ok(GeneratedField::SingleKeySignature), "multiKeySignature" | "multi_key_signature" => Ok(GeneratedField::MultiKeySignature), + "abstraction" => Ok(GeneratedField::Abstraction), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -146,6 +263,13 @@ impl<'de> serde::Deserialize<'de> for AccountSignature { return Err(serde::de::Error::duplicate_field("multiKeySignature")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(account_signature::Signature::MultiKeySignature) +; + } + GeneratedField::Abstraction => { + if signature__.is_some() { + return Err(serde::de::Error::duplicate_field("abstraction")); + } + signature__ = map.next_value::<::std::option::Option<_>>()?.map(account_signature::Signature::Abstraction) ; } } @@ -171,6 +295,7 @@ impl serde::Serialize for account_signature::Type { Self::MultiEd25519 => "TYPE_MULTI_ED25519", Self::SingleKey => "TYPE_SINGLE_KEY", Self::MultiKey => "TYPE_MULTI_KEY", + Self::Abstraction => "TYPE_ABSTRACTION", }; serializer.serialize_str(variant) } @@ -187,6 +312,7 @@ impl<'de> serde::Deserialize<'de> for account_signature::Type { "TYPE_MULTI_ED25519", "TYPE_SINGLE_KEY", "TYPE_MULTI_KEY", + "TYPE_ABSTRACTION", ]; struct GeneratedVisitor; @@ -234,6 +360,7 @@ impl<'de> serde::Deserialize<'de> for account_signature::Type { "TYPE_MULTI_ED25519" => Ok(account_signature::Type::MultiEd25519), "TYPE_SINGLE_KEY" => Ok(account_signature::Type::SingleKey), "TYPE_MULTI_KEY" => Ok(account_signature::Type::MultiKey), + "TYPE_ABSTRACTION" => Ok(account_signature::Type::Abstraction), _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), } } diff --git a/protos/rust/src/pb/aptos.util.timestamp.rs b/protos/rust/src/pb/aptos.util.timestamp.rs index f746dba3fd7b1..df8a9f30f8a73 100644 --- a/protos/rust/src/pb/aptos.util.timestamp.rs +++ b/protos/rust/src/pb/aptos.util.timestamp.rs @@ -3,6 +3,7 @@ // @generated // This file is @generated by prost-build. +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct Timestamp { /// Represents seconds of UTC time since Unix epoch diff --git a/protos/typescript/src/aptos/indexer/v1/grpc.ts b/protos/typescript/src/aptos/indexer/v1/grpc.ts new file mode 100644 index 0000000000000..20ecfd84421e7 --- /dev/null +++ b/protos/typescript/src/aptos/indexer/v1/grpc.ts @@ -0,0 +1,2131 @@ +/* eslint-disable */ +import { + ChannelCredentials, + Client, + ClientReadableStream, + handleServerStreamingCall, + makeGenericClientConstructor, + Metadata, +} from "@grpc/grpc-js"; +import type { + CallOptions, + ClientOptions, + ClientUnaryCall, + handleUnaryCall, + ServiceError, + UntypedServiceImplementation, +} from "@grpc/grpc-js"; +import Long from "long"; +import _m0 from "protobufjs/minimal"; +import { Timestamp } from "../../util/timestamp/timestamp"; +import { GetTransactionsRequest, TransactionsResponse } from "./raw_data"; + +export interface StreamProgressSampleProto { + timestamp?: Timestamp | undefined; + version?: bigint | undefined; + sizeBytes?: bigint | undefined; +} + +export interface StreamProgress { + samples?: StreamProgressSampleProto[] | undefined; +} + +export interface ActiveStream { + id?: string | undefined; + startTime?: Timestamp | undefined; + startVersion?: bigint | undefined; + endVersion?: bigint | undefined; + progress?: StreamProgress | undefined; +} + +export interface StreamInfo { + activeStreams?: ActiveStream[] | undefined; +} + +export interface LiveDataServiceInfo { + chainId?: bigint | undefined; + timestamp?: Timestamp | undefined; + knownLatestVersion?: bigint | undefined; + streamInfo?: + | StreamInfo + | undefined; + /** If not present, it means the data service is not available to serve anything yet. */ + minServableVersion?: bigint | undefined; +} + +export interface HistoricalDataServiceInfo { + chainId?: bigint | undefined; + timestamp?: Timestamp | undefined; + knownLatestVersion?: bigint | undefined; + streamInfo?: StreamInfo | undefined; +} + +export interface FullnodeInfo { + chainId?: bigint | undefined; + timestamp?: Timestamp | undefined; + knownLatestVersion?: bigint | undefined; +} + +export interface GrpcManagerInfo { + chainId?: bigint | undefined; + timestamp?: Timestamp | undefined; + knownLatestVersion?: bigint | undefined; + masterAddress?: string | undefined; +} + +export interface ServiceInfo { + address?: string | undefined; + liveDataServiceInfo?: LiveDataServiceInfo | undefined; + historicalDataServiceInfo?: HistoricalDataServiceInfo | undefined; + fullnodeInfo?: FullnodeInfo | undefined; + grpcManagerInfo?: GrpcManagerInfo | undefined; +} + +export interface HeartbeatRequest { + serviceInfo?: ServiceInfo | undefined; +} + +export interface HeartbeatResponse { + knownLatestVersion?: bigint | undefined; +} + +export interface PingDataServiceRequest { + knownLatestVersion?: + | bigint + | undefined; + /** `true` for live data service, `false` for historical data service. */ + pingLiveDataService?: boolean | undefined; +} + +export interface PingDataServiceResponse { + liveDataServiceInfo?: LiveDataServiceInfo | undefined; + historicalDataServiceInfo?: HistoricalDataServiceInfo | undefined; +} + +export interface GetDataServiceForRequestRequest { + userRequest?: GetTransactionsRequest | undefined; +} + +export interface GetDataServiceForRequestResponse { + dataServiceAddress?: string | undefined; +} + +function createBaseStreamProgressSampleProto(): StreamProgressSampleProto { + return { timestamp: undefined, version: BigInt("0"), sizeBytes: BigInt("0") }; +} + +export const StreamProgressSampleProto = { + encode(message: StreamProgressSampleProto, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.timestamp !== undefined) { + Timestamp.encode(message.timestamp, writer.uint32(10).fork()).ldelim(); + } + if (message.version !== undefined && message.version !== BigInt("0")) { + if (BigInt.asUintN(64, message.version) !== message.version) { + throw new globalThis.Error("value provided for field message.version of type uint64 too large"); + } + writer.uint32(16).uint64(message.version.toString()); + } + if (message.sizeBytes !== undefined && message.sizeBytes !== BigInt("0")) { + if (BigInt.asUintN(64, message.sizeBytes) !== message.sizeBytes) { + throw new globalThis.Error("value provided for field message.sizeBytes of type uint64 too large"); + } + writer.uint32(24).uint64(message.sizeBytes.toString()); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): StreamProgressSampleProto { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseStreamProgressSampleProto(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.timestamp = Timestamp.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.version = longToBigint(reader.uint64() as Long); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.sizeBytes = longToBigint(reader.uint64() as Long); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: + | AsyncIterable + | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [StreamProgressSampleProto.encode(p).finish()]; + } + } else { + yield* [StreamProgressSampleProto.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [StreamProgressSampleProto.decode(p)]; + } + } else { + yield* [StreamProgressSampleProto.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): StreamProgressSampleProto { + return { + timestamp: isSet(object.timestamp) ? Timestamp.fromJSON(object.timestamp) : undefined, + version: isSet(object.version) ? BigInt(object.version) : BigInt("0"), + sizeBytes: isSet(object.sizeBytes) ? BigInt(object.sizeBytes) : BigInt("0"), + }; + }, + + toJSON(message: StreamProgressSampleProto): unknown { + const obj: any = {}; + if (message.timestamp !== undefined) { + obj.timestamp = Timestamp.toJSON(message.timestamp); + } + if (message.version !== undefined && message.version !== BigInt("0")) { + obj.version = message.version.toString(); + } + if (message.sizeBytes !== undefined && message.sizeBytes !== BigInt("0")) { + obj.sizeBytes = message.sizeBytes.toString(); + } + return obj; + }, + + create(base?: DeepPartial): StreamProgressSampleProto { + return StreamProgressSampleProto.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): StreamProgressSampleProto { + const message = createBaseStreamProgressSampleProto(); + message.timestamp = (object.timestamp !== undefined && object.timestamp !== null) + ? Timestamp.fromPartial(object.timestamp) + : undefined; + message.version = object.version ?? BigInt("0"); + message.sizeBytes = object.sizeBytes ?? BigInt("0"); + return message; + }, +}; + +function createBaseStreamProgress(): StreamProgress { + return { samples: [] }; +} + +export const StreamProgress = { + encode(message: StreamProgress, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.samples !== undefined && message.samples.length !== 0) { + for (const v of message.samples) { + StreamProgressSampleProto.encode(v!, writer.uint32(10).fork()).ldelim(); + } + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): StreamProgress { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseStreamProgress(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.samples!.push(StreamProgressSampleProto.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [StreamProgress.encode(p).finish()]; + } + } else { + yield* [StreamProgress.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [StreamProgress.decode(p)]; + } + } else { + yield* [StreamProgress.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): StreamProgress { + return { + samples: globalThis.Array.isArray(object?.samples) + ? object.samples.map((e: any) => StreamProgressSampleProto.fromJSON(e)) + : [], + }; + }, + + toJSON(message: StreamProgress): unknown { + const obj: any = {}; + if (message.samples?.length) { + obj.samples = message.samples.map((e) => StreamProgressSampleProto.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): StreamProgress { + return StreamProgress.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): StreamProgress { + const message = createBaseStreamProgress(); + message.samples = object.samples?.map((e) => StreamProgressSampleProto.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseActiveStream(): ActiveStream { + return { id: undefined, startTime: undefined, startVersion: BigInt("0"), endVersion: undefined, progress: undefined }; +} + +export const ActiveStream = { + encode(message: ActiveStream, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.id !== undefined) { + writer.uint32(10).string(message.id); + } + if (message.startTime !== undefined) { + Timestamp.encode(message.startTime, writer.uint32(18).fork()).ldelim(); + } + if (message.startVersion !== undefined && message.startVersion !== BigInt("0")) { + if (BigInt.asUintN(64, message.startVersion) !== message.startVersion) { + throw new globalThis.Error("value provided for field message.startVersion of type uint64 too large"); + } + writer.uint32(24).uint64(message.startVersion.toString()); + } + if (message.endVersion !== undefined) { + if (BigInt.asUintN(64, message.endVersion) !== message.endVersion) { + throw new globalThis.Error("value provided for field message.endVersion of type uint64 too large"); + } + writer.uint32(32).uint64(message.endVersion.toString()); + } + if (message.progress !== undefined) { + StreamProgress.encode(message.progress, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ActiveStream { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseActiveStream(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.startTime = Timestamp.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.startVersion = longToBigint(reader.uint64() as Long); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.endVersion = longToBigint(reader.uint64() as Long); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.progress = StreamProgress.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [ActiveStream.encode(p).finish()]; + } + } else { + yield* [ActiveStream.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [ActiveStream.decode(p)]; + } + } else { + yield* [ActiveStream.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): ActiveStream { + return { + id: isSet(object.id) ? globalThis.String(object.id) : undefined, + startTime: isSet(object.startTime) ? Timestamp.fromJSON(object.startTime) : undefined, + startVersion: isSet(object.startVersion) ? BigInt(object.startVersion) : BigInt("0"), + endVersion: isSet(object.endVersion) ? BigInt(object.endVersion) : undefined, + progress: isSet(object.progress) ? StreamProgress.fromJSON(object.progress) : undefined, + }; + }, + + toJSON(message: ActiveStream): unknown { + const obj: any = {}; + if (message.id !== undefined) { + obj.id = message.id; + } + if (message.startTime !== undefined) { + obj.startTime = Timestamp.toJSON(message.startTime); + } + if (message.startVersion !== undefined && message.startVersion !== BigInt("0")) { + obj.startVersion = message.startVersion.toString(); + } + if (message.endVersion !== undefined) { + obj.endVersion = message.endVersion.toString(); + } + if (message.progress !== undefined) { + obj.progress = StreamProgress.toJSON(message.progress); + } + return obj; + }, + + create(base?: DeepPartial): ActiveStream { + return ActiveStream.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ActiveStream { + const message = createBaseActiveStream(); + message.id = object.id ?? undefined; + message.startTime = (object.startTime !== undefined && object.startTime !== null) + ? Timestamp.fromPartial(object.startTime) + : undefined; + message.startVersion = object.startVersion ?? BigInt("0"); + message.endVersion = object.endVersion ?? undefined; + message.progress = (object.progress !== undefined && object.progress !== null) + ? StreamProgress.fromPartial(object.progress) + : undefined; + return message; + }, +}; + +function createBaseStreamInfo(): StreamInfo { + return { activeStreams: [] }; +} + +export const StreamInfo = { + encode(message: StreamInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.activeStreams !== undefined && message.activeStreams.length !== 0) { + for (const v of message.activeStreams) { + ActiveStream.encode(v!, writer.uint32(10).fork()).ldelim(); + } + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): StreamInfo { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseStreamInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.activeStreams!.push(ActiveStream.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [StreamInfo.encode(p).finish()]; + } + } else { + yield* [StreamInfo.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [StreamInfo.decode(p)]; + } + } else { + yield* [StreamInfo.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): StreamInfo { + return { + activeStreams: globalThis.Array.isArray(object?.activeStreams) + ? object.activeStreams.map((e: any) => ActiveStream.fromJSON(e)) + : [], + }; + }, + + toJSON(message: StreamInfo): unknown { + const obj: any = {}; + if (message.activeStreams?.length) { + obj.activeStreams = message.activeStreams.map((e) => ActiveStream.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): StreamInfo { + return StreamInfo.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): StreamInfo { + const message = createBaseStreamInfo(); + message.activeStreams = object.activeStreams?.map((e) => ActiveStream.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseLiveDataServiceInfo(): LiveDataServiceInfo { + return { + chainId: undefined, + timestamp: undefined, + knownLatestVersion: undefined, + streamInfo: undefined, + minServableVersion: undefined, + }; +} + +export const LiveDataServiceInfo = { + encode(message: LiveDataServiceInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.chainId !== undefined) { + if (BigInt.asUintN(64, message.chainId) !== message.chainId) { + throw new globalThis.Error("value provided for field message.chainId of type uint64 too large"); + } + writer.uint32(8).uint64(message.chainId.toString()); + } + if (message.timestamp !== undefined) { + Timestamp.encode(message.timestamp, writer.uint32(18).fork()).ldelim(); + } + if (message.knownLatestVersion !== undefined) { + if (BigInt.asUintN(64, message.knownLatestVersion) !== message.knownLatestVersion) { + throw new globalThis.Error("value provided for field message.knownLatestVersion of type uint64 too large"); + } + writer.uint32(24).uint64(message.knownLatestVersion.toString()); + } + if (message.streamInfo !== undefined) { + StreamInfo.encode(message.streamInfo, writer.uint32(34).fork()).ldelim(); + } + if (message.minServableVersion !== undefined) { + if (BigInt.asUintN(64, message.minServableVersion) !== message.minServableVersion) { + throw new globalThis.Error("value provided for field message.minServableVersion of type uint64 too large"); + } + writer.uint32(40).uint64(message.minServableVersion.toString()); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LiveDataServiceInfo { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLiveDataServiceInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.chainId = longToBigint(reader.uint64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.timestamp = Timestamp.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.knownLatestVersion = longToBigint(reader.uint64() as Long); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.streamInfo = StreamInfo.decode(reader, reader.uint32()); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.minServableVersion = longToBigint(reader.uint64() as Long); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: + | AsyncIterable + | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [LiveDataServiceInfo.encode(p).finish()]; + } + } else { + yield* [LiveDataServiceInfo.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [LiveDataServiceInfo.decode(p)]; + } + } else { + yield* [LiveDataServiceInfo.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): LiveDataServiceInfo { + return { + chainId: isSet(object.chainId) ? BigInt(object.chainId) : undefined, + timestamp: isSet(object.timestamp) ? Timestamp.fromJSON(object.timestamp) : undefined, + knownLatestVersion: isSet(object.knownLatestVersion) ? BigInt(object.knownLatestVersion) : undefined, + streamInfo: isSet(object.streamInfo) ? StreamInfo.fromJSON(object.streamInfo) : undefined, + minServableVersion: isSet(object.minServableVersion) ? BigInt(object.minServableVersion) : undefined, + }; + }, + + toJSON(message: LiveDataServiceInfo): unknown { + const obj: any = {}; + if (message.chainId !== undefined) { + obj.chainId = message.chainId.toString(); + } + if (message.timestamp !== undefined) { + obj.timestamp = Timestamp.toJSON(message.timestamp); + } + if (message.knownLatestVersion !== undefined) { + obj.knownLatestVersion = message.knownLatestVersion.toString(); + } + if (message.streamInfo !== undefined) { + obj.streamInfo = StreamInfo.toJSON(message.streamInfo); + } + if (message.minServableVersion !== undefined) { + obj.minServableVersion = message.minServableVersion.toString(); + } + return obj; + }, + + create(base?: DeepPartial): LiveDataServiceInfo { + return LiveDataServiceInfo.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LiveDataServiceInfo { + const message = createBaseLiveDataServiceInfo(); + message.chainId = object.chainId ?? undefined; + message.timestamp = (object.timestamp !== undefined && object.timestamp !== null) + ? Timestamp.fromPartial(object.timestamp) + : undefined; + message.knownLatestVersion = object.knownLatestVersion ?? undefined; + message.streamInfo = (object.streamInfo !== undefined && object.streamInfo !== null) + ? StreamInfo.fromPartial(object.streamInfo) + : undefined; + message.minServableVersion = object.minServableVersion ?? undefined; + return message; + }, +}; + +function createBaseHistoricalDataServiceInfo(): HistoricalDataServiceInfo { + return { chainId: undefined, timestamp: undefined, knownLatestVersion: undefined, streamInfo: undefined }; +} + +export const HistoricalDataServiceInfo = { + encode(message: HistoricalDataServiceInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.chainId !== undefined) { + if (BigInt.asUintN(64, message.chainId) !== message.chainId) { + throw new globalThis.Error("value provided for field message.chainId of type uint64 too large"); + } + writer.uint32(8).uint64(message.chainId.toString()); + } + if (message.timestamp !== undefined) { + Timestamp.encode(message.timestamp, writer.uint32(18).fork()).ldelim(); + } + if (message.knownLatestVersion !== undefined) { + if (BigInt.asUintN(64, message.knownLatestVersion) !== message.knownLatestVersion) { + throw new globalThis.Error("value provided for field message.knownLatestVersion of type uint64 too large"); + } + writer.uint32(24).uint64(message.knownLatestVersion.toString()); + } + if (message.streamInfo !== undefined) { + StreamInfo.encode(message.streamInfo, writer.uint32(34).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): HistoricalDataServiceInfo { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHistoricalDataServiceInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.chainId = longToBigint(reader.uint64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.timestamp = Timestamp.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.knownLatestVersion = longToBigint(reader.uint64() as Long); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.streamInfo = StreamInfo.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: + | AsyncIterable + | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [HistoricalDataServiceInfo.encode(p).finish()]; + } + } else { + yield* [HistoricalDataServiceInfo.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [HistoricalDataServiceInfo.decode(p)]; + } + } else { + yield* [HistoricalDataServiceInfo.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): HistoricalDataServiceInfo { + return { + chainId: isSet(object.chainId) ? BigInt(object.chainId) : undefined, + timestamp: isSet(object.timestamp) ? Timestamp.fromJSON(object.timestamp) : undefined, + knownLatestVersion: isSet(object.knownLatestVersion) ? BigInt(object.knownLatestVersion) : undefined, + streamInfo: isSet(object.streamInfo) ? StreamInfo.fromJSON(object.streamInfo) : undefined, + }; + }, + + toJSON(message: HistoricalDataServiceInfo): unknown { + const obj: any = {}; + if (message.chainId !== undefined) { + obj.chainId = message.chainId.toString(); + } + if (message.timestamp !== undefined) { + obj.timestamp = Timestamp.toJSON(message.timestamp); + } + if (message.knownLatestVersion !== undefined) { + obj.knownLatestVersion = message.knownLatestVersion.toString(); + } + if (message.streamInfo !== undefined) { + obj.streamInfo = StreamInfo.toJSON(message.streamInfo); + } + return obj; + }, + + create(base?: DeepPartial): HistoricalDataServiceInfo { + return HistoricalDataServiceInfo.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HistoricalDataServiceInfo { + const message = createBaseHistoricalDataServiceInfo(); + message.chainId = object.chainId ?? undefined; + message.timestamp = (object.timestamp !== undefined && object.timestamp !== null) + ? Timestamp.fromPartial(object.timestamp) + : undefined; + message.knownLatestVersion = object.knownLatestVersion ?? undefined; + message.streamInfo = (object.streamInfo !== undefined && object.streamInfo !== null) + ? StreamInfo.fromPartial(object.streamInfo) + : undefined; + return message; + }, +}; + +function createBaseFullnodeInfo(): FullnodeInfo { + return { chainId: undefined, timestamp: undefined, knownLatestVersion: undefined }; +} + +export const FullnodeInfo = { + encode(message: FullnodeInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.chainId !== undefined) { + if (BigInt.asUintN(64, message.chainId) !== message.chainId) { + throw new globalThis.Error("value provided for field message.chainId of type uint64 too large"); + } + writer.uint32(8).uint64(message.chainId.toString()); + } + if (message.timestamp !== undefined) { + Timestamp.encode(message.timestamp, writer.uint32(18).fork()).ldelim(); + } + if (message.knownLatestVersion !== undefined) { + if (BigInt.asUintN(64, message.knownLatestVersion) !== message.knownLatestVersion) { + throw new globalThis.Error("value provided for field message.knownLatestVersion of type uint64 too large"); + } + writer.uint32(24).uint64(message.knownLatestVersion.toString()); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): FullnodeInfo { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFullnodeInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.chainId = longToBigint(reader.uint64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.timestamp = Timestamp.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.knownLatestVersion = longToBigint(reader.uint64() as Long); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [FullnodeInfo.encode(p).finish()]; + } + } else { + yield* [FullnodeInfo.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [FullnodeInfo.decode(p)]; + } + } else { + yield* [FullnodeInfo.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): FullnodeInfo { + return { + chainId: isSet(object.chainId) ? BigInt(object.chainId) : undefined, + timestamp: isSet(object.timestamp) ? Timestamp.fromJSON(object.timestamp) : undefined, + knownLatestVersion: isSet(object.knownLatestVersion) ? BigInt(object.knownLatestVersion) : undefined, + }; + }, + + toJSON(message: FullnodeInfo): unknown { + const obj: any = {}; + if (message.chainId !== undefined) { + obj.chainId = message.chainId.toString(); + } + if (message.timestamp !== undefined) { + obj.timestamp = Timestamp.toJSON(message.timestamp); + } + if (message.knownLatestVersion !== undefined) { + obj.knownLatestVersion = message.knownLatestVersion.toString(); + } + return obj; + }, + + create(base?: DeepPartial): FullnodeInfo { + return FullnodeInfo.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): FullnodeInfo { + const message = createBaseFullnodeInfo(); + message.chainId = object.chainId ?? undefined; + message.timestamp = (object.timestamp !== undefined && object.timestamp !== null) + ? Timestamp.fromPartial(object.timestamp) + : undefined; + message.knownLatestVersion = object.knownLatestVersion ?? undefined; + return message; + }, +}; + +function createBaseGrpcManagerInfo(): GrpcManagerInfo { + return { chainId: undefined, timestamp: undefined, knownLatestVersion: undefined, masterAddress: undefined }; +} + +export const GrpcManagerInfo = { + encode(message: GrpcManagerInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.chainId !== undefined) { + if (BigInt.asUintN(64, message.chainId) !== message.chainId) { + throw new globalThis.Error("value provided for field message.chainId of type uint64 too large"); + } + writer.uint32(8).uint64(message.chainId.toString()); + } + if (message.timestamp !== undefined) { + Timestamp.encode(message.timestamp, writer.uint32(18).fork()).ldelim(); + } + if (message.knownLatestVersion !== undefined) { + if (BigInt.asUintN(64, message.knownLatestVersion) !== message.knownLatestVersion) { + throw new globalThis.Error("value provided for field message.knownLatestVersion of type uint64 too large"); + } + writer.uint32(24).uint64(message.knownLatestVersion.toString()); + } + if (message.masterAddress !== undefined) { + writer.uint32(34).string(message.masterAddress); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): GrpcManagerInfo { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGrpcManagerInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.chainId = longToBigint(reader.uint64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.timestamp = Timestamp.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.knownLatestVersion = longToBigint(reader.uint64() as Long); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.masterAddress = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [GrpcManagerInfo.encode(p).finish()]; + } + } else { + yield* [GrpcManagerInfo.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [GrpcManagerInfo.decode(p)]; + } + } else { + yield* [GrpcManagerInfo.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): GrpcManagerInfo { + return { + chainId: isSet(object.chainId) ? BigInt(object.chainId) : undefined, + timestamp: isSet(object.timestamp) ? Timestamp.fromJSON(object.timestamp) : undefined, + knownLatestVersion: isSet(object.knownLatestVersion) ? BigInt(object.knownLatestVersion) : undefined, + masterAddress: isSet(object.masterAddress) ? globalThis.String(object.masterAddress) : undefined, + }; + }, + + toJSON(message: GrpcManagerInfo): unknown { + const obj: any = {}; + if (message.chainId !== undefined) { + obj.chainId = message.chainId.toString(); + } + if (message.timestamp !== undefined) { + obj.timestamp = Timestamp.toJSON(message.timestamp); + } + if (message.knownLatestVersion !== undefined) { + obj.knownLatestVersion = message.knownLatestVersion.toString(); + } + if (message.masterAddress !== undefined) { + obj.masterAddress = message.masterAddress; + } + return obj; + }, + + create(base?: DeepPartial): GrpcManagerInfo { + return GrpcManagerInfo.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GrpcManagerInfo { + const message = createBaseGrpcManagerInfo(); + message.chainId = object.chainId ?? undefined; + message.timestamp = (object.timestamp !== undefined && object.timestamp !== null) + ? Timestamp.fromPartial(object.timestamp) + : undefined; + message.knownLatestVersion = object.knownLatestVersion ?? undefined; + message.masterAddress = object.masterAddress ?? undefined; + return message; + }, +}; + +function createBaseServiceInfo(): ServiceInfo { + return { + address: undefined, + liveDataServiceInfo: undefined, + historicalDataServiceInfo: undefined, + fullnodeInfo: undefined, + grpcManagerInfo: undefined, + }; +} + +export const ServiceInfo = { + encode(message: ServiceInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.address !== undefined) { + writer.uint32(10).string(message.address); + } + if (message.liveDataServiceInfo !== undefined) { + LiveDataServiceInfo.encode(message.liveDataServiceInfo, writer.uint32(18).fork()).ldelim(); + } + if (message.historicalDataServiceInfo !== undefined) { + HistoricalDataServiceInfo.encode(message.historicalDataServiceInfo, writer.uint32(26).fork()).ldelim(); + } + if (message.fullnodeInfo !== undefined) { + FullnodeInfo.encode(message.fullnodeInfo, writer.uint32(34).fork()).ldelim(); + } + if (message.grpcManagerInfo !== undefined) { + GrpcManagerInfo.encode(message.grpcManagerInfo, writer.uint32(42).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ServiceInfo { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseServiceInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.address = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.liveDataServiceInfo = LiveDataServiceInfo.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.historicalDataServiceInfo = HistoricalDataServiceInfo.decode(reader, reader.uint32()); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.fullnodeInfo = FullnodeInfo.decode(reader, reader.uint32()); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.grpcManagerInfo = GrpcManagerInfo.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [ServiceInfo.encode(p).finish()]; + } + } else { + yield* [ServiceInfo.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [ServiceInfo.decode(p)]; + } + } else { + yield* [ServiceInfo.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): ServiceInfo { + return { + address: isSet(object.address) ? globalThis.String(object.address) : undefined, + liveDataServiceInfo: isSet(object.liveDataServiceInfo) + ? LiveDataServiceInfo.fromJSON(object.liveDataServiceInfo) + : undefined, + historicalDataServiceInfo: isSet(object.historicalDataServiceInfo) + ? HistoricalDataServiceInfo.fromJSON(object.historicalDataServiceInfo) + : undefined, + fullnodeInfo: isSet(object.fullnodeInfo) ? FullnodeInfo.fromJSON(object.fullnodeInfo) : undefined, + grpcManagerInfo: isSet(object.grpcManagerInfo) ? GrpcManagerInfo.fromJSON(object.grpcManagerInfo) : undefined, + }; + }, + + toJSON(message: ServiceInfo): unknown { + const obj: any = {}; + if (message.address !== undefined) { + obj.address = message.address; + } + if (message.liveDataServiceInfo !== undefined) { + obj.liveDataServiceInfo = LiveDataServiceInfo.toJSON(message.liveDataServiceInfo); + } + if (message.historicalDataServiceInfo !== undefined) { + obj.historicalDataServiceInfo = HistoricalDataServiceInfo.toJSON(message.historicalDataServiceInfo); + } + if (message.fullnodeInfo !== undefined) { + obj.fullnodeInfo = FullnodeInfo.toJSON(message.fullnodeInfo); + } + if (message.grpcManagerInfo !== undefined) { + obj.grpcManagerInfo = GrpcManagerInfo.toJSON(message.grpcManagerInfo); + } + return obj; + }, + + create(base?: DeepPartial): ServiceInfo { + return ServiceInfo.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ServiceInfo { + const message = createBaseServiceInfo(); + message.address = object.address ?? undefined; + message.liveDataServiceInfo = (object.liveDataServiceInfo !== undefined && object.liveDataServiceInfo !== null) + ? LiveDataServiceInfo.fromPartial(object.liveDataServiceInfo) + : undefined; + message.historicalDataServiceInfo = + (object.historicalDataServiceInfo !== undefined && object.historicalDataServiceInfo !== null) + ? HistoricalDataServiceInfo.fromPartial(object.historicalDataServiceInfo) + : undefined; + message.fullnodeInfo = (object.fullnodeInfo !== undefined && object.fullnodeInfo !== null) + ? FullnodeInfo.fromPartial(object.fullnodeInfo) + : undefined; + message.grpcManagerInfo = (object.grpcManagerInfo !== undefined && object.grpcManagerInfo !== null) + ? GrpcManagerInfo.fromPartial(object.grpcManagerInfo) + : undefined; + return message; + }, +}; + +function createBaseHeartbeatRequest(): HeartbeatRequest { + return { serviceInfo: undefined }; +} + +export const HeartbeatRequest = { + encode(message: HeartbeatRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.serviceInfo !== undefined) { + ServiceInfo.encode(message.serviceInfo, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): HeartbeatRequest { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHeartbeatRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.serviceInfo = ServiceInfo.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [HeartbeatRequest.encode(p).finish()]; + } + } else { + yield* [HeartbeatRequest.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [HeartbeatRequest.decode(p)]; + } + } else { + yield* [HeartbeatRequest.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): HeartbeatRequest { + return { serviceInfo: isSet(object.serviceInfo) ? ServiceInfo.fromJSON(object.serviceInfo) : undefined }; + }, + + toJSON(message: HeartbeatRequest): unknown { + const obj: any = {}; + if (message.serviceInfo !== undefined) { + obj.serviceInfo = ServiceInfo.toJSON(message.serviceInfo); + } + return obj; + }, + + create(base?: DeepPartial): HeartbeatRequest { + return HeartbeatRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HeartbeatRequest { + const message = createBaseHeartbeatRequest(); + message.serviceInfo = (object.serviceInfo !== undefined && object.serviceInfo !== null) + ? ServiceInfo.fromPartial(object.serviceInfo) + : undefined; + return message; + }, +}; + +function createBaseHeartbeatResponse(): HeartbeatResponse { + return { knownLatestVersion: undefined }; +} + +export const HeartbeatResponse = { + encode(message: HeartbeatResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.knownLatestVersion !== undefined) { + if (BigInt.asUintN(64, message.knownLatestVersion) !== message.knownLatestVersion) { + throw new globalThis.Error("value provided for field message.knownLatestVersion of type uint64 too large"); + } + writer.uint32(8).uint64(message.knownLatestVersion.toString()); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): HeartbeatResponse { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHeartbeatResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.knownLatestVersion = longToBigint(reader.uint64() as Long); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [HeartbeatResponse.encode(p).finish()]; + } + } else { + yield* [HeartbeatResponse.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [HeartbeatResponse.decode(p)]; + } + } else { + yield* [HeartbeatResponse.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): HeartbeatResponse { + return { knownLatestVersion: isSet(object.knownLatestVersion) ? BigInt(object.knownLatestVersion) : undefined }; + }, + + toJSON(message: HeartbeatResponse): unknown { + const obj: any = {}; + if (message.knownLatestVersion !== undefined) { + obj.knownLatestVersion = message.knownLatestVersion.toString(); + } + return obj; + }, + + create(base?: DeepPartial): HeartbeatResponse { + return HeartbeatResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HeartbeatResponse { + const message = createBaseHeartbeatResponse(); + message.knownLatestVersion = object.knownLatestVersion ?? undefined; + return message; + }, +}; + +function createBasePingDataServiceRequest(): PingDataServiceRequest { + return { knownLatestVersion: undefined, pingLiveDataService: false }; +} + +export const PingDataServiceRequest = { + encode(message: PingDataServiceRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.knownLatestVersion !== undefined) { + if (BigInt.asUintN(64, message.knownLatestVersion) !== message.knownLatestVersion) { + throw new globalThis.Error("value provided for field message.knownLatestVersion of type uint64 too large"); + } + writer.uint32(8).uint64(message.knownLatestVersion.toString()); + } + if (message.pingLiveDataService === true) { + writer.uint32(16).bool(message.pingLiveDataService); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PingDataServiceRequest { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePingDataServiceRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.knownLatestVersion = longToBigint(reader.uint64() as Long); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.pingLiveDataService = reader.bool(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: + | AsyncIterable + | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [PingDataServiceRequest.encode(p).finish()]; + } + } else { + yield* [PingDataServiceRequest.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [PingDataServiceRequest.decode(p)]; + } + } else { + yield* [PingDataServiceRequest.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): PingDataServiceRequest { + return { + knownLatestVersion: isSet(object.knownLatestVersion) ? BigInt(object.knownLatestVersion) : undefined, + pingLiveDataService: isSet(object.pingLiveDataService) ? globalThis.Boolean(object.pingLiveDataService) : false, + }; + }, + + toJSON(message: PingDataServiceRequest): unknown { + const obj: any = {}; + if (message.knownLatestVersion !== undefined) { + obj.knownLatestVersion = message.knownLatestVersion.toString(); + } + if (message.pingLiveDataService === true) { + obj.pingLiveDataService = message.pingLiveDataService; + } + return obj; + }, + + create(base?: DeepPartial): PingDataServiceRequest { + return PingDataServiceRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PingDataServiceRequest { + const message = createBasePingDataServiceRequest(); + message.knownLatestVersion = object.knownLatestVersion ?? undefined; + message.pingLiveDataService = object.pingLiveDataService ?? false; + return message; + }, +}; + +function createBasePingDataServiceResponse(): PingDataServiceResponse { + return { liveDataServiceInfo: undefined, historicalDataServiceInfo: undefined }; +} + +export const PingDataServiceResponse = { + encode(message: PingDataServiceResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.liveDataServiceInfo !== undefined) { + LiveDataServiceInfo.encode(message.liveDataServiceInfo, writer.uint32(10).fork()).ldelim(); + } + if (message.historicalDataServiceInfo !== undefined) { + HistoricalDataServiceInfo.encode(message.historicalDataServiceInfo, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PingDataServiceResponse { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePingDataServiceResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.liveDataServiceInfo = LiveDataServiceInfo.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.historicalDataServiceInfo = HistoricalDataServiceInfo.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: + | AsyncIterable + | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [PingDataServiceResponse.encode(p).finish()]; + } + } else { + yield* [PingDataServiceResponse.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [PingDataServiceResponse.decode(p)]; + } + } else { + yield* [PingDataServiceResponse.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): PingDataServiceResponse { + return { + liveDataServiceInfo: isSet(object.liveDataServiceInfo) + ? LiveDataServiceInfo.fromJSON(object.liveDataServiceInfo) + : undefined, + historicalDataServiceInfo: isSet(object.historicalDataServiceInfo) + ? HistoricalDataServiceInfo.fromJSON(object.historicalDataServiceInfo) + : undefined, + }; + }, + + toJSON(message: PingDataServiceResponse): unknown { + const obj: any = {}; + if (message.liveDataServiceInfo !== undefined) { + obj.liveDataServiceInfo = LiveDataServiceInfo.toJSON(message.liveDataServiceInfo); + } + if (message.historicalDataServiceInfo !== undefined) { + obj.historicalDataServiceInfo = HistoricalDataServiceInfo.toJSON(message.historicalDataServiceInfo); + } + return obj; + }, + + create(base?: DeepPartial): PingDataServiceResponse { + return PingDataServiceResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PingDataServiceResponse { + const message = createBasePingDataServiceResponse(); + message.liveDataServiceInfo = (object.liveDataServiceInfo !== undefined && object.liveDataServiceInfo !== null) + ? LiveDataServiceInfo.fromPartial(object.liveDataServiceInfo) + : undefined; + message.historicalDataServiceInfo = + (object.historicalDataServiceInfo !== undefined && object.historicalDataServiceInfo !== null) + ? HistoricalDataServiceInfo.fromPartial(object.historicalDataServiceInfo) + : undefined; + return message; + }, +}; + +function createBaseGetDataServiceForRequestRequest(): GetDataServiceForRequestRequest { + return { userRequest: undefined }; +} + +export const GetDataServiceForRequestRequest = { + encode(message: GetDataServiceForRequestRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.userRequest !== undefined) { + GetTransactionsRequest.encode(message.userRequest, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): GetDataServiceForRequestRequest { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetDataServiceForRequestRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.userRequest = GetTransactionsRequest.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: + | AsyncIterable + | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [GetDataServiceForRequestRequest.encode(p).finish()]; + } + } else { + yield* [GetDataServiceForRequestRequest.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [GetDataServiceForRequestRequest.decode(p)]; + } + } else { + yield* [GetDataServiceForRequestRequest.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): GetDataServiceForRequestRequest { + return { userRequest: isSet(object.userRequest) ? GetTransactionsRequest.fromJSON(object.userRequest) : undefined }; + }, + + toJSON(message: GetDataServiceForRequestRequest): unknown { + const obj: any = {}; + if (message.userRequest !== undefined) { + obj.userRequest = GetTransactionsRequest.toJSON(message.userRequest); + } + return obj; + }, + + create(base?: DeepPartial): GetDataServiceForRequestRequest { + return GetDataServiceForRequestRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GetDataServiceForRequestRequest { + const message = createBaseGetDataServiceForRequestRequest(); + message.userRequest = (object.userRequest !== undefined && object.userRequest !== null) + ? GetTransactionsRequest.fromPartial(object.userRequest) + : undefined; + return message; + }, +}; + +function createBaseGetDataServiceForRequestResponse(): GetDataServiceForRequestResponse { + return { dataServiceAddress: "" }; +} + +export const GetDataServiceForRequestResponse = { + encode(message: GetDataServiceForRequestResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.dataServiceAddress !== undefined && message.dataServiceAddress !== "") { + writer.uint32(10).string(message.dataServiceAddress); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): GetDataServiceForRequestResponse { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetDataServiceForRequestResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.dataServiceAddress = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: + | AsyncIterable + | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [GetDataServiceForRequestResponse.encode(p).finish()]; + } + } else { + yield* [GetDataServiceForRequestResponse.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [GetDataServiceForRequestResponse.decode(p)]; + } + } else { + yield* [GetDataServiceForRequestResponse.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): GetDataServiceForRequestResponse { + return { dataServiceAddress: isSet(object.dataServiceAddress) ? globalThis.String(object.dataServiceAddress) : "" }; + }, + + toJSON(message: GetDataServiceForRequestResponse): unknown { + const obj: any = {}; + if (message.dataServiceAddress !== undefined && message.dataServiceAddress !== "") { + obj.dataServiceAddress = message.dataServiceAddress; + } + return obj; + }, + + create(base?: DeepPartial): GetDataServiceForRequestResponse { + return GetDataServiceForRequestResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GetDataServiceForRequestResponse { + const message = createBaseGetDataServiceForRequestResponse(); + message.dataServiceAddress = object.dataServiceAddress ?? ""; + return message; + }, +}; + +export type GrpcManagerService = typeof GrpcManagerService; +export const GrpcManagerService = { + heartbeat: { + path: "/aptos.indexer.v1.GrpcManager/Heartbeat", + requestStream: false, + responseStream: false, + requestSerialize: (value: HeartbeatRequest) => Buffer.from(HeartbeatRequest.encode(value).finish()), + requestDeserialize: (value: Buffer) => HeartbeatRequest.decode(value), + responseSerialize: (value: HeartbeatResponse) => Buffer.from(HeartbeatResponse.encode(value).finish()), + responseDeserialize: (value: Buffer) => HeartbeatResponse.decode(value), + }, + getTransactions: { + path: "/aptos.indexer.v1.GrpcManager/GetTransactions", + requestStream: false, + responseStream: false, + requestSerialize: (value: GetTransactionsRequest) => Buffer.from(GetTransactionsRequest.encode(value).finish()), + requestDeserialize: (value: Buffer) => GetTransactionsRequest.decode(value), + responseSerialize: (value: TransactionsResponse) => Buffer.from(TransactionsResponse.encode(value).finish()), + responseDeserialize: (value: Buffer) => TransactionsResponse.decode(value), + }, + getDataServiceForRequest: { + path: "/aptos.indexer.v1.GrpcManager/GetDataServiceForRequest", + requestStream: false, + responseStream: false, + requestSerialize: (value: GetDataServiceForRequestRequest) => + Buffer.from(GetDataServiceForRequestRequest.encode(value).finish()), + requestDeserialize: (value: Buffer) => GetDataServiceForRequestRequest.decode(value), + responseSerialize: (value: GetDataServiceForRequestResponse) => + Buffer.from(GetDataServiceForRequestResponse.encode(value).finish()), + responseDeserialize: (value: Buffer) => GetDataServiceForRequestResponse.decode(value), + }, +} as const; + +export interface GrpcManagerServer extends UntypedServiceImplementation { + heartbeat: handleUnaryCall; + getTransactions: handleUnaryCall; + getDataServiceForRequest: handleUnaryCall; +} + +export interface GrpcManagerClient extends Client { + heartbeat( + request: HeartbeatRequest, + callback: (error: ServiceError | null, response: HeartbeatResponse) => void, + ): ClientUnaryCall; + heartbeat( + request: HeartbeatRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: HeartbeatResponse) => void, + ): ClientUnaryCall; + heartbeat( + request: HeartbeatRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: HeartbeatResponse) => void, + ): ClientUnaryCall; + getTransactions( + request: GetTransactionsRequest, + callback: (error: ServiceError | null, response: TransactionsResponse) => void, + ): ClientUnaryCall; + getTransactions( + request: GetTransactionsRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: TransactionsResponse) => void, + ): ClientUnaryCall; + getTransactions( + request: GetTransactionsRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: TransactionsResponse) => void, + ): ClientUnaryCall; + getDataServiceForRequest( + request: GetDataServiceForRequestRequest, + callback: (error: ServiceError | null, response: GetDataServiceForRequestResponse) => void, + ): ClientUnaryCall; + getDataServiceForRequest( + request: GetDataServiceForRequestRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: GetDataServiceForRequestResponse) => void, + ): ClientUnaryCall; + getDataServiceForRequest( + request: GetDataServiceForRequestRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: GetDataServiceForRequestResponse) => void, + ): ClientUnaryCall; +} + +export const GrpcManagerClient = makeGenericClientConstructor( + GrpcManagerService, + "aptos.indexer.v1.GrpcManager", +) as unknown as { + new (address: string, credentials: ChannelCredentials, options?: Partial): GrpcManagerClient; + service: typeof GrpcManagerService; + serviceName: string; +}; + +export type DataServiceService = typeof DataServiceService; +export const DataServiceService = { + ping: { + path: "/aptos.indexer.v1.DataService/Ping", + requestStream: false, + responseStream: false, + requestSerialize: (value: PingDataServiceRequest) => Buffer.from(PingDataServiceRequest.encode(value).finish()), + requestDeserialize: (value: Buffer) => PingDataServiceRequest.decode(value), + responseSerialize: (value: PingDataServiceResponse) => Buffer.from(PingDataServiceResponse.encode(value).finish()), + responseDeserialize: (value: Buffer) => PingDataServiceResponse.decode(value), + }, + getTransactions: { + path: "/aptos.indexer.v1.DataService/GetTransactions", + requestStream: false, + responseStream: true, + requestSerialize: (value: GetTransactionsRequest) => Buffer.from(GetTransactionsRequest.encode(value).finish()), + requestDeserialize: (value: Buffer) => GetTransactionsRequest.decode(value), + responseSerialize: (value: TransactionsResponse) => Buffer.from(TransactionsResponse.encode(value).finish()), + responseDeserialize: (value: Buffer) => TransactionsResponse.decode(value), + }, +} as const; + +export interface DataServiceServer extends UntypedServiceImplementation { + ping: handleUnaryCall; + getTransactions: handleServerStreamingCall; +} + +export interface DataServiceClient extends Client { + ping( + request: PingDataServiceRequest, + callback: (error: ServiceError | null, response: PingDataServiceResponse) => void, + ): ClientUnaryCall; + ping( + request: PingDataServiceRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: PingDataServiceResponse) => void, + ): ClientUnaryCall; + ping( + request: PingDataServiceRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: PingDataServiceResponse) => void, + ): ClientUnaryCall; + getTransactions( + request: GetTransactionsRequest, + options?: Partial, + ): ClientReadableStream; + getTransactions( + request: GetTransactionsRequest, + metadata?: Metadata, + options?: Partial, + ): ClientReadableStream; +} + +export const DataServiceClient = makeGenericClientConstructor( + DataServiceService, + "aptos.indexer.v1.DataService", +) as unknown as { + new (address: string, credentials: ChannelCredentials, options?: Partial): DataServiceClient; + service: typeof DataServiceService; + serviceName: string; +}; + +type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined; + +type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function longToBigint(long: Long) { + return BigInt(long.toString()); +} + +if (_m0.util.Long !== Long) { + _m0.util.Long = Long as any; + _m0.configure(); +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} diff --git a/protos/typescript/src/aptos/transaction/v1/transaction.ts b/protos/typescript/src/aptos/transaction/v1/transaction.ts index 6ec0fd1472bd8..168f6f0c2448d 100644 --- a/protos/typescript/src/aptos/transaction/v1/transaction.ts +++ b/protos/typescript/src/aptos/transaction/v1/transaction.ts @@ -1106,6 +1106,11 @@ export interface MultiKeySignature { signaturesRequired?: number | undefined; } +export interface AbstractionSignature { + functionInfo?: string | undefined; + signature?: Uint8Array | undefined; +} + export interface SingleSender { sender?: AccountSignature | undefined; } @@ -1119,6 +1124,7 @@ export interface AccountSignature { /** 4 is reserved. */ singleKeySignature?: SingleKeySignature | undefined; multiKeySignature?: MultiKeySignature | undefined; + abstraction?: AbstractionSignature | undefined; } export enum AccountSignature_Type { @@ -1127,6 +1133,7 @@ export enum AccountSignature_Type { TYPE_MULTI_ED25519 = 2, TYPE_SINGLE_KEY = 4, TYPE_MULTI_KEY = 5, + TYPE_ABSTRACTION = 6, UNRECOGNIZED = -1, } @@ -1147,6 +1154,9 @@ export function accountSignature_TypeFromJSON(object: any): AccountSignature_Typ case 5: case "TYPE_MULTI_KEY": return AccountSignature_Type.TYPE_MULTI_KEY; + case 6: + case "TYPE_ABSTRACTION": + return AccountSignature_Type.TYPE_ABSTRACTION; case -1: case "UNRECOGNIZED": default: @@ -1166,6 +1176,8 @@ export function accountSignature_TypeToJSON(object: AccountSignature_Type): stri return "TYPE_SINGLE_KEY"; case AccountSignature_Type.TYPE_MULTI_KEY: return "TYPE_MULTI_KEY"; + case AccountSignature_Type.TYPE_ABSTRACTION: + return "TYPE_ABSTRACTION"; case AccountSignature_Type.UNRECOGNIZED: default: return "UNRECOGNIZED"; @@ -10255,6 +10267,114 @@ export const MultiKeySignature = { }, }; +function createBaseAbstractionSignature(): AbstractionSignature { + return { functionInfo: "", signature: new Uint8Array(0) }; +} + +export const AbstractionSignature = { + encode(message: AbstractionSignature, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.functionInfo !== undefined && message.functionInfo !== "") { + writer.uint32(10).string(message.functionInfo); + } + if (message.signature !== undefined && message.signature.length !== 0) { + writer.uint32(18).bytes(message.signature); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AbstractionSignature { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAbstractionSignature(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.functionInfo = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.signature = reader.bytes(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + // encodeTransform encodes a source of message objects. + // Transform + async *encodeTransform( + source: + | AsyncIterable + | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [AbstractionSignature.encode(p).finish()]; + } + } else { + yield* [AbstractionSignature.encode(pkt as any).finish()]; + } + } + }, + + // decodeTransform decodes a source of encoded messages. + // Transform + async *decodeTransform( + source: AsyncIterable | Iterable, + ): AsyncIterable { + for await (const pkt of source) { + if (globalThis.Array.isArray(pkt)) { + for (const p of (pkt as any)) { + yield* [AbstractionSignature.decode(p)]; + } + } else { + yield* [AbstractionSignature.decode(pkt as any)]; + } + } + }, + + fromJSON(object: any): AbstractionSignature { + return { + functionInfo: isSet(object.functionInfo) ? globalThis.String(object.functionInfo) : "", + signature: isSet(object.signature) ? bytesFromBase64(object.signature) : new Uint8Array(0), + }; + }, + + toJSON(message: AbstractionSignature): unknown { + const obj: any = {}; + if (message.functionInfo !== undefined && message.functionInfo !== "") { + obj.functionInfo = message.functionInfo; + } + if (message.signature !== undefined && message.signature.length !== 0) { + obj.signature = base64FromBytes(message.signature); + } + return obj; + }, + + create(base?: DeepPartial): AbstractionSignature { + return AbstractionSignature.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): AbstractionSignature { + const message = createBaseAbstractionSignature(); + message.functionInfo = object.functionInfo ?? ""; + message.signature = object.signature ?? new Uint8Array(0); + return message; + }, +}; + function createBaseSingleSender(): SingleSender { return { sender: undefined }; } @@ -10353,6 +10473,7 @@ function createBaseAccountSignature(): AccountSignature { multiEd25519: undefined, singleKeySignature: undefined, multiKeySignature: undefined, + abstraction: undefined, }; } @@ -10373,6 +10494,9 @@ export const AccountSignature = { if (message.multiKeySignature !== undefined) { MultiKeySignature.encode(message.multiKeySignature, writer.uint32(50).fork()).ldelim(); } + if (message.abstraction !== undefined) { + AbstractionSignature.encode(message.abstraction, writer.uint32(58).fork()).ldelim(); + } return writer; }, @@ -10418,6 +10542,13 @@ export const AccountSignature = { message.multiKeySignature = MultiKeySignature.decode(reader, reader.uint32()); continue; + case 7: + if (tag !== 58) { + break; + } + + message.abstraction = AbstractionSignature.decode(reader, reader.uint32()); + continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -10470,6 +10601,7 @@ export const AccountSignature = { multiKeySignature: isSet(object.multiKeySignature) ? MultiKeySignature.fromJSON(object.multiKeySignature) : undefined, + abstraction: isSet(object.abstraction) ? AbstractionSignature.fromJSON(object.abstraction) : undefined, }; }, @@ -10490,6 +10622,9 @@ export const AccountSignature = { if (message.multiKeySignature !== undefined) { obj.multiKeySignature = MultiKeySignature.toJSON(message.multiKeySignature); } + if (message.abstraction !== undefined) { + obj.abstraction = AbstractionSignature.toJSON(message.abstraction); + } return obj; }, @@ -10511,6 +10646,9 @@ export const AccountSignature = { message.multiKeySignature = (object.multiKeySignature !== undefined && object.multiKeySignature !== null) ? MultiKeySignature.fromPartial(object.multiKeySignature) : undefined; + message.abstraction = (object.abstraction !== undefined && object.abstraction !== null) + ? AbstractionSignature.fromPartial(object.abstraction) + : undefined; return message; }, }; diff --git a/scripts/dev_setup.sh b/scripts/dev_setup.sh index 7d0fdf70199f9..b64e4a156173b 100755 --- a/scripts/dev_setup.sh +++ b/scripts/dev_setup.sh @@ -45,7 +45,6 @@ function usage { echo "-o install operations tooling as well: helm, terraform, yamllint, vault, docker, kubectl, python3" echo "-y install or update Move Prover tools: z3, cvc5, dotnet, boogie" echo "-d install tools for the Move documentation generator: graphviz" - echo "-a install tools for build and test api" echo "-P install PostgreSQL" echo "-J install js/ts tools" echo "-v verbose mode" @@ -801,13 +800,6 @@ protoc and related plugins (since -r was provided): EOF fi - if [[ "$INSTALL_API_BUILD_TOOLS" == "true" ]]; then - cat <, @@ -155,6 +158,19 @@ impl TransactionFactory { )) } + pub fn add_dispatchable_authentication_function( + &self, + function_info: FunctionInfo, + ) -> TransactionBuilder { + self.payload( + aptos_stdlib::account_abstraction_add_dispatchable_authentication_function( + function_info.module_address, + function_info.module_name.into_bytes(), + function_info.function_name.into_bytes(), + ), + ) + } + pub fn implicitly_create_user_account_and_transfer( &self, public_key: &Ed25519PublicKey, diff --git a/sdk/src/types.rs b/sdk/src/types.rs index 22084b72bdc24..d60374bd0b96f 100644 --- a/sdk/src/types.rs +++ b/sdk/src/types.rs @@ -16,34 +16,53 @@ use crate::{ }, }; use anyhow::{Context, Result}; -use aptos_crypto::{ed25519::Ed25519Signature, secp256r1_ecdsa, PrivateKey, SigningKey}; +use aptos_crypto::{ed25519::Ed25519Signature, secp256r1_ecdsa, HashValue, PrivateKey, SigningKey}; use aptos_ledger::AptosLedgerError; -use aptos_rest_client::{Client, PepperRequest, ProverRequest}; +use aptos_rest_client::{aptos_api_types::MoveStructTag, Client, PepperRequest, ProverRequest}; pub use aptos_types::*; use aptos_types::{ event::EventKey, + function_info::FunctionInfo, keyless::{ Claims, Configuration, EphemeralCertificate, IdCommitment, KeylessPublicKey, KeylessSignature, OpenIdSig, Pepper, ZeroKnowledgeSig, }, - transaction::authenticator::{AnyPublicKey, EphemeralPublicKey, EphemeralSignature}, + transaction::{ + authenticator::{AnyPublicKey, EphemeralPublicKey, EphemeralSignature}, + Auth, + }, }; use bip39::{Language, Mnemonic, Seed}; use ed25519_dalek_bip32::{DerivationPath, ExtendedSecretKey}; use keyless::FederatedKeylessPublicKey; +use lazy_static::lazy_static; use rand::Rng; use serde::{Deserialize, Serialize}; use std::{ + fmt, str::FromStr, - sync::atomic::{AtomicU64, Ordering}, + sync::{ + atomic::{AtomicU64, Ordering}, + Arc, + }, time::{Duration, SystemTime, UNIX_EPOCH}, }; +pub const APTOS_COIN_TYPE_STR: &str = "0x1::aptos_coin::AptosCoin"; +lazy_static! { + pub static ref APT_METADATA_ADDRESS: AccountAddress = { + let mut addr = [0u8; 32]; + addr[31] = 10u8; + AccountAddress::new(addr) + }; +} + #[derive(Debug)] enum LocalAccountAuthenticator { PrivateKey(AccountKey), Keyless(KeylessAccount), FederatedKeyless(FederatedKeylessAccount), + Abstraction(AbstractedAccount), // TODO: Add support for keyless authentication } impl LocalAccountAuthenticator { @@ -65,6 +84,7 @@ impl LocalAccountAuthenticator { sig, ) }, + LocalAccountAuthenticator::Abstraction(..) => unreachable!(), } } @@ -118,6 +138,28 @@ pub fn get_apt_primary_store_address(address: AccountAddress) -> AccountAddress AccountAddress::from_bytes(aptos_crypto::hash::HashValue::sha3_256_of(&bytes).to_vec()).unwrap() } +pub fn get_paired_fa_primary_store_address( + address: AccountAddress, + fa_metadata_address: AccountAddress, +) -> AccountAddress { + let mut bytes = address.to_vec(); + bytes.append(&mut fa_metadata_address.to_vec()); + bytes.push(0xFC); + AccountAddress::from_bytes(aptos_crypto::hash::HashValue::sha3_256_of(&bytes).to_vec()).unwrap() +} + +pub fn get_paired_fa_metadata_address(coin_type_name: &MoveStructTag) -> AccountAddress { + let coin_type_name = coin_type_name.to_string(); + if coin_type_name == APTOS_COIN_TYPE_STR { + *APT_METADATA_ADDRESS + } else { + let mut preimage = APT_METADATA_ADDRESS.to_vec(); + preimage.extend(coin_type_name.as_bytes()); + preimage.push(0xFE); + AccountAddress::from_bytes(HashValue::sha3_256_of(&preimage).to_vec()).unwrap() + } +} + impl LocalAccount { /// Create a new representation of an account locally. Note: This function /// does not actually create an account on the Aptos blockchain, just a @@ -355,6 +397,32 @@ impl LocalAccount { .into_inner() } + pub fn sign_aa_transaction_with_transaction_builder( + &self, + secondary_signers: Vec<&Self>, + fee_payer_signer: Option<&Self>, + builder: TransactionBuilder, + ) -> SignedTransaction { + let secondary_signer_addresses = secondary_signers + .iter() + .map(|signer| signer.address()) + .collect(); + let secondary_signer_auths = secondary_signers.iter().map(|a| a.auth()).collect(); + let raw_txn = builder + .sender(self.address()) + .sequence_number(self.increment_sequence_number()) + .build(); + raw_txn + .sign_aa_transaction( + self.auth(), + secondary_signer_addresses, + secondary_signer_auths, + fee_payer_signer.map(|fee_payer| (fee_payer.address(), fee_payer.auth())), + ) + .expect("Signing aa txn failed") + .into_inner() + } + pub fn address(&self) -> AccountAddress { self.address } @@ -364,6 +432,7 @@ impl LocalAccount { LocalAccountAuthenticator::PrivateKey(key) => key.private_key(), LocalAccountAuthenticator::Keyless(_) => todo!(), LocalAccountAuthenticator::FederatedKeyless(_) => todo!(), + LocalAccountAuthenticator::Abstraction(..) => todo!(), } } @@ -372,6 +441,7 @@ impl LocalAccount { LocalAccountAuthenticator::PrivateKey(key) => key.public_key(), LocalAccountAuthenticator::Keyless(_) => todo!(), LocalAccountAuthenticator::FederatedKeyless(_) => todo!(), + LocalAccountAuthenticator::Abstraction(..) => todo!(), } } @@ -384,9 +454,32 @@ impl LocalAccount { LocalAccountAuthenticator::FederatedKeyless(federated_keyless_account) => { federated_keyless_account.authentication_key() }, + LocalAccountAuthenticator::Abstraction(..) => todo!(), + } + } + + pub fn auth(&self) -> Auth { + match &self.auth { + LocalAccountAuthenticator::PrivateKey(key) => Auth::Ed25519(key.private_key()), + LocalAccountAuthenticator::Keyless(_) => todo!(), + LocalAccountAuthenticator::FederatedKeyless(_) => todo!(), + LocalAccountAuthenticator::Abstraction(aa) => { + Auth::Abstraction(aa.function_info.clone(), aa.sign_func.clone()) + }, } } + pub fn set_abstraction_auth( + &mut self, + function_info: FunctionInfo, + sign_func: Arc Vec + Send + Sync>, + ) { + self.auth = LocalAccountAuthenticator::Abstraction(AbstractedAccount { + function_info, + sign_func, + }) + } + pub fn sequence_number(&self) -> u64 { self.sequence_number.load(Ordering::SeqCst) } @@ -409,6 +502,7 @@ impl LocalAccount { LocalAccountAuthenticator::PrivateKey(key) => std::mem::replace(key, new_key.into()), LocalAccountAuthenticator::Keyless(_) => todo!(), LocalAccountAuthenticator::FederatedKeyless(_) => todo!(), + LocalAccountAuthenticator::Abstraction(..) => todo!(), } } @@ -713,6 +807,20 @@ pub struct FederatedKeylessAccount { jwt: Option, } +pub struct AbstractedAccount { + function_info: FunctionInfo, + sign_func: Arc Vec + Send + Sync>, +} + +impl fmt::Debug for AbstractedAccount { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("AbstractedAccount") + .field("function_info", &self.function_info) + .field("sign_func", &"") // Placeholder for the function + .finish() + } +} + impl KeylessAccount { pub fn new( iss: &str, diff --git a/state-sync/state-sync-driver/src/metadata_storage.rs b/state-sync/state-sync-driver/src/metadata_storage.rs index 4b158f4b9945f..a84879bb909ec 100644 --- a/state-sync/state-sync-driver/src/metadata_storage.rs +++ b/state-sync/state-sync-driver/src/metadata_storage.rs @@ -8,9 +8,10 @@ use crate::{ use anyhow::{anyhow, Result}; use aptos_logger::prelude::*; use aptos_schemadb::{ + batch::SchemaBatch, define_schema, schema::{KeyCodec, ValueCodec}, - ColumnFamilyName, Options, SchemaBatch, DB, + ColumnFamilyName, Options, DB, }; use aptos_types::ledger_info::LedgerInfoWithSignatures; use serde::{Deserialize, Serialize}; @@ -144,7 +145,7 @@ impl PersistentMetadataStorage { metadata_value: MetadataValue, ) -> Result<(), Error> { // Create the schema batch - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch .put::(&metadata_key, &metadata_value) .map_err(|error| { diff --git a/storage/aptosdb/Cargo.toml b/storage/aptosdb/Cargo.toml index 1a66f2e434489..889d6b34ffe00 100644 --- a/storage/aptosdb/Cargo.toml +++ b/storage/aptosdb/Cargo.toml @@ -19,7 +19,6 @@ aptos-config = { workspace = true } aptos-crypto = { workspace = true } aptos-db-indexer = { workspace = true } aptos-db-indexer-schemas = { workspace = true, features = ["fuzzing"] } -aptos-executor = { workspace = true } aptos-executor-types = { workspace = true } aptos-experimental-runtimes = { workspace = true } aptos-infallible = { workspace = true } @@ -42,14 +41,12 @@ claims = { workspace = true } clap = { workspace = true, optional = true } crossbeam-channel = { workspace = true, optional = true } dashmap = { workspace = true } -derive_more = { workspace = true } either = { workspace = true } hex = { workspace = true } indicatif = { workspace = true, optional = true } itertools = { workspace = true } lru = { workspace = true } move-core-types = { workspace = true } -num-derive = { workspace = true } once_cell = { workspace = true } owo-colors = { workspace = true, optional = true } proptest = { workspace = true, optional = true } diff --git a/storage/aptosdb/src/backup/restore_handler.rs b/storage/aptosdb/src/backup/restore_handler.rs index 42339c122da73..bacadb5bb9857 100644 --- a/storage/aptosdb/src/backup/restore_handler.rs +++ b/storage/aptosdb/src/backup/restore_handler.rs @@ -97,6 +97,10 @@ impl RestoreHandler { ) } + pub fn force_state_version_for_kv_restore(&self, version: Option) -> Result<()> { + self.state_store.init_state_ignoring_summary(version) + } + pub fn save_transactions_and_replay_kv( &self, first_version: Version, diff --git a/storage/aptosdb/src/backup/restore_utils.rs b/storage/aptosdb/src/backup/restore_utils.rs index 21b4acdb015d5..a6873bcb5214a 100644 --- a/storage/aptosdb/src/backup/restore_utils.rs +++ b/storage/aptosdb/src/backup/restore_utils.rs @@ -14,12 +14,12 @@ use crate::{ transaction_accumulator::TransactionAccumulatorSchema, }, state_store::StateStore, - utils::{new_sharded_kv_schema_batch, ShardedStateKvSchemaBatch}, + utils::ShardedStateKvSchemaBatch, }; use aptos_crypto::HashValue; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::{ - db_ensure as ensure, state_store::state_delta::StateDelta, AptosDbError, Result, + db_ensure as ensure, state_store::state_update_refs::StateUpdateRefs, AptosDbError, Result, }; use aptos_types::{ account_config::new_block_event_key, @@ -121,7 +121,7 @@ pub(crate) fn save_transactions( existing_batch: Option<( &mut LedgerDbSchemaBatches, &mut ShardedStateKvSchemaBatch, - &SchemaBatch, + &mut SchemaBatch, )>, kv_replay: bool, ) -> Result<()> { @@ -140,8 +140,10 @@ pub(crate) fn save_transactions( )?; } else { let mut ledger_db_batch = LedgerDbSchemaBatches::new(); - let mut sharded_kv_schema_batch = new_sharded_kv_schema_batch(); - let state_kv_metadata_batch = SchemaBatch::new(); + let mut sharded_kv_schema_batch = state_store + .state_db + .state_kv_db + .new_sharded_native_batches(); save_transactions_impl( Arc::clone(&state_store), Arc::clone(&ledger_db), @@ -157,17 +159,12 @@ pub(crate) fn save_transactions( // get the last version and commit to the state kv db // commit the state kv before ledger in case of failure happens let last_version = first_version + txns.len() as u64 - 1; - state_store.state_db.state_kv_db.commit( - last_version, - state_kv_metadata_batch, - sharded_kv_schema_batch, - )?; + state_store + .state_db + .state_kv_db + .commit(last_version, None, sharded_kv_schema_batch)?; ledger_db.write_schemas(ledger_db_batch)?; - - state_store - .current_state() - .set(StateDelta::new_empty_with_version(Some(last_version))); } Ok(()) @@ -205,7 +202,7 @@ pub(crate) fn save_transactions_impl( first_version + idx as Version, txn, /*skip_index=*/ false, - &ledger_db_batch.transaction_db_batches, + &mut ledger_db_batch.transaction_db_batches, )?; } @@ -213,7 +210,7 @@ pub(crate) fn save_transactions_impl( TransactionInfoDb::put_transaction_info( first_version + idx as Version, txn_info, - &ledger_db_batch.transaction_info_db_batches, + &mut ledger_db_batch.transaction_info_db_batches, )?; } @@ -222,13 +219,13 @@ pub(crate) fn save_transactions_impl( .put_transaction_accumulator( first_version, txn_infos, - &ledger_db_batch.transaction_accumulator_db_batches, + &mut ledger_db_batch.transaction_accumulator_db_batches, )?; ledger_db.event_db().put_events_multiple_versions( first_version, events, - &ledger_db_batch.event_db_batches, + &mut ledger_db_batch.event_db_batches, )?; if ledger_db.enable_storage_sharding() { @@ -239,7 +236,7 @@ pub(crate) fn save_transactions_impl( LedgerMetadataDb::put_block_info( first_version + idx as Version, event, - &ledger_db_batch.ledger_metadata_db_batches, + &mut ledger_db_batch.ledger_metadata_db_batches, )?; } } @@ -251,18 +248,18 @@ pub(crate) fn save_transactions_impl( WriteSetDb::put_write_set( first_version + idx as Version, ws, - &ledger_db_batch.write_set_db_batches, + &mut ledger_db_batch.write_set_db_batches, )?; } if kv_replay && first_version > 0 && state_store.get_usage(Some(first_version - 1)).is_ok() { - state_store.put_write_sets( - write_sets.to_vec(), - first_version, - &ledger_db_batch.ledger_metadata_db_batches, // used for storing the storage usage + let ledger_state = state_store.calculate_state_and_put_updates( + &StateUpdateRefs::index_write_sets(first_version, write_sets, write_sets.len(), None), + &mut ledger_db_batch.ledger_metadata_db_batches, // used for storing the storage usage state_kv_batches, - state_store.state_kv_db.enabled_sharding(), )?; + // n.b. ideally this is set after the batches are committed + state_store.set_state_ignoring_summary(ledger_state); } let last_version = first_version + txns.len() as u64 - 1; diff --git a/storage/aptosdb/src/backup/test.rs b/storage/aptosdb/src/backup/test.rs index 5b6c9bbff9fff..5ac9cc764095a 100644 --- a/storage/aptosdb/src/backup/test.rs +++ b/storage/aptosdb/src/backup/test.rs @@ -2,10 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::db::{ - test_helper::{arb_blocks_to_commit, update_in_memory_state}, - AptosDB, -}; +use crate::db::{test_helper::arb_blocks_to_commit, AptosDB}; use anyhow::Result; use aptos_temppath::TempPath; use aptos_types::transaction::Version; @@ -18,18 +15,13 @@ proptest! { fn test_get_transaction_iter(input in arb_blocks_to_commit()) { let tmp_dir = TempPath::new(); let db = AptosDB::new_for_test(&tmp_dir); - let mut in_memory_state = db.state_store.current_state_cloned(); - let _ancestor = in_memory_state.base.clone(); let mut cur_ver: Version = 0; for (txns_to_commit, ledger_info_with_sigs) in input.iter() { - update_in_memory_state(&mut in_memory_state, txns_to_commit.as_slice()); db.save_transactions_for_test( txns_to_commit, cur_ver, - cur_ver.checked_sub(1), Some(ledger_info_with_sigs), true, // sync commit - &in_memory_state, ) .unwrap(); cur_ver += txns_to_commit.len() as u64; diff --git a/storage/aptosdb/src/db/aptosdb_test.rs b/storage/aptosdb/src/db/aptosdb_test.rs index 68d32147edd3a..f1ff5353c5a99 100644 --- a/storage/aptosdb/src/db/aptosdb_test.rs +++ b/storage/aptosdb/src/db/aptosdb_test.rs @@ -4,10 +4,7 @@ use crate::{ db::{ get_first_seq_num_and_limit, test_helper, - test_helper::{ - arb_blocks_to_commit, put_as_state_root, put_transaction_auxiliary_data, - put_transaction_infos, - }, + test_helper::{arb_blocks_to_commit, put_transaction_auxiliary_data}, AptosDB, }, pruner::{LedgerPrunerManager, PrunerManager, StateMerklePrunerManager}, @@ -19,19 +16,18 @@ use aptos_config::config::{ DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD, }; use aptos_crypto::{hash::CryptoHash, HashValue}; -use aptos_storage_interface::{DbReader, LedgerSummary, Order}; +use aptos_storage_interface::{DbReader, Order}; use aptos_temppath::TempPath; use aptos_types::{ ledger_info::LedgerInfoWithSignatures, proof::SparseMerkleLeafNode, - state_store::{ - state_key::StateKey, state_storage_usage::StateStorageUsage, state_value::StateValue, - }, + state_store::{state_key::StateKey, state_value::StateValue}, transaction::{ ExecutionStatus, TransactionAuxiliaryData, TransactionAuxiliaryDataV1, TransactionInfo, TransactionToCommit, VMErrorDetail, Version, }, vm_status::StatusCode, + write_set::WriteSet, }; use proptest::prelude::*; use std::{collections::HashSet, sync::Arc}; @@ -176,38 +172,51 @@ fn test_get_transaction_auxiliary_data() { } #[test] -fn test_get_latest_executed_trees() { +fn test_get_latest_ledger_summary() { let tmp_dir = TempPath::new(); let db = AptosDB::new_for_test(&tmp_dir); + db.save_transactions_for_test( + &[], + 0, /* first_version */ + None, /* ledger_info_with_sigs */ + true, /* sync_commit */ + ) + .unwrap(); + // entirely empty db let empty = db.get_pre_committed_ledger_summary().unwrap(); - assert!(empty.is_same_view(&LedgerSummary::new_empty())); + assert_eq!(empty.next_version(), 0); // bootstrapped db (any transaction info is in) let key = StateKey::raw(b"test_key"); let value = StateValue::from(b"test_val".to_vec()); - let hash = SparseMerkleLeafNode::new(key.hash(), value.hash()).hash(); - put_as_state_root(&db, 0, key, value); + let state_hash = SparseMerkleLeafNode::new(key.hash(), value.hash()).hash(); let txn_info = TransactionInfo::new( HashValue::random(), HashValue::random(), HashValue::random(), - Some(hash), + Some(state_hash), 0, ExecutionStatus::MiscellaneousError(None), ); - put_transaction_infos(&db, 0, &[txn_info.clone()]); + let root_hash = txn_info.hash(); + let mut txn_to_commit = TransactionToCommit::dummy(); + txn_to_commit.transaction_info = txn_info; + txn_to_commit.write_set = WriteSet::new_for_test([(key, Some(value))]); + + db.save_transactions_for_test( + &[txn_to_commit], + 0, /* first_version */ + None, /* ledger_info_with_sigs */ + true, /* sync_commit */ + ) + .unwrap(); let bootstrapped = db.get_pre_committed_ledger_summary().unwrap(); - assert!( - bootstrapped.is_same_view(&LedgerSummary::new_at_state_checkpoint( - txn_info.state_checkpoint_hash().unwrap(), - StateStorageUsage::new_untracked(), - vec![txn_info.hash()], - 1, - )) - ); + assert_eq!(bootstrapped.next_version(), 1); + assert_eq!(bootstrapped.transaction_accumulator.root_hash(), root_hash,); + assert_eq!(bootstrapped.state_summary.root_hash(), state_hash); } pub fn test_state_merkle_pruning_impl( @@ -245,19 +254,14 @@ pub fn test_state_merkle_pruning_impl( .unwrap(); // augment DB in blocks - let mut in_memory_state = db.state_store.current_state_cloned(); - let _ancester = in_memory_state.current.clone(); let mut next_ver: Version = 0; let mut snapshot_versions = vec![]; for (txns_to_commit, ledger_info_with_sigs) in input.iter() { - test_helper::update_in_memory_state(&mut in_memory_state, txns_to_commit.as_slice()); db.save_transactions_for_test( txns_to_commit, - next_ver, /* first_version */ - next_ver.checked_sub(1), /* base_state_version */ + next_ver, /* first_version */ Some(ledger_info_with_sigs), true, /* sync_commit */ - &in_memory_state, ) .unwrap(); diff --git a/storage/aptosdb/src/db/fake_aptosdb.rs b/storage/aptosdb/src/db/fake_aptosdb.rs index c3faf81301baa..f54a44edc133e 100644 --- a/storage/aptosdb/src/db/fake_aptosdb.rs +++ b/storage/aptosdb/src/db/fake_aptosdb.rs @@ -18,7 +18,7 @@ use aptos_scratchpad::SparseMerkleTree; use aptos_storage_interface::{ db_ensure as ensure, state_store::{ - sharded_state_updates::ShardedStateUpdates, state_delta::StateDelta, + state_delta::StateDelta, state_update_refs::BatchedStateUpdateRefs, state_view::cached_state_view::ShardedStateCache, }, AptosDbError, DbReader, DbWriter, LedgerSummary, MAX_REQUEST_LIMIT, @@ -108,7 +108,7 @@ impl FakeBufferedState { pub fn update( &mut self, - updates_until_next_checkpoint_since_current_option: Option<&ShardedStateUpdates>, + updates_until_next_checkpoint_since_current_option: Option<&BatchedStateUpdateRefs>, new_state_after_checkpoint: StateDelta, ) -> Result<()> { ensure!( @@ -373,7 +373,7 @@ impl FakeAptosDB { ledger_info_with_sigs: Option<&LedgerInfoWithSignatures>, sync_commit: bool, latest_in_memory_state: StateDelta, - state_updates_until_last_checkpoint: Option, + state_updates_until_last_checkpoint: Option, ) -> Result<()> { gauged_api("save_transactions", || { // Executing and committing from more than one threads not allowed -- consensus and @@ -410,6 +410,7 @@ impl FakeAptosDB { ledger_info_with_sigs, sync_commit, &latest_in_memory_state, + true, )?; } @@ -460,7 +461,7 @@ impl DbWriter for FakeAptosDB { ledger_info_with_sigs: Option<&LedgerInfoWithSignatures>, sync_commit: bool, latest_in_memory_state: StateDelta, - state_updates_until_last_checkpoint: Option, + state_updates_until_last_checkpoint: Option, _sharded_state_cache: Option<&ShardedStateCache>, ) -> Result<()> { debug!( @@ -815,22 +816,22 @@ impl DbReader for FakeAptosDB { fn get_state_proof_by_version_ext( &self, - state_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result { self.inner - .get_state_proof_by_version_ext(state_key, version, root_depth) + .get_state_proof_by_version_ext(key_hash, version, root_depth) } fn get_state_value_with_proof_by_version_ext( &self, - state_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result<(Option, SparseMerkleProofExt)> { self.inner - .get_state_value_with_proof_by_version_ext(state_key, version, root_depth) + .get_state_value_with_proof_by_version_ext(key_hash, version, root_depth) } fn get_pre_committed_ledger_summary(&self) -> Result { @@ -860,10 +861,6 @@ impl DbReader for FakeAptosDB { }) } - fn get_buffered_state_base(&self) -> Result> { - self.inner.get_buffered_state_base() - } - fn get_latest_block_events(&self, num_events: usize) -> Result> { self.inner.get_latest_block_events(num_events) } diff --git a/storage/aptosdb/src/db/include/aptosdb_reader.rs b/storage/aptosdb/src/db/include/aptosdb_reader.rs index 7a29fee5eaf8f..d0496fbf99fef 100644 --- a/storage/aptosdb/src/db/include/aptosdb_reader.rs +++ b/storage/aptosdb/src/db/include/aptosdb_reader.rs @@ -1,9 +1,23 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +use aptos_storage_interface::state_store::state::State; +use aptos_storage_interface::state_store::state_summary::StateSummary; use aptos_types::block_info::BlockHeight; impl DbReader for AptosDB { + fn get_persisted_state(&self) -> Result { + gauged_api("get_persisted_state", || { + self.state_store.get_persisted_state() + }) + } + + fn get_persisted_state_summary(&self) -> Result { + gauged_api("get_persisted_state_summary", || { + self.state_store.get_persisted_state_summary() + }) + } + fn get_epoch_ending_ledger_infos( &self, start_epoch: u64, @@ -63,7 +77,7 @@ impl DbReader for AptosDB { fn get_pre_committed_version(&self) -> Result> { gauged_api("get_pre_committed_version", || { - Ok(self.state_store.current_state().current_version) + Ok(self.state_store.current_state_locked().version()) }) } @@ -485,7 +499,7 @@ impl DbReader for AptosDB { /// Returns the proof of the given state key and version. fn get_state_proof_by_version_ext( &self, - state_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result { @@ -493,13 +507,13 @@ impl DbReader for AptosDB { self.error_if_state_merkle_pruned("State merkle", version)?; self.state_store - .get_state_proof_by_version_ext(state_key, version, root_depth) + .get_state_proof_by_version_ext(key_hash, version, root_depth) }) } fn get_state_value_with_proof_by_version_ext( &self, - state_store_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result<(Option, SparseMerkleProofExt)> { @@ -507,7 +521,7 @@ impl DbReader for AptosDB { self.error_if_state_merkle_pruned("State merkle", version)?; self.state_store.get_state_value_with_proof_by_version_ext( - state_store_key, + key_hash, version, root_depth, ) @@ -529,8 +543,8 @@ impl DbReader for AptosDB { fn get_pre_committed_ledger_summary(&self) -> Result { gauged_api("get_pre_committed_ledger_summary", || { - let current_state = self.state_store.current_state_cloned(); - let num_txns = current_state.next_version(); + let (state, state_summary) = self.state_store.current_state_locked().to_state_and_summary(); + let num_txns = state.next_version(); let frozen_subtrees = self .ledger_db @@ -538,17 +552,11 @@ impl DbReader for AptosDB { .get_frozen_subtree_hashes(num_txns)?; let transaction_accumulator = Arc::new(InMemoryAccumulator::new(frozen_subtrees, num_txns)?); - let ledger_summary = LedgerSummary::new( - Arc::new(current_state), + Ok(LedgerSummary { + state, + state_summary, transaction_accumulator, - ); - Ok(ledger_summary) - }) - } - - fn get_buffered_state_base(&self) -> Result> { - gauged_api("get_buffered_state_base", || { - self.state_store.get_buffered_state_base() + }) }) } @@ -638,11 +646,7 @@ impl DbReader for AptosDB { fn get_latest_state_checkpoint_version(&self) -> Result> { gauged_api("get_latest_state_checkpoint_version", || { - Ok(self - .state_store - .current_state() - .base_version - ) + Ok(self.state_store.current_state_locked().last_checkpoint().version()) }) } diff --git a/storage/aptosdb/src/db/include/aptosdb_testonly.rs b/storage/aptosdb/src/db/include/aptosdb_testonly.rs index 77288df003b01..dd295855d36d9 100644 --- a/storage/aptosdb/src/db/include/aptosdb_testonly.rs +++ b/storage/aptosdb/src/db/include/aptosdb_testonly.rs @@ -3,11 +3,9 @@ use aptos_config::config::{BUFFERED_STATE_TARGET_ITEMS_FOR_TEST, DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD}; use std::default::Default; -use aptos_storage_interface::state_store::state_view::cached_state_view::ShardedStateCache; -use aptos_storage_interface::state_store::state_delta::StateDelta; use aptos_types::transaction::{TransactionStatus, TransactionToCommit}; use aptos_executor_types::transactions_with_output::TransactionsToKeep; -use aptos_storage_interface::state_store::sharded_state_update_refs::ShardedStateUpdateRefs; +use aptos_storage_interface::state_store::state_summary::ProvableStateSummary; impl AptosDB { /// This opens db in non-readonly mode, without the pruner. @@ -90,6 +88,7 @@ impl AptosDB { ) } + #[cfg(test)] pub(crate) fn state_merkle_db(&self) -> Arc { self.state_store.state_db.state_merkle_db.clone() } @@ -101,85 +100,42 @@ impl AptosDB { &self, txns_to_commit: &[TransactionToCommit], first_version: Version, - base_state_version: Option, ledger_info_with_sigs: Option<&LedgerInfoWithSignatures>, sync_commit: bool, - latest_in_memory_state: &StateDelta, ) -> Result<()> { - let chunk = ChunkToCommitOwned::from_test_txns_to_commit( - txns_to_commit, - first_version, - base_state_version, - latest_in_memory_state, - ); - self.save_transactions( - chunk.as_ref(), - ledger_info_with_sigs, - sync_commit, - ) - } -} - -pub struct ChunkToCommitOwned { - first_version: Version, - transactions_to_keep: TransactionsToKeep, - transaction_infos: Vec, - base_state_version: Option, - latest_in_memory_state: Arc, - state_updates_until_last_checkpoint: Option, - sharded_state_cache: Option, - is_reconfig: bool, -} - -impl ChunkToCommitOwned { - pub fn from_test_txns_to_commit( - txns_to_commit: &[TransactionToCommit], - first_version: Version, - base_state_version: Option, - latest_in_memory_state: &StateDelta, - ) -> Self { let (transactions, transaction_outputs, transaction_infos) = Self::disassemble_txns_to_commit(txns_to_commit); - let is_reconfig = transaction_outputs .iter() .rev() .flat_map(TransactionOutput::events) .any(ContractEvent::is_new_epoch_event); + let transactions_to_keep = TransactionsToKeep::make(first_version, transactions, transaction_outputs, is_reconfig); - let transactions_to_keep = TransactionsToKeep::make(transactions, transaction_outputs, is_reconfig); - - let state_updates_until_last_checkpoint = Self::gather_state_updates_until_last_checkpoint( - first_version, - latest_in_memory_state, + let current = self.state_store.current_state_locked().clone(); + let persisted = self.state_store.persisted_state_locked().clone(); + let (new_state, reads) = current.ledger_state().update_with_db_reader( + persisted.state(), transactions_to_keep.state_update_refs(), - &transaction_infos, - ); + self.state_store.clone(), + )?; + let new_state_summary = current.ledger_state_summary().update( + &ProvableStateSummary::new(persisted.summary().clone(), self), + transactions_to_keep.state_update_refs(), + )?; - Self { + let chunk = ChunkToCommit { first_version, - transactions_to_keep, - transaction_infos, - base_state_version, - latest_in_memory_state: Arc::new(latest_in_memory_state.clone()), - state_updates_until_last_checkpoint, - sharded_state_cache: None, + transactions: &transactions_to_keep.transactions, + transaction_outputs: &transactions_to_keep.transaction_outputs, + transaction_infos: &transaction_infos, + state: &new_state, + state_summary: &new_state_summary, + state_update_refs: transactions_to_keep.state_update_refs(), + state_reads: &reads, is_reconfig, - } - } + }; - pub fn as_ref(&self) -> ChunkToCommit { - ChunkToCommit { - first_version: self.first_version, - transactions: &self.transactions_to_keep.transactions, - transaction_outputs: &self.transactions_to_keep.transaction_outputs, - transaction_infos: &self.transaction_infos, - base_state_version: self.base_state_version, - latest_in_memory_state: &self.latest_in_memory_state, - state_update_refs: self.transactions_to_keep.state_update_refs(), - state_updates_until_last_checkpoint: self.state_updates_until_last_checkpoint.as_ref(), - sharded_state_cache: self.sharded_state_cache.as_ref(), - is_reconfig: self.is_reconfig, - } + self.save_transactions( chunk, ledger_info_with_sigs, sync_commit) } fn disassemble_txns_to_commit(txns_to_commit: &[TransactionToCommit]) -> ( @@ -201,40 +157,4 @@ impl ChunkToCommitOwned { (transaction.clone(), transaction_output, transaction_info.clone()) }).multiunzip() } - - pub fn gather_state_updates_until_last_checkpoint( - first_version: Version, - latest_in_memory_state: &StateDelta, - state_update_refs: &ShardedStateUpdateRefs, - transaction_infos: &[TransactionInfo], - ) -> Option { - if let Some(latest_checkpoint_version) = latest_in_memory_state.base_version { - if latest_checkpoint_version >= first_version { - let idx = (latest_checkpoint_version - first_version) as usize; - assert!( - transaction_infos[idx].state_checkpoint_hash().is_some(), - "The new latest snapshot version passed in {:?} does not match with the last checkpoint version in txns_to_commit {:?}", - latest_checkpoint_version, - first_version + idx as u64 - ); - let mut sharded_state_updates = ShardedStateUpdates::new_empty(); - sharded_state_updates - .shards - .par_iter_mut() - .zip_eq(state_update_refs.shards.par_iter()) - .for_each(|(updates, index)| { - updates - .extend( - index - .iter() - .take_while(|(i, _k, _v)| *i <= idx) - .map(|(_i, k, v)| ((*k).clone(), v.cloned())) - ); - }); - return Some(sharded_state_updates); - } - } - - None - } } diff --git a/storage/aptosdb/src/db/include/aptosdb_writer.rs b/storage/aptosdb/src/db/include/aptosdb_writer.rs index ea387084ec67f..ef02303e12a1d 100644 --- a/storage/aptosdb/src/db/include/aptosdb_writer.rs +++ b/storage/aptosdb/src/db/include/aptosdb_writer.rs @@ -21,7 +21,7 @@ impl DbWriter for AptosDB { .expect("Concurrent committing detected."); let _timer = OTHER_TIMERS_SECONDS.timer_with(&["pre_commit_ledger"]); - chunk.latest_in_memory_state.current.log_generation("db_save"); + chunk.state_summary.latest().global_state_summary.log_generation("db_save"); self.pre_commit_validation(&chunk)?; let _new_root_hash = self.calculate_and_commit_ledger_and_state_kv( @@ -29,19 +29,13 @@ impl DbWriter for AptosDB { self.skip_index_and_usage, )?; - // n.b make sure buffered_state.update() is called after all other commits are done, since - // internally it updates state_store.current_state which indicates the "pre-committed version" let _timer = OTHER_TIMERS_SECONDS.timer_with(&["save_transactions__others"]); - { - let mut buffered_state = self.state_store.buffered_state().lock(); - - let _timer = OTHER_TIMERS_SECONDS.timer_with(&["buffered_state___update"]); - buffered_state.update( - chunk.state_updates_until_last_checkpoint, - chunk.latest_in_memory_state, - sync_commit || chunk.is_reconfig, - )?; - } + + self.state_store.buffered_state().lock().update( + chunk.result_ledger_state_with_summary(), + chunk.estimated_total_state_updates(), + sync_commit || chunk.is_reconfig, + )?; Ok(()) }) @@ -66,10 +60,10 @@ impl DbWriter for AptosDB { let old_committed_ver = self.get_and_check_commit_range(version)?; - let ledger_batch = SchemaBatch::new(); + let mut ledger_batch = SchemaBatch::new(); // Write down LedgerInfo if provided. if let Some(li) = ledger_info_with_sigs { - self.check_and_put_ledger_info(version, li, &ledger_batch)?; + self.check_and_put_ledger_info(version, li, &mut ledger_batch)?; } // Write down commit progress ledger_batch.put::( @@ -138,8 +132,8 @@ impl DbWriter for AptosDB { // Create a single change set for all further write operations let mut ledger_db_batch = LedgerDbSchemaBatches::new(); - let mut sharded_kv_batch = new_sharded_kv_schema_batch(); - let state_kv_metadata_batch = SchemaBatch::new(); + let mut sharded_kv_batch = self.state_kv_db.new_sharded_native_batches(); + let mut state_kv_metadata_batch = SchemaBatch::new(); // Save the target transactions, outputs, infos and events let (transactions, outputs): (Vec, Vec) = output_with_proof @@ -168,7 +162,7 @@ impl DbWriter for AptosDB { Some(( &mut ledger_db_batch, &mut sharded_kv_batch, - &state_kv_metadata_batch, + &mut state_kv_metadata_batch, )), false, )?; @@ -222,40 +216,20 @@ impl AptosDB { &self, chunk: &ChunkToCommit, ) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["save_transactions_validation"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["save_transactions_validation"]); + ensure!(!chunk.is_empty(), "chunk is empty, nothing to save."); + + let next_version = self.state_store.current_state_locked().next_version(); + // Ensure the incoming committing requests are always consecutive and the version in + // buffered state is consistent with that in db. ensure!( - !chunk.is_empty(), - "chunk is empty, nothing to save.", - ); - ensure!( - Some(chunk.expect_last_version()) == chunk.latest_in_memory_state.current_version, - "the last_version {:?} to commit doesn't match the current_version {:?} in latest_in_memory_state", - chunk.expect_last_version(), - chunk.latest_in_memory_state.current_version.expect("Must exist"), + chunk.first_version == next_version, + "The first version passed in ({}), and the next version expected by db ({}) are inconsistent.", + chunk.first_version, + next_version, ); - { - let current_state = self.state_store.current_state(); - ensure!( - chunk.base_state_version == current_state.base_version, - "base_state_version {:?} does not equal to the base_version {:?} in buffered state with current version {:?}", - chunk.base_state_version, - current_state.base_version, - current_state.current_version, - ); - - // Ensure the incoming committing requests are always consecutive and the version in - // buffered state is consistent with that in db. - ensure!(chunk.first_version == current_state.next_version(), - "The first version passed in ({}), and the next version expected by db ({}) are inconsistent.", - chunk.first_version, - current_state.next_version(), - ); - } - Ok(()) } @@ -264,9 +238,8 @@ impl AptosDB { chunk: &ChunkToCommit, skip_index_and_usage: bool, ) -> Result { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["save_transactions__work"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["save_transactions__work"]); + let mut new_root_hash = HashValue::zero(); THREAD_MANAGER.get_non_exe_cpu_pool().scope(|s| { // TODO(grao): Write progress for each of the following databases, and handle the @@ -282,7 +255,7 @@ impl AptosDB { .write_set_db() .commit_write_sets( chunk.first_version, - chunk.transaction_outputs.par_iter().map(TransactionOutput::write_set) + chunk.transaction_outputs, ) .unwrap() }); @@ -318,31 +291,17 @@ impl AptosDB { chunk: &ChunkToCommit, skip_index_and_usage: bool, ) -> Result<()> { - if chunk.is_empty() { - return Ok(()); - } - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_state_kv_and_ledger_metadata"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_state_kv_and_ledger_metadata"]); - let ledger_metadata_batch = SchemaBatch::new(); - let sharded_state_kv_batches = new_sharded_kv_schema_batch(); - let state_kv_metadata_batch = SchemaBatch::new(); + let mut ledger_metadata_batch = SchemaBatch::new(); + let mut sharded_state_kv_batches = self.state_kv_db.new_sharded_native_batches(); - // TODO(grao): Make state_store take sharded state updates. - self.state_store.put_value_sets( - chunk.first_version, - chunk.state_update_refs, - chunk.latest_in_memory_state.current.usage(), - chunk.sharded_state_cache, - &ledger_metadata_batch, - &sharded_state_kv_batches, - // Always put in state value index for now. - // TODO(grao): remove after APIs migrated off the DB to the indexer. - self.state_store.state_kv_db.enabled_sharding(), - chunk.transaction_infos - .iter() - .rposition(|t| t.state_checkpoint_hash().is_some()), + self.state_store.put_state_updates( + chunk.state, + &chunk.state_update_refs.per_version, + chunk.state_reads, + &mut ledger_metadata_batch, + &mut sharded_state_kv_batches, )?; // Write block index if event index is skipped. @@ -355,7 +314,7 @@ impl AptosDB { LedgerMetadataDb::put_block_info( version, event, - &ledger_metadata_batch, + &mut ledger_metadata_batch, )?; } } @@ -370,9 +329,7 @@ impl AptosDB { ) .unwrap(); - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_state_kv_and_ledger_metadata___commit"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_state_kv_and_ledger_metadata___commit"]); rayon::scope(|s| { s.spawn(|_| { self.ledger_db @@ -384,7 +341,7 @@ impl AptosDB { self.state_kv_db .commit( chunk.expect_last_version(), - state_kv_metadata_batch, + None, sharded_state_kv_batches, ) .unwrap(); @@ -400,28 +357,36 @@ impl AptosDB { transaction_outputs: &[TransactionOutput], skip_index: bool, ) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_events"]) - .start_timer(); - let batch = SchemaBatch::new(); - transaction_outputs - .par_iter() - .with_min_len(optimal_min_len(transaction_outputs.len(), 128)) + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_events"]); + + let chunk_size = transaction_outputs.len() / 4 + 1; + let batches = transaction_outputs + .par_chunks(chunk_size) .enumerate() - .try_for_each(|(i, txn_out)| -> Result<()> { - self.ledger_db.event_db().put_events( - first_version + i as Version, - txn_out.events(), - skip_index, - &batch, - )?; + .map(|(chunk_idx, chunk)| { + let mut batch = self.ledger_db.event_db().db().new_native_batch(); + let chunk_first_ver = first_version + (chunk_size * chunk_idx) as u64; + chunk.iter().enumerate().try_for_each(|(i, txn_out)| { + self.ledger_db.event_db().put_events( + chunk_first_ver + i as Version, + txn_out.events(), + skip_index, + &mut batch, + ) + })?; + Ok(batch) + }) + .collect::>>()?; - Ok(()) - })?; - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_events___commit"]) - .start_timer(); - self.ledger_db.event_db().write_schemas(batch) + { + let _timer = OTHER_TIMERS_SECONDS + .with_label_values(&["commit_events___commit"]) + .start_timer(); + for batch in batches { + self.ledger_db.event_db().db().write_schemas(batch)? + } + Ok(()) + } } fn commit_transaction_accumulator( @@ -429,30 +394,26 @@ impl AptosDB { first_version: Version, transaction_infos: &[TransactionInfo], ) -> Result { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_transaction_accumulator"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transaction_accumulator"]); let num_txns = transaction_infos.len() as Version; - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let root_hash = self .ledger_db .transaction_accumulator_db() .put_transaction_accumulator( first_version, transaction_infos, - &batch, + &mut batch, )?; - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_transaction_accumulator___commit"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transaction_accumulator___commit"]); self.ledger_db .transaction_accumulator_db() .write_schemas(batch)?; - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let all_versions: Vec<_> = (first_version..first_version + num_txns).collect(); THREAD_MANAGER @@ -488,11 +449,9 @@ impl AptosDB { first_version: Version, auxiliary_data: impl IntoIterator, ) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_transaction_auxiliary_data"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transaction_auxiliary_data"]); - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); auxiliary_data .into_iter() .enumerate() @@ -500,15 +459,13 @@ impl AptosDB { TransactionAuxiliaryDataDb::put_transaction_auxiliary_data( first_version + i as Version, aux_data, - &batch, + &mut batch, )?; Ok(()) })?; - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_transaction_auxiliary_data___commit"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transaction_auxiliary_data___commit"]); self.ledger_db .transaction_auxiliary_data_db() .write_schemas(batch) @@ -519,28 +476,24 @@ impl AptosDB { first_version: Version, txn_infos: &[TransactionInfo], ) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_transaction_infos"]) - .start_timer(); - let batch = SchemaBatch::new(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transaction_infos"]); + + let mut batch = SchemaBatch::new(); txn_infos - .par_iter() - .with_min_len(optimal_min_len(txn_infos.len(), 128)) + .iter() .enumerate() .try_for_each(|(i, txn_info)| -> Result<()> { let version = first_version + i as u64; TransactionInfoDb::put_transaction_info( version, txn_info, - &batch, + &mut batch, )?; Ok(()) })?; - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_transaction_infos___commit"]) - .start_timer(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transaction_infos___commit"]); self.ledger_db.transaction_info_db().write_schemas(batch) } @@ -549,7 +502,7 @@ impl AptosDB { version_to_commit: Version, ) -> Result> { let old_committed_ver = self.ledger_db.metadata_db().get_synced_version()?; - let pre_committed_ver = self.state_store.current_state().current_version; + let pre_committed_ver = self.state_store.current_state_locked().version(); ensure!( old_committed_ver.is_none() || version_to_commit >= old_committed_ver.unwrap(), "Version too old to commit. Committed: {:?}; Trying to commit with LI: {}", @@ -569,7 +522,7 @@ impl AptosDB { &self, version: Version, ledger_info_with_sig: &LedgerInfoWithSignatures, - ledger_batch: &SchemaBatch + ledger_batch: &mut SchemaBatch ) -> Result<(), AptosDbError> { let ledger_info = ledger_info_with_sig.ledger_info(); diff --git a/storage/aptosdb/src/db/mod.rs b/storage/aptosdb/src/db/mod.rs index 425974c8b5043..4569cdc6e17de 100644 --- a/storage/aptosdb/src/db/mod.rs +++ b/storage/aptosdb/src/db/mod.rs @@ -26,23 +26,20 @@ use crate::{ state_merkle_db::StateMerkleDb, state_store::StateStore, transaction_store::TransactionStore, - utils::new_sharded_kv_schema_batch, }; use aptos_config::config::{ PrunerConfig, RocksdbConfig, RocksdbConfigs, StorageDirPaths, NO_OP_STORAGE_PRUNER_CONFIG, }; use aptos_crypto::HashValue; use aptos_db_indexer::{db_indexer::InternalIndexerDB, Indexer}; -use aptos_experimental_runtimes::thread_manager::{optimal_min_len, THREAD_MANAGER}; +use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_logger::prelude::*; use aptos_metrics_core::TimerHelper; use aptos_resource_viewer::AptosValueAnnotator; -use aptos_schemadb::SchemaBatch; -use aptos_scratchpad::SparseMerkleTree; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::{ - db_ensure as ensure, db_other_bail as bail, - state_store::sharded_state_updates::ShardedStateUpdates, AptosDbError, DbReader, DbWriter, - LedgerSummary, Order, Result, StateSnapshotReceiver, MAX_REQUEST_LIMIT, + db_ensure as ensure, db_other_bail as bail, AptosDbError, DbReader, DbWriter, LedgerSummary, + Order, Result, StateSnapshotReceiver, MAX_REQUEST_LIMIT, }; use aptos_types::{ account_address::AccountAddress, @@ -236,8 +233,8 @@ impl AptosDB { genesis_li.ledger_info().epoch() == current_epoch && current_epoch == 0, "Genesis ledger info epoch is not 0" ); - let ledger_batch = SchemaBatch::new(); - ledger_metadata_db.put_ledger_info(genesis_li, &ledger_batch)?; + let mut ledger_batch = SchemaBatch::new(); + ledger_metadata_db.put_ledger_info(genesis_li, &mut ledger_batch)?; ledger_metadata_db.write_schemas(ledger_batch) } } diff --git a/storage/aptosdb/src/db/test_helper.rs b/storage/aptosdb/src/db/test_helper.rs index 6de6bce71bb76..bd4446d35287c 100644 --- a/storage/aptosdb/src/db/test_helper.rs +++ b/storage/aptosdb/src/db/test_helper.rs @@ -3,27 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 //! This module provides reusable helpers in tests. -#[cfg(test)] -use crate::state_store::StateStore; -#[cfg(test)] -use crate::utils::new_sharded_kv_schema_batch; -use crate::{ - schema::{jellyfish_merkle_node::JellyfishMerkleNodeSchema, state_value::StateValueSchema}, - AptosDB, + +use crate::AptosDB; +use aptos_crypto::{ + hash::{CryptoHash, SPARSE_MERKLE_PLACEHOLDER_HASH}, + HashValue, }; -use aptos_crypto::hash::CryptoHash; -#[cfg(test)] -use aptos_crypto::HashValue; -use aptos_executor_types::ProofReader; -use aptos_jellyfish_merkle::node_type::{Node, NodeKey}; -#[cfg(test)] -use aptos_schemadb::SchemaBatch; -use aptos_storage_interface::{state_store::state_delta::StateDelta, DbReader, Order, Result}; +use aptos_scratchpad::SparseMerkleTree; +use aptos_storage_interface::{DbReader, Order, Result}; use aptos_temppath::TempPath; -#[cfg(test)] -use aptos_types::state_store::state_storage_usage::StateStorageUsage; -#[cfg(test)] -use aptos_types::transaction::TransactionAuxiliaryData; use aptos_types::{ account_address::AccountAddress, contract_event::ContractEvent, @@ -32,139 +20,113 @@ use aptos_types::{ proof::accumulator::{InMemoryEventAccumulator, InMemoryTransactionAccumulator}, proptest_types::{AccountInfoUniverse, BlockGen}, state_store::{state_key::StateKey, state_value::StateValue}, - transaction::{Transaction, TransactionInfo, TransactionToCommit, Version}, + transaction::{ + Transaction, TransactionAuxiliaryData, TransactionInfo, TransactionToCommit, Version, + }, write_set::TransactionWrite, }; -use proptest::{collection::vec, prelude::*, sample::Index}; -use std::{collections::HashMap, fmt::Debug}; +use itertools::Itertools; +use proptest::{ + collection::{hash_set, vec}, + prelude::*, + sample::Index, +}; +use std::{ + collections::{HashMap, HashSet}, + fmt::Debug, +}; + +/// hack: special keys to guarantee state db has at least two keys +fn kv_genesis_keys() -> Vec { + vec![StateKey::raw(b"g1"), StateKey::raw(b"g2")] +} + +/// hack: special keys to guarantee state db has at least two keys +pub fn kv_store_genesis() -> Vec<(StateKey, Option)> { + kv_genesis_keys() + .into_iter() + .map(|k| (k, Some(StateValue::from(b"genesis_value".to_vec())))) + .collect() +} + +fn arb_key_universe(size: usize) -> impl Strategy> { + let genesis_keys = kv_genesis_keys(); + hash_set( + any::().prop_filter( + "hack: special keys to guarantee state db has at least two keys", + move |k| genesis_keys.iter().all(|gk| gk != k), + ), + size, + ) + .prop_map(move |keys| keys.into_iter().collect_vec()) +} prop_compose! { pub fn arb_state_kv_sets( key_universe_size: usize, max_update_set_size: usize, - max_versions: usize - ) - ( - keys in vec(any::(), key_universe_size), - input in vec(vec((any::(), any::>()), 1..max_update_set_size), 1..max_versions) + max_versions: usize, + )( + keys in arb_key_universe(key_universe_size), + input in vec( + vec( + any::<(Index, Option)>(), + 1..=max_update_set_size, + ), + 1..=max_versions + ) ) -> Vec)>> { - input + input .into_iter() .map(|kvs| kvs .into_iter() .map(|(idx, value)| (idx.get(&keys).clone(), value)) - .collect::>() + .collect_vec() ) - .collect::>() + .collect_vec() + } +} + +prop_compose! { + pub fn arb_state_kv_sets_with_genesis( + key_universe_size: usize, + max_update_set_size: usize, + max_versions: usize, + )( + sets in arb_state_kv_sets(key_universe_size, max_update_set_size, max_versions - 1), + ) -> Vec)>> { + std::iter::once(kv_store_genesis()) + .chain(sets.into_iter()) + .collect_vec() } } #[cfg(test)] pub(crate) fn update_store( - store: &StateStore, + store: &crate::state_store::StateStore, input: impl Iterator)>, first_version: Version, - enable_sharding: bool, ) -> HashValue { - use aptos_storage_interface::{ - jmt_update_refs, jmt_updates, - state_store::sharded_state_update_refs::ShardedStateUpdateRefs, - }; - - let mut root_hash = *aptos_crypto::hash::SPARSE_MERKLE_PLACEHOLDER_HASH; - for (i, (key, value)) in input.enumerate() { - let value_state_set = vec![(&key, value.as_ref())].into_iter().collect(); - let jmt_updates = jmt_updates(&value_state_set); - let version = first_version + i as Version; - root_hash = store - .merklize_value_set( - jmt_update_refs(&jmt_updates), - version, - version.checked_sub(1), - ) - .unwrap(); - let ledger_batch = SchemaBatch::new(); - let sharded_state_kv_batches = new_sharded_kv_schema_batch(); - let schema_batch = SchemaBatch::new(); - store - .put_value_sets( - version, - &ShardedStateUpdateRefs::index_per_version_updates([[(&key, value.as_ref())]], 1), - StateStorageUsage::new_untracked(), - None, - &ledger_batch, - &sharded_state_kv_batches, - /*put_state_value_indices=*/ enable_sharding, - /*last_checkpoint_index=*/ None, - ) - .unwrap(); - store - .ledger_db - .metadata_db() - .write_schemas(ledger_batch) - .unwrap(); - store - .state_kv_db - .commit(version, schema_batch, sharded_state_kv_batches) - .unwrap(); - } - root_hash + store.commit_block_for_test(first_version, input.map(|(key, value)| [(key, value)])) } -pub fn update_in_memory_state(state: &mut StateDelta, txns_to_commit: &[TransactionToCommit]) { - let mut next_version = state.current_version.map_or(0, |v| v + 1); - for txn_to_commit in txns_to_commit { - txn_to_commit - .write_set - .state_updates_cloned() - .for_each(|(key, value)| { - state.updates_since_base.insert(key, value); - }); - next_version += 1; - if txn_to_commit.has_state_checkpoint_hash() { - state.current = state - .current - .batch_update( - state - .updates_since_base - .shards - .iter() - .flatten() - .map(|(k, v)| (k.hash(), v.as_ref())) - .collect(), - &ProofReader::new_empty(), - ) - .unwrap(); - state.current_version = next_version.checked_sub(1); - state.base = state.current.clone(); - state.base_version = state.current_version; - state - .updates_since_base - .shards - .iter_mut() - .for_each(|shard| { - shard.clear(); - }); - } - } - - if next_version.checked_sub(1) != state.current_version { - state.current = state - .current - .batch_update( - state - .updates_since_base - .shards - .iter() - .flatten() - .map(|(k, v)| (k.hash(), v.as_ref())) - .collect(), - &ProofReader::new_empty(), - ) - .unwrap(); - state.current_version = next_version.checked_sub(1); - } +pub fn update_in_memory_state( + smt: &SparseMerkleTree, + root_smt: &SparseMerkleTree, + txns_to_commit: &[TransactionToCommit], +) -> SparseMerkleTree { + let updates = txns_to_commit + .iter() + .flat_map(|txn_to_commit| txn_to_commit.write_set().state_update_refs()) + .collect::>() + .into_iter() + .map(|(k, u)| (k.hash(), u)) + .collect(); + smt.freeze(root_smt) + .batch_update(updates, &()) + .unwrap() + .unfreeze() } prop_compose! { @@ -184,15 +146,15 @@ prop_compose! { block_gens in vec(any_with::(max_user_txns_per_block), min_blocks..=max_blocks), ) -> Vec<(Vec, LedgerInfoWithSignatures)> { let mut txn_accumulator = InMemoryTransactionAccumulator::new_empty(); - let mut result = Vec::new(); + let root_smt = SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH); + let mut smt = root_smt.clone(); - let mut in_memory_state = StateDelta::new_empty(); - let _ancester = in_memory_state.current.clone(); + let mut result = Vec::new(); for block_gen in block_gens { let (mut txns_to_commit, mut ledger_info) = block_gen.materialize(&mut universe); - update_in_memory_state(&mut in_memory_state, &txns_to_commit); - let state_checkpoint_root_hash = in_memory_state.root_hash(); + smt = update_in_memory_state(&smt, &root_smt, &txns_to_commit); + let state_checkpoint_root_hash = smt.root_hash(); // make real txn_info's for txn in txns_to_commit.iter_mut() { @@ -314,39 +276,42 @@ fn verify_epochs(db: &AptosDB, ledger_infos_with_sigs: &[LedgerInfoWithSignature } } +fn count_state_updates(txns_to_commit: &[TransactionToCommit]) -> usize { + txns_to_commit + .iter() + .flat_map(|t| t.write_set.state_update_refs()) + .map(|(k, _v)| k) + .collect::>() + .len() +} + fn gen_snapshot_version( - updates: &mut HashMap>, + estimated_buffer_size: &mut usize, txns_to_commit: &[TransactionToCommit], - cur_ver: Version, + first_version: Version, threshold: usize, ) -> Option { - let mut snapshot_version = None; let last_checkpoint = txns_to_commit .iter() .rposition(TransactionToCommit::has_state_checkpoint_hash); + if let Some(idx) = last_checkpoint { - updates.extend( - txns_to_commit[0..=idx] - .iter() - .flat_map(|x| x.write_set().state_updates_cloned()), - ); - if updates.len() >= threshold || txns_to_commit[idx].is_reconfig { - snapshot_version = Some(cur_ver + idx as u64); - updates.clear(); + *estimated_buffer_size += count_state_updates(&txns_to_commit[0..=idx]); + if idx + 1 != txns_to_commit.len() { + *estimated_buffer_size += count_state_updates(&txns_to_commit[idx + 1..]) } - updates.extend( - txns_to_commit[idx + 1..] - .iter() - .flat_map(|x| x.write_set().state_updates_cloned()), - ); } else { - updates.extend( - txns_to_commit - .iter() - .flat_map(|x| x.write_set().state_updates_cloned()), - ); + *estimated_buffer_size += count_state_updates(txns_to_commit) } - snapshot_version + + if let Some(idx) = last_checkpoint { + if *estimated_buffer_size >= threshold || txns_to_commit[idx].is_reconfig { + *estimated_buffer_size = 0; + return Some(first_version + idx as Version); + } + } + + None } pub fn test_save_blocks_impl( @@ -357,27 +322,22 @@ pub fn test_save_blocks_impl( let db = AptosDB::new_for_test_with_buffered_state_target_items(&tmp_dir, snapshot_size_threshold); - let mut in_memory_state = db.state_store.current_state_cloned(); - let _ancester = in_memory_state.current.clone(); let num_batches = input.len(); let mut cur_ver: Version = 0; let mut all_committed_txns = vec![]; - let mut updates = HashMap::new(); + let mut estimated_buffer_size = 0; let mut snapshot_versions = vec![]; for (batch_idx, (txns_to_commit, ledger_info_with_sigs)) in input.iter().enumerate() { - update_in_memory_state(&mut in_memory_state, txns_to_commit.as_slice()); db.save_transactions_for_test( txns_to_commit, - cur_ver, /* first_version */ - cur_ver.checked_sub(1), /* base_state_version */ + cur_ver, /* first_version */ Some(ledger_info_with_sigs), false, /* sync_commit */ - &in_memory_state, ) .unwrap(); if let Some(v) = gen_snapshot_version( - &mut updates, + &mut estimated_buffer_size, txns_to_commit, cur_ver, snapshot_size_threshold, @@ -893,8 +853,7 @@ pub fn verify_committed_transactions( verify_account_txns(db, group_txns_by_account(txns_to_commit), ledger_info); } -#[cfg(test)] -pub(crate) fn put_transaction_infos( +pub fn put_transaction_infos( db: &AptosDB, version: Version, txn_infos: &[TransactionInfo], @@ -904,8 +863,7 @@ pub(crate) fn put_transaction_infos( .unwrap() } -#[cfg(test)] -pub(crate) fn put_transaction_auxiliary_data( +pub fn put_transaction_auxiliary_data( db: &AptosDB, version: Version, auxiliary_data: &[TransactionAuxiliaryData], @@ -914,32 +872,6 @@ pub(crate) fn put_transaction_auxiliary_data( .unwrap(); } -pub fn put_as_state_root(db: &AptosDB, version: Version, key: StateKey, value: StateValue) { - let leaf_node = Node::new_leaf(key.hash(), value.hash(), (key.clone(), version)); - db.state_merkle_db() - .metadata_db() - .put::(&NodeKey::new_empty_path(version), &leaf_node) - .unwrap(); - let smt = db - .get_buffered_state_base() - .unwrap() - .batch_update(vec![(key.hash(), Some(&value))], &ProofReader::new_empty()) - .unwrap(); - db.state_kv_db - .metadata_db() - .put::(&(key.clone(), version), &Some(value.clone())) - .unwrap(); - let mut in_memory_state = db.state_store.current_state_cloned(); - in_memory_state.current = smt; - in_memory_state.current_version = Some(version); - in_memory_state.updates_since_base.insert(key, Some(value)); - db.state_store - .buffered_state() - .lock() - .update(None, &in_memory_state, true) - .unwrap(); -} - pub fn test_sync_transactions_impl( input: Vec<(Vec, LedgerInfoWithSignatures)>, snapshot_size_threshold: usize, @@ -948,46 +880,46 @@ pub fn test_sync_transactions_impl( let db = AptosDB::new_for_test_with_buffered_state_target_items(&tmp_dir, snapshot_size_threshold); - let mut in_memory_state = db.state_store.current_state_cloned(); - let _ancester = in_memory_state.current.clone(); let num_batches = input.len(); let mut cur_ver: Version = 0; - let mut updates = HashMap::new(); + let mut estimated_buffer_size = 0; let mut snapshot_versions = vec![]; for (batch_idx, (txns_to_commit, ledger_info_with_sigs)) in input.iter().enumerate() { // if batch has more than 2 transactions, save them in two batches let batch1_len = txns_to_commit.len() / 2; - let base_state_version = cur_ver.checked_sub(1); if batch1_len > 0 { let txns_to_commit_batch = &txns_to_commit[..batch1_len]; - update_in_memory_state(&mut in_memory_state, txns_to_commit_batch); db.save_transactions_for_test( txns_to_commit_batch, cur_ver, /* first_version */ - base_state_version, - None, /* ledger_info_with_sigs */ - false, /* sync_commit */ - &in_memory_state, + None, /* ledger_info_with_sigs */ + false, /* sync_commit */ ) .unwrap(); + + if let Some(v) = gen_snapshot_version( + &mut estimated_buffer_size, + txns_to_commit_batch, + cur_ver, + snapshot_size_threshold, + ) { + snapshot_versions.push(v); + } } let ver = cur_ver + batch1_len as Version; let txns_to_commit_batch = &txns_to_commit[batch1_len..]; - update_in_memory_state(&mut in_memory_state, txns_to_commit_batch); db.save_transactions_for_test( txns_to_commit_batch, ver, - base_state_version, Some(ledger_info_with_sigs), false, /* sync_commit */ - &in_memory_state, ) .unwrap(); if let Some(v) = gen_snapshot_version( - &mut updates, - txns_to_commit, - cur_ver, + &mut estimated_buffer_size, + txns_to_commit_batch, + ver, snapshot_size_threshold, ) { snapshot_versions.push(v); diff --git a/storage/aptosdb/src/db_debugger/state_tree/get_path.rs b/storage/aptosdb/src/db_debugger/state_tree/get_path.rs index 0e7e2b838545e..74552db7379dd 100644 --- a/storage/aptosdb/src/db_debugger/state_tree/get_path.rs +++ b/storage/aptosdb/src/db_debugger/state_tree/get_path.rs @@ -6,7 +6,7 @@ use crate::{ schema::jellyfish_merkle_node::JellyfishMerkleNodeSchema, state_merkle_db::StateMerkleDb, }; -use aptos_crypto::{hash::CryptoHash, HashValue}; +use aptos_crypto::HashValue; use aptos_jellyfish_merkle::{ node_type::{Child, Node, NodeKey, NodeType}, TreeReader, @@ -170,7 +170,7 @@ impl Cmd { }, Some(Node::Leaf(leaf_node)) => { let state_key = leaf_node.value_index().0.clone(); - assert_eq!(state_key.hash(), leaf_node.account_key()); + assert_eq!(state_key.crypto_hash_ref(), leaf_node.account_key()); let serialized = hex::encode(bcs::to_bytes(&state_key).unwrap()); println!(" state key: {:?}\n", state_key); diff --git a/storage/aptosdb/src/db_debugger/truncate/mod.rs b/storage/aptosdb/src/db_debugger/truncate/mod.rs index 548bdf8961bd1..c7c8c23498f1e 100644 --- a/storage/aptosdb/src/db_debugger/truncate/mod.rs +++ b/storage/aptosdb/src/db_debugger/truncate/mod.rs @@ -11,7 +11,7 @@ use crate::{ }, }; use aptos_config::config::{RocksdbConfigs, StorageDirPaths}; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::{db_ensure as ensure, AptosDbError, Result}; use claims::assert_le; use clap::Parser; @@ -120,7 +120,7 @@ impl Cmd { } println!("Starting db truncation..."); - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch.put::( &DbMetadataKey::OverallCommitProgress, &DbMetadataValue::Version(target_version), @@ -159,10 +159,7 @@ impl Cmd { mod test { use super::*; use crate::{ - db::{ - test_helper::{arb_blocks_to_commit_with_block_nums, update_in_memory_state}, - AptosDB, - }, + db::{test_helper::arb_blocks_to_commit_with_block_nums, AptosDB}, schema::{ epoch_by_version::EpochByVersionSchema, jellyfish_merkle_node::JellyfishMerkleNodeSchema, ledger_info::LedgerInfoSchema, @@ -194,18 +191,13 @@ mod test { let tmp_dir = TempPath::new(); let db = if input.1 { AptosDB::new_for_test_with_sharding(&tmp_dir, DEFAULT_MAX_NUM_NODES_PER_LRU_CACHE_SHARD) } else { AptosDB::new_for_test(&tmp_dir) }; - let mut in_memory_state = db.state_store.current_state_cloned(); - let _ancestor = in_memory_state.base.clone(); let mut version = 0; for (txns_to_commit, ledger_info_with_sigs) in input.0.iter() { - update_in_memory_state(&mut in_memory_state, txns_to_commit.as_slice()); db.save_transactions_for_test( txns_to_commit, version, - version.checked_sub(1), Some(ledger_info_with_sigs), true, - &in_memory_state, ) .unwrap(); version += txns_to_commit.len() as u64; diff --git a/storage/aptosdb/src/event_store/mod.rs b/storage/aptosdb/src/event_store/mod.rs index e909ab782a4f7..481d890471d29 100644 --- a/storage/aptosdb/src/event_store/mod.rs +++ b/storage/aptosdb/src/event_store/mod.rs @@ -7,34 +7,26 @@ #![allow(unused)] use super::AptosDB; -use crate::{ - schema::{event::EventSchema, event_accumulator::EventAccumulatorSchema}, - utils::iterators::EventsByVersionIter, -}; +use crate::schema::{event::EventSchema, event_accumulator::EventAccumulatorSchema}; use anyhow::anyhow; -use aptos_accumulator::{HashReader, MerkleAccumulator}; -use aptos_crypto::{ - hash::{CryptoHash, EventAccumulatorHasher}, - HashValue, -}; +use aptos_accumulator::HashReader; +use aptos_crypto::{hash::CryptoHash, HashValue}; use aptos_db_indexer_schemas::schema::{ event_by_key::EventByKeySchema, event_by_version::EventByVersionSchema, - translated_v1_event::TranslatedV1EventSchema, }; -use aptos_schemadb::{iterator::SchemaIterator, schema::ValueCodec, ReadOptions, SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, schema::ValueCodec, DB}; use aptos_storage_interface::{db_ensure as ensure, db_other_bail, AptosDbError, Result}; use aptos_types::{ account_address::AccountAddress, account_config::{new_block_event_key, NewBlockEvent}, - contract_event::{ContractEvent, ContractEventV1}, + contract_event::ContractEvent, event::EventKey, proof::position::Position, transaction::Version, }; use std::{ - collections::{hash_map::Entry, HashMap, HashSet}, + collections::HashMap, convert::{TryFrom, TryInto}, - iter::Peekable, sync::Arc, }; @@ -330,7 +322,7 @@ impl EventStore { &self, begin: Version, end: Version, - db_batch: &SchemaBatch, + db_batch: &mut SchemaBatch, ) -> anyhow::Result<()> { let mut iter = self.event_db.iter::()?; iter.seek(&(begin, Position::from_inorder_index(0)))?; diff --git a/storage/aptosdb/src/event_store/test.rs b/storage/aptosdb/src/event_store/test.rs index e27b1bd720884..d6afb1d3a48e1 100644 --- a/storage/aptosdb/src/event_store/test.rs +++ b/storage/aptosdb/src/event_store/test.rs @@ -100,10 +100,10 @@ fn test_index_get_impl(event_batches: Vec>) { let store = &db.event_store; let event_db = &db.ledger_db.event_db(); - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); event_batches.iter().enumerate().for_each(|(ver, events)| { event_db - .put_events(ver as u64, events, /*skip_index=*/ false, &batch) + .put_events(ver as u64, events, /*skip_index=*/ false, &mut batch) .unwrap(); }); event_db.write_schemas(batch); @@ -233,10 +233,15 @@ fn test_get_last_version_before_timestamp_impl(new_block_events: Vec<(Version, C assert!(store.get_last_version_before_timestamp(1000, 2000).is_err()); // save events to db - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); new_block_events.iter().for_each(|(ver, event)| { event_db - .put_events(*ver, &[event.clone()], /*skip_index=*/ false, &batch) + .put_events( + *ver, + &[event.clone()], + /*skip_index=*/ false, + &mut batch, + ) .unwrap(); }); event_db.write_schemas(batch); diff --git a/storage/aptosdb/src/ledger_db/event_db.rs b/storage/aptosdb/src/ledger_db/event_db.rs index f34586cfbb42d..afbff0e22515f 100644 --- a/storage/aptosdb/src/ledger_db/event_db.rs +++ b/storage/aptosdb/src/ledger_db/event_db.rs @@ -18,7 +18,10 @@ use aptos_crypto::{ use aptos_db_indexer_schemas::schema::{ event_by_key::EventByKeySchema, event_by_version::EventByVersionSchema, }; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{ + batch::{SchemaBatch, WriteBatch}, + DB, +}; use aptos_storage_interface::{AptosDbError, Result}; use aptos_types::{ account_config::new_block_event_key, contract_event::ContractEvent, transaction::Version, @@ -48,7 +51,7 @@ impl EventDb { ) } - pub(super) fn db(&self) -> &DB { + pub(crate) fn db(&self) -> &DB { &self.db } @@ -128,7 +131,7 @@ impl EventDb { &self, first_version: u64, event_vecs: &[Vec], - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> { event_vecs.iter().enumerate().try_for_each(|(idx, events)| { let version = first_version @@ -144,7 +147,7 @@ impl EventDb { version: u64, events: &[ContractEvent], skip_index: bool, - batch: &SchemaBatch, + batch: &mut impl WriteBatch, ) -> Result<()> { // Event table and indices updates events @@ -184,20 +187,25 @@ impl EventDb { Ok(()) } - /// Deletes a set of events in the range of version in [begin, end), and all related indices. - pub(crate) fn prune_events( + /// Deletes event indices, returns number of events per version, so `prune_events` doesn't need + /// to iterate through evnets from DB again. + pub(crate) fn prune_event_indices( &self, start: Version, end: Version, - db_batch: &SchemaBatch, - indices_batch: Option<&SchemaBatch>, - ) -> anyhow::Result<()> { + mut indices_batch: Option<&mut SchemaBatch>, + ) -> Result> { + let mut ret = Vec::new(); + let mut current_version = start; for events in self.get_events_by_version_iter(start, (end - start) as usize)? { - for (idx, event) in (events?).into_iter().enumerate() { - if let ContractEvent::V1(v1) = event { - if let Some(batch) = indices_batch { + let events = events?; + ret.push(events.len()); + + if let Some(ref mut batch) = indices_batch { + for event in events { + if let ContractEvent::V1(v1) = event { batch.delete::(&(*v1.key(), v1.sequence_number()))?; batch.delete::(&( *v1.key(), @@ -206,6 +214,25 @@ impl EventDb { ))?; } } + } + current_version += 1; + } + + Ok(ret) + } + + /// Deletes a set of events in the range of version in [begin, end), and all related indices. + pub(crate) fn prune_events( + &self, + num_events_per_version: Vec, + start: Version, + end: Version, + db_batch: &mut SchemaBatch, + ) -> Result<()> { + let mut current_version = start; + + for num_events in num_events_per_version { + for idx in 0..num_events { db_batch.delete::(&(current_version, idx as u64))?; } current_version += 1; diff --git a/storage/aptosdb/src/ledger_db/event_db_test.rs b/storage/aptosdb/src/ledger_db/event_db_test.rs index 0bf3dba1695f6..f126f4feb296a 100644 --- a/storage/aptosdb/src/ledger_db/event_db_test.rs +++ b/storage/aptosdb/src/ledger_db/event_db_test.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::db::AptosDB; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::Result; use aptos_temppath::TempPath; use aptos_types::contract_event::ContractEvent; @@ -19,8 +19,8 @@ proptest! { prop_assert_eq!(event_db.latest_version().unwrap(), None); - let batch = SchemaBatch::new(); - event_db.put_events(100, &events, /*skip_index=*/false, &batch).unwrap(); + let mut batch = SchemaBatch::new(); + event_db.put_events(100, &events, /*skip_index=*/false, &mut batch).unwrap(); event_db.write_schemas(batch).unwrap(); prop_assert_eq!(event_db.latest_version().unwrap(), Some(100)); @@ -39,8 +39,8 @@ proptest! { let tmp_dir = TempPath::new(); let db = AptosDB::new_for_test(&tmp_dir); let event_db = &db.ledger_db.event_db(); - let batch = SchemaBatch::new(); - event_db.put_events_multiple_versions(99, &[events1.clone(), events2.clone(), events3.clone()], &batch).unwrap(); + let mut batch = SchemaBatch::new(); + event_db.put_events_multiple_versions(99, &[events1.clone(), events2.clone(), events3.clone()], &mut batch).unwrap(); event_db.write_schemas(batch).unwrap(); let events_99 = event_db.get_events_by_version(99).unwrap(); diff --git a/storage/aptosdb/src/ledger_db/ledger_metadata_db.rs b/storage/aptosdb/src/ledger_db/ledger_metadata_db.rs index 01fad778dec7f..39494dae4dee9 100644 --- a/storage/aptosdb/src/ledger_db/ledger_metadata_db.rs +++ b/storage/aptosdb/src/ledger_db/ledger_metadata_db.rs @@ -13,7 +13,7 @@ use crate::{ utils::{get_progress, iterators::EpochEndingLedgerInfoIter}, }; use anyhow::anyhow; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::{block_info::BlockInfo, db_ensure as ensure, AptosDbError, Result}; use aptos_types::{ account_config::NewBlockEvent, block_info::BlockHeight, contract_event::ContractEvent, @@ -186,7 +186,7 @@ impl LedgerMetadataDb { pub(crate) fn put_ledger_info( &self, ledger_info_with_sigs: &LedgerInfoWithSignatures, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> { let ledger_info = ledger_info_with_sigs.ledger_info(); @@ -296,7 +296,7 @@ impl LedgerMetadataDb { pub(crate) fn put_block_info( version: Version, event: &ContractEvent, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> { let new_block_event = NewBlockEvent::try_from_bytes(event.event_data())?; let block_height = new_block_event.height(); diff --git a/storage/aptosdb/src/ledger_db/ledger_metadata_db_test.rs b/storage/aptosdb/src/ledger_db/ledger_metadata_db_test.rs index b14c98b70a754..5357e36275121 100644 --- a/storage/aptosdb/src/ledger_db/ledger_metadata_db_test.rs +++ b/storage/aptosdb/src/ledger_db/ledger_metadata_db_test.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ledger_db::ledger_metadata_db::LedgerMetadataDb, AptosDB}; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::AptosDbError; use aptos_temppath::TempPath; use aptos_types::{ @@ -63,10 +63,10 @@ fn set_up(path: &impl AsRef, ledger_infos_with_sigs: &[LedgerInfoWithSigna let db = AptosDB::new_for_test(path); let ledger_metadata_db = db.ledger_db.metadata_db(); - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); ledger_infos_with_sigs .iter() - .map(|info| ledger_metadata_db.put_ledger_info(info, &batch)) + .map(|info| ledger_metadata_db.put_ledger_info(info, &mut batch)) .collect::, AptosDbError>>() .unwrap(); ledger_metadata_db.write_schemas(batch).unwrap(); @@ -233,7 +233,7 @@ fn test_block_api() { let db = AptosDB::new_for_test(&tmp_dir); let ledger_metadata_db = db.ledger_db.metadata_db(); - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let proposer_1 = AccountAddress::random(); let proposer_2 = AccountAddress::random(); let events = vec![ @@ -266,7 +266,7 @@ fn test_block_api() { TypeTag::from(NewBlockEvent::struct_tag()), bcs::to_bytes(&events[0]).unwrap(), ), - &batch, + &mut batch, ) .unwrap(); LedgerMetadataDb::put_block_info( @@ -277,7 +277,7 @@ fn test_block_api() { TypeTag::from(NewBlockEvent::struct_tag()), bcs::to_bytes(&events[1]).unwrap(), ), - &batch, + &mut batch, ) .unwrap(); ledger_metadata_db.write_schemas(batch).unwrap(); diff --git a/storage/aptosdb/src/ledger_db/mod.rs b/storage/aptosdb/src/ledger_db/mod.rs index 96d886360bd3b..351e2fa384cd1 100644 --- a/storage/aptosdb/src/ledger_db/mod.rs +++ b/storage/aptosdb/src/ledger_db/mod.rs @@ -27,7 +27,7 @@ use aptos_config::config::{RocksdbConfig, RocksdbConfigs}; use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_logger::prelude::info; use aptos_rocksdb_options::gen_rocksdb_options; -use aptos_schemadb::{ColumnFamilyDescriptor, ColumnFamilyName, SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, ColumnFamilyDescriptor, ColumnFamilyName, DB}; use aptos_storage_interface::Result; use aptos_types::transaction::Version; use std::{ diff --git a/storage/aptosdb/src/ledger_db/transaction_accumulator_db.rs b/storage/aptosdb/src/ledger_db/transaction_accumulator_db.rs index e5d14e6fefab1..3612a5f4d45f4 100644 --- a/storage/aptosdb/src/ledger_db/transaction_accumulator_db.rs +++ b/storage/aptosdb/src/ledger_db/transaction_accumulator_db.rs @@ -12,7 +12,7 @@ use aptos_crypto::{ hash::{CryptoHash, TransactionAccumulatorHasher}, HashValue, }; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::Result; use aptos_types::{ proof::{ @@ -109,7 +109,7 @@ impl TransactionAccumulatorDb { &self, first_version: Version, txn_infos: &[impl Borrow], - transaction_accumulator_batch: &SchemaBatch, + transaction_accumulator_batch: &mut SchemaBatch, ) -> Result { let txn_hashes: Vec = txn_infos.iter().map(|t| t.borrow().hash()).collect(); @@ -146,7 +146,7 @@ impl TransactionAccumulatorDb { /// 2. From the node found from the previous step, delete both its children non-useful, and go /// to the right child to repeat the process until we reach a leaf node. /// More details are in this issue https://github.com/aptos-labs/aptos-core/issues/1288. - pub(crate) fn prune(begin: Version, end: Version, db_batch: &SchemaBatch) -> Result<()> { + pub(crate) fn prune(begin: Version, end: Version, db_batch: &mut SchemaBatch) -> Result<()> { for version_to_delete in begin..end { db_batch.delete::(&version_to_delete)?; // The even version will be pruned in the iteration of version + 1. diff --git a/storage/aptosdb/src/ledger_db/transaction_auxiliary_data_db.rs b/storage/aptosdb/src/ledger_db/transaction_auxiliary_data_db.rs index a3b0226a484c5..d67a958fa281b 100644 --- a/storage/aptosdb/src/ledger_db/transaction_auxiliary_data_db.rs +++ b/storage/aptosdb/src/ledger_db/transaction_auxiliary_data_db.rs @@ -8,7 +8,7 @@ use crate::{ }, utils::iterators::ExpectContinuousVersions, }; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::Result; use aptos_types::transaction::{TransactionAuxiliaryData, Version}; use std::{path::Path, sync::Arc}; @@ -65,13 +65,13 @@ impl TransactionAuxiliaryDataDb { pub(crate) fn put_transaction_auxiliary_data( version: Version, transaction_auxiliary_data: &TransactionAuxiliaryData, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> { batch.put::(&version, transaction_auxiliary_data) } /// Deletes the transaction info between a range of version in [begin, end) - pub(crate) fn prune(begin: Version, end: Version, batch: &SchemaBatch) -> Result<()> { + pub(crate) fn prune(begin: Version, end: Version, batch: &mut SchemaBatch) -> Result<()> { for version in begin..end { batch.delete::(&version)?; } diff --git a/storage/aptosdb/src/ledger_db/transaction_db.rs b/storage/aptosdb/src/ledger_db/transaction_db.rs index beaefa935740d..5d4be02484645 100644 --- a/storage/aptosdb/src/ledger_db/transaction_db.rs +++ b/storage/aptosdb/src/ledger_db/transaction_db.rs @@ -12,7 +12,11 @@ use crate::{ }; use aptos_crypto::hash::{CryptoHash, HashValue}; use aptos_db_indexer_schemas::schema::transaction_by_account::TransactionByAccountSchema; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_metrics_core::TimerHelper; +use aptos_schemadb::{ + batch::{NativeBatch, SchemaBatch, WriteBatch}, + DB, +}; use aptos_storage_interface::{AptosDbError, Result}; use aptos_types::transaction::{Transaction, Version}; use rayon::prelude::*; @@ -83,15 +87,13 @@ impl TransactionDb { transactions: &[Transaction], skip_index: bool, ) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_transactions"]) - .start_timer(); - let chunk_size = 512; + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transactions"]); + let chunk_size = transactions.len() / 4 + 1; let batches = transactions .par_chunks(chunk_size) .enumerate() - .map(|(chunk_index, txns_in_chunk)| -> Result { - let batch = SchemaBatch::new(); + .map(|(chunk_index, txns_in_chunk)| -> Result { + let mut batch = self.db().new_native_batch(); let chunk_first_version = first_version + (chunk_size * chunk_index) as u64; txns_in_chunk .iter() @@ -101,7 +103,7 @@ impl TransactionDb { chunk_first_version + i as u64, txn, skip_index, - &batch, + &mut batch, )?; Ok(()) @@ -114,13 +116,11 @@ impl TransactionDb { // it might be acceptable because we are writing the progress, we want to play on the safer // side unless this really becomes the bottleneck on production. { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_transactions___commit"]) - .start_timer(); - - batches - .into_iter() - .try_for_each(|batch| self.write_schemas(batch)) + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_transactions___commit"]); + for batch in batches { + self.db().write_schemas(batch)? + } + Ok(()) } } @@ -131,7 +131,7 @@ impl TransactionDb { version: Version, transaction: &Transaction, skip_index: bool, - batch: &SchemaBatch, + batch: &mut impl WriteBatch, ) -> Result<()> { if !skip_index { if let Some(txn) = transaction.try_as_signed_user_txn() { @@ -152,7 +152,7 @@ impl TransactionDb { &self, begin: Version, end: Version, - db_batch: &SchemaBatch, + db_batch: &mut SchemaBatch, ) -> Result<()> { for version in begin..end { db_batch.delete::(&version)?; @@ -164,7 +164,7 @@ impl TransactionDb { pub(crate) fn prune_transaction_by_hash_indices( &self, transactions: &[Transaction], - db_batch: &SchemaBatch, + db_batch: &mut SchemaBatch, ) -> Result<()> { for transaction in transactions { db_batch.delete::(&transaction.hash())?; diff --git a/storage/aptosdb/src/ledger_db/transaction_db_test.rs b/storage/aptosdb/src/ledger_db/transaction_db_test.rs index 8370856b2bace..4afce0d951aa0 100644 --- a/storage/aptosdb/src/ledger_db/transaction_db_test.rs +++ b/storage/aptosdb/src/ledger_db/transaction_db_test.rs @@ -4,7 +4,7 @@ use crate::{ledger_db::transaction_db::TransactionDb, AptosDB}; use aptos_crypto::hash::CryptoHash; use aptos_proptest_helpers::Index; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::Result; use aptos_temppath::TempPath; use aptos_types::{ @@ -112,8 +112,8 @@ proptest! { { prop_assert!(transaction_db.get_transaction(0).is_ok()); - let batch = SchemaBatch::new(); - transaction_db.prune_transactions(0, 1, &batch).unwrap(); + let mut batch = SchemaBatch::new(); + transaction_db.prune_transactions(0, 1, &mut batch).unwrap(); transaction_db.write_schemas(batch).unwrap(); prop_assert!(transaction_db.get_transaction(0).is_err()); } @@ -121,8 +121,8 @@ proptest! { { prop_assert!(transaction_db.get_transaction(1).is_ok()); prop_assert_eq!(transaction_db.get_transaction_version_by_hash(&txns[1].hash(), num_txns as Version).unwrap(), Some(1)); - let batch = SchemaBatch::new(); - transaction_db.prune_transaction_by_hash_indices(&[txns[1].clone()], &batch).unwrap(); + let mut batch = SchemaBatch::new(); + transaction_db.prune_transaction_by_hash_indices(&[txns[1].clone()], &mut batch).unwrap(); transaction_db.write_schemas(batch).unwrap(); prop_assert!(transaction_db.get_transaction(1).is_ok()); prop_assert_eq!(transaction_db.get_transaction_version_by_hash(&txns[1].hash(), num_txns as Version).unwrap(), None); diff --git a/storage/aptosdb/src/ledger_db/transaction_info_db.rs b/storage/aptosdb/src/ledger_db/transaction_info_db.rs index 45d826f16cd1c..a865bd8d81e9d 100644 --- a/storage/aptosdb/src/ledger_db/transaction_info_db.rs +++ b/storage/aptosdb/src/ledger_db/transaction_info_db.rs @@ -9,7 +9,7 @@ use crate::{ }, utils::iterators::ExpectContinuousVersions, }; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::{AptosDbError, Result}; use aptos_types::{ proof::TransactionInfoWithProof, @@ -86,13 +86,13 @@ impl TransactionInfoDb { pub(crate) fn put_transaction_info( version: Version, transaction_info: &TransactionInfo, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> { batch.put::(&version, transaction_info) } /// Deletes the transaction info between a range of version in [begin, end) - pub(crate) fn prune(begin: Version, end: Version, batch: &SchemaBatch) -> Result<()> { + pub(crate) fn prune(begin: Version, end: Version, batch: &mut SchemaBatch) -> Result<()> { for version in begin..end { batch.delete::(&version)?; } diff --git a/storage/aptosdb/src/ledger_db/write_set_db.rs b/storage/aptosdb/src/ledger_db/write_set_db.rs index a37b099d2bac7..d31152303bb71 100644 --- a/storage/aptosdb/src/ledger_db/write_set_db.rs +++ b/storage/aptosdb/src/ledger_db/write_set_db.rs @@ -9,10 +9,16 @@ use crate::{ }, utils::iterators::ExpectContinuousVersions, }; -use aptos_experimental_runtimes::thread_manager::optimal_min_len; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_metrics_core::TimerHelper; +use aptos_schemadb::{ + batch::{SchemaBatch, WriteBatch}, + DB, +}; use aptos_storage_interface::{db_ensure as ensure, AptosDbError, Result}; -use aptos_types::{transaction::Version, write_set::WriteSet}; +use aptos_types::{ + transaction::{TransactionOutput, Version}, + write_set::WriteSet, +}; use rayon::prelude::*; use std::{path::Path, sync::Arc}; @@ -104,42 +110,52 @@ impl WriteSetDb { } /// Commits write sets starting from `first_version` to the database. - pub(crate) fn commit_write_sets<'a>( + pub(crate) fn commit_write_sets( &self, first_version: Version, - write_sets: impl IndexedParallelIterator, + transaction_outputs: &[TransactionOutput], ) -> Result<()> { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_write_sets"]) - .start_timer(); - let batch = SchemaBatch::new(); - let num_txns = write_sets.len(); - - write_sets - .with_min_len(optimal_min_len(num_txns, 128)) - .enumerate() - .try_for_each(|(i, write_set)| -> Result<()> { - Self::put_write_set(first_version + i as Version, write_set, &batch)?; + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_write_sets"]); - Ok(()) - })?; - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_write_sets___commit"]) - .start_timer(); - self.write_schemas(batch) + let chunk_size = transaction_outputs.len() / 4 + 1; + let batches = transaction_outputs + .par_chunks(chunk_size) + .enumerate() + .map(|(chunk_idx, chunk)| { + let mut batch = self.db().new_native_batch(); + let chunk_first_version = first_version + (chunk_idx * chunk_size) as Version; + + chunk.iter().enumerate().try_for_each(|(i, txn_out)| { + Self::put_write_set( + chunk_first_version + i as Version, + txn_out.write_set(), + &mut batch, + ) + })?; + Ok(batch) + }) + .collect::>>()?; + + { + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["commit_write_sets___commit"]); + for batch in batches { + self.db().write_schemas(batch)? + } + Ok(()) + } } /// Saves executed transaction vm output given the `version`. pub(crate) fn put_write_set( version: Version, write_set: &WriteSet, - batch: &SchemaBatch, + batch: &mut impl WriteBatch, ) -> Result<()> { batch.put::(&version, write_set) } /// Deletes the write sets between a range of version in [begin, end). - pub(crate) fn prune(begin: Version, end: Version, db_batch: &SchemaBatch) -> Result<()> { + pub(crate) fn prune(begin: Version, end: Version, db_batch: &mut SchemaBatch) -> Result<()> { for version in begin..end { db_batch.delete::(&version)?; } diff --git a/storage/aptosdb/src/ledger_db/write_set_db_test.rs b/storage/aptosdb/src/ledger_db/write_set_db_test.rs index e0140b246f847..176e29d59a3d3 100644 --- a/storage/aptosdb/src/ledger_db/write_set_db_test.rs +++ b/storage/aptosdb/src/ledger_db/write_set_db_test.rs @@ -2,12 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ledger_db::WriteSetDb, AptosDB}; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::Result; use aptos_temppath::TempPath; -use aptos_types::{transaction::Version, write_set::WriteSet}; +use aptos_types::{ + transaction::{ExecutionStatus, TransactionAuxiliaryData, TransactionOutput, Version}, + write_set::WriteSet, +}; use proptest::{collection::vec, prelude::*}; -use rayon::prelude::*; proptest! { #![proptest_config(ProptestConfig::with_cases(10))] @@ -99,8 +101,8 @@ proptest! { { prop_assert!(write_set_db.get_write_set(0).is_ok()); - let batch = SchemaBatch::new(); - WriteSetDb::prune(0, 1, &batch).unwrap(); + let mut batch = SchemaBatch::new(); + WriteSetDb::prune(0, 1, &mut batch).unwrap(); write_set_db.write_schemas(batch).unwrap(); prop_assert!(write_set_db.get_write_set(0).is_err()); } @@ -110,7 +112,18 @@ proptest! { fn init_db(write_sets: &[WriteSet], write_set_db: &WriteSetDb) { assert!(write_set_db.get_write_set(0).is_err()); - write_set_db - .commit_write_sets(0, write_sets.par_iter()) - .unwrap(); + let dummy_txn_outs = write_sets + .iter() + .map(|write_set| { + TransactionOutput::new( + write_set.clone(), + vec![], + 0, + ExecutionStatus::Success.into(), + TransactionAuxiliaryData::default(), + ) + }) + .collect::>(); + + write_set_db.commit_write_sets(0, &dummy_txn_outs).unwrap(); } diff --git a/storage/aptosdb/src/pruner/ledger_pruner/event_store_pruner.rs b/storage/aptosdb/src/pruner/ledger_pruner/event_store_pruner.rs index 952bb2086e457..a1e89deae99c0 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/event_store_pruner.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/event_store_pruner.rs @@ -12,7 +12,7 @@ use aptos_db_indexer_schemas::{ schema::indexer_metadata::InternalIndexerMetadataSchema, }; use aptos_logger::info; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::Result; use aptos_types::transaction::Version; use std::sync::Arc; @@ -41,29 +41,34 @@ impl DBSubPruner for EventStorePruner { } fn prune(&self, current_progress: Version, target_version: Version) -> Result<()> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let mut indexer_batch = None; let indices_batch = if let Some(indexer_db) = self.indexer_db() { if indexer_db.event_enabled() { indexer_batch = Some(SchemaBatch::new()); } - indexer_batch.as_ref() + indexer_batch.as_mut() } else { - Some(&batch) + Some(&mut batch) }; - self.ledger_db.event_db().prune_events( + let num_events_per_version = self.ledger_db.event_db().prune_event_indices( current_progress, target_version, - &batch, indices_batch, )?; + self.ledger_db.event_db().prune_events( + num_events_per_version, + current_progress, + target_version, + &mut batch, + )?; batch.put::( &DbMetadataKey::EventPrunerProgress, &DbMetadataValue::Version(target_version), )?; - if let Some(indexer_batch) = indexer_batch { + if let Some(mut indexer_batch) = indexer_batch { indexer_batch.put::( &IndexerMetadataKey::EventPrunerProgress, &IndexerMetadataValue::Version(target_version), diff --git a/storage/aptosdb/src/pruner/ledger_pruner/event_store_pruner_test.rs b/storage/aptosdb/src/pruner/ledger_pruner/event_store_pruner_test.rs index 1d9ef50b21071..adaa221123f4e 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/event_store_pruner_test.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/event_store_pruner_test.rs @@ -56,7 +56,7 @@ fn verify_event_store_pruner(events: Vec>) { let tmp_dir = TempPath::new(); let aptos_db = AptosDB::new_for_test(&tmp_dir); let event_store = &aptos_db.event_store; - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let num_versions = events.len(); // Write events to DB @@ -66,7 +66,7 @@ fn verify_event_store_pruner(events: Vec>) { version as u64, events_for_version, /*skip_index=*/ false, - &batch, + &mut batch, ) .unwrap(); } @@ -102,7 +102,7 @@ fn verify_event_store_pruner_disabled(events: Vec>) { let tmp_dir = TempPath::new(); let aptos_db = AptosDB::new_for_test(&tmp_dir); let event_store = &aptos_db.event_store; - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let num_versions = events.len(); // Write events to DB @@ -112,7 +112,7 @@ fn verify_event_store_pruner_disabled(events: Vec>) { version as u64, events_for_version, /*skip_index=*/ false, - &batch, + &mut batch, ) .unwrap(); } diff --git a/storage/aptosdb/src/pruner/ledger_pruner/ledger_metadata_pruner.rs b/storage/aptosdb/src/pruner/ledger_pruner/ledger_metadata_pruner.rs index e4e94d41a0e20..d69a6abacba26 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/ledger_metadata_pruner.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/ledger_metadata_pruner.rs @@ -5,7 +5,7 @@ use crate::schema::{ db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, version_data::VersionDataSchema, }; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::{AptosDbError, Result}; use aptos_types::transaction::Version; use std::sync::Arc; @@ -44,7 +44,7 @@ impl LedgerMetadataPruner { current_progress: Version, target_version: Version, ) -> Result<()> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); for version in current_progress..target_version { batch.delete::(&version)?; } diff --git a/storage/aptosdb/src/pruner/ledger_pruner/test.rs b/storage/aptosdb/src/pruner/ledger_pruner/test.rs index 70ef9a9c5366d..5298abd17e160 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/test.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/test.rs @@ -57,10 +57,10 @@ fn verify_write_set_pruner(write_sets: Vec) { }); // write sets - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); for (ver, ws) in write_sets.iter().enumerate() { transaction_store - .put_write_set(ver as Version, ws, &batch) + .put_write_set(ver as Version, ws, &mut batch) .unwrap(); } aptos_db @@ -105,7 +105,7 @@ fn verify_txn_store_pruner( &txns, ); - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); for i in 0..=num_transaction as u64 { let usage = StateStorageUsage::zero(); batch.put::(&i, &usage.into()).unwrap(); @@ -233,7 +233,7 @@ fn put_txn_in_store( txn_infos: &[TransactionInfo], txns: &[Transaction], ) { - let transaction_batch = SchemaBatch::new(); + let mut transaction_batch = SchemaBatch::new(); for i in 0..txns.len() { transaction_store .put_transaction( @@ -249,8 +249,8 @@ fn put_txn_in_store( .transaction_db() .write_schemas(transaction_batch) .unwrap(); - let transaction_info_batch = SchemaBatch::new(); - let transaction_accumulator_batch = SchemaBatch::new(); + let mut transaction_info_batch = SchemaBatch::new(); + let mut transaction_accumulator_batch = SchemaBatch::new(); ledger_store .put_transaction_infos( 0, diff --git a/storage/aptosdb/src/pruner/ledger_pruner/transaction_accumulator_pruner.rs b/storage/aptosdb/src/pruner/ledger_pruner/transaction_accumulator_pruner.rs index 1f435418e0110..ae57a5bb18d14 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/transaction_accumulator_pruner.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/transaction_accumulator_pruner.rs @@ -7,7 +7,7 @@ use crate::{ schema::db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, }; use aptos_logger::info; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::Result; use aptos_types::transaction::Version; use std::sync::Arc; @@ -23,8 +23,8 @@ impl DBSubPruner for TransactionAccumulatorPruner { } fn prune(&self, current_progress: Version, target_version: Version) -> Result<()> { - let batch = SchemaBatch::new(); - TransactionAccumulatorDb::prune(current_progress, target_version, &batch)?; + let mut batch = SchemaBatch::new(); + TransactionAccumulatorDb::prune(current_progress, target_version, &mut batch)?; batch.put::( &DbMetadataKey::TransactionAccumulatorPrunerProgress, &DbMetadataValue::Version(target_version), diff --git a/storage/aptosdb/src/pruner/ledger_pruner/transaction_auxiliary_data_pruner.rs b/storage/aptosdb/src/pruner/ledger_pruner/transaction_auxiliary_data_pruner.rs index cd9ace677b583..203bf88eba724 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/transaction_auxiliary_data_pruner.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/transaction_auxiliary_data_pruner.rs @@ -7,7 +7,7 @@ use crate::{ schema::db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, }; use aptos_logger::info; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::Result; use aptos_types::transaction::Version; use std::sync::Arc; @@ -23,8 +23,8 @@ impl DBSubPruner for TransactionAuxiliaryDataPruner { } fn prune(&self, current_progress: Version, target_version: Version) -> Result<()> { - let batch = SchemaBatch::new(); - TransactionAuxiliaryDataDb::prune(current_progress, target_version, &batch)?; + let mut batch = SchemaBatch::new(); + TransactionAuxiliaryDataDb::prune(current_progress, target_version, &mut batch)?; batch.put::( &DbMetadataKey::TransactionAuxiliaryDataPrunerProgress, &DbMetadataValue::Version(target_version), diff --git a/storage/aptosdb/src/pruner/ledger_pruner/transaction_info_pruner.rs b/storage/aptosdb/src/pruner/ledger_pruner/transaction_info_pruner.rs index 69d1c50673178..ef7ef94080d3e 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/transaction_info_pruner.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/transaction_info_pruner.rs @@ -7,7 +7,7 @@ use crate::{ schema::db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, }; use aptos_logger::info; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::Result; use aptos_types::transaction::Version; use std::sync::Arc; @@ -23,8 +23,8 @@ impl DBSubPruner for TransactionInfoPruner { } fn prune(&self, current_progress: Version, target_version: Version) -> Result<()> { - let batch = SchemaBatch::new(); - TransactionInfoDb::prune(current_progress, target_version, &batch)?; + let mut batch = SchemaBatch::new(); + TransactionInfoDb::prune(current_progress, target_version, &mut batch)?; batch.put::( &DbMetadataKey::TransactionInfoPrunerProgress, &DbMetadataValue::Version(target_version), diff --git a/storage/aptosdb/src/pruner/ledger_pruner/transaction_pruner.rs b/storage/aptosdb/src/pruner/ledger_pruner/transaction_pruner.rs index bccabdb0f891a..8fb665e53c377 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/transaction_pruner.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/transaction_pruner.rs @@ -16,7 +16,7 @@ use aptos_db_indexer_schemas::{ schema::indexer_metadata::InternalIndexerMetadataSchema, }; use aptos_logger::info; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::{db_ensure as ensure, AptosDbError, Result}; use aptos_types::transaction::{Transaction, Version}; use std::sync::Arc; @@ -34,16 +34,16 @@ impl DBSubPruner for TransactionPruner { } fn prune(&self, current_progress: Version, target_version: Version) -> Result<()> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let candidate_transactions = self.get_pruning_candidate_transactions(current_progress, target_version)?; self.ledger_db .transaction_db() - .prune_transaction_by_hash_indices(&candidate_transactions, &batch)?; + .prune_transaction_by_hash_indices(&candidate_transactions, &mut batch)?; self.ledger_db.transaction_db().prune_transactions( current_progress, target_version, - &batch, + &mut batch, )?; batch.put::( &DbMetadataKey::TransactionPrunerProgress, @@ -51,9 +51,9 @@ impl DBSubPruner for TransactionPruner { )?; if let Some(indexer_db) = self.internal_indexer_db.as_ref() { if indexer_db.transaction_enabled() { - let index_batch = SchemaBatch::new(); + let mut index_batch = SchemaBatch::new(); self.transaction_store - .prune_transaction_by_account(&candidate_transactions, &index_batch)?; + .prune_transaction_by_account(&candidate_transactions, &mut index_batch)?; index_batch.put::( &IndexerMetadataKey::TransactionPrunerProgress, &IndexerMetadataValue::Version(target_version), @@ -61,7 +61,7 @@ impl DBSubPruner for TransactionPruner { indexer_db.get_inner_db_ref().write_schemas(index_batch)?; } else { self.transaction_store - .prune_transaction_by_account(&candidate_transactions, &batch)?; + .prune_transaction_by_account(&candidate_transactions, &mut batch)?; } } self.ledger_db.transaction_db().write_schemas(batch) diff --git a/storage/aptosdb/src/pruner/ledger_pruner/write_set_pruner.rs b/storage/aptosdb/src/pruner/ledger_pruner/write_set_pruner.rs index 6489ccad51405..07ba5dd8022cc 100644 --- a/storage/aptosdb/src/pruner/ledger_pruner/write_set_pruner.rs +++ b/storage/aptosdb/src/pruner/ledger_pruner/write_set_pruner.rs @@ -7,7 +7,7 @@ use crate::{ schema::db_metadata::{DbMetadataKey, DbMetadataSchema, DbMetadataValue}, }; use aptos_logger::info; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::Result; use aptos_types::transaction::Version; use std::sync::Arc; @@ -23,8 +23,8 @@ impl DBSubPruner for WriteSetPruner { } fn prune(&self, current_progress: Version, target_version: Version) -> Result<()> { - let batch = SchemaBatch::new(); - WriteSetDb::prune(current_progress, target_version, &batch)?; + let mut batch = SchemaBatch::new(); + WriteSetDb::prune(current_progress, target_version, &mut batch)?; batch.put::( &DbMetadataKey::WriteSetPrunerProgress, &DbMetadataValue::Version(target_version), diff --git a/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_metadata_pruner.rs b/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_metadata_pruner.rs index a4a79d4b0c78c..c928873d892f1 100644 --- a/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_metadata_pruner.rs +++ b/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_metadata_pruner.rs @@ -11,7 +11,7 @@ use crate::{ state_kv_db::StateKvDb, utils::get_progress, }; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::Result; use aptos_types::transaction::Version; use std::sync::Arc; @@ -30,7 +30,7 @@ impl StateKvMetadataPruner { current_progress: Version, target_version: Version, ) -> Result<()> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); if self.state_kv_db.enabled_sharding() { let num_shards = self.state_kv_db.num_shards(); diff --git a/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_shard_pruner.rs b/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_shard_pruner.rs index 7824d5bc78c18..cf11242544ac9 100644 --- a/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_shard_pruner.rs +++ b/storage/aptosdb/src/pruner/state_kv_pruner/state_kv_shard_pruner.rs @@ -10,7 +10,7 @@ use crate::{ }, }; use aptos_logger::info; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::Result; use aptos_types::transaction::Version; use std::sync::Arc; @@ -49,7 +49,7 @@ impl StateKvShardPruner { current_progress: Version, target_version: Version, ) -> Result<()> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let mut iter = self .db_shard diff --git a/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_metadata_pruner.rs b/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_metadata_pruner.rs index c519b15cdf258..da9cff2acd741 100644 --- a/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_metadata_pruner.rs +++ b/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_metadata_pruner.rs @@ -11,7 +11,7 @@ use crate::{ }; use anyhow::Result; use aptos_jellyfish_merkle::StaleNodeIndex; -use aptos_schemadb::{schema::KeyCodec, SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, schema::KeyCodec, DB}; use aptos_types::transaction::{AtomicVersion, Version}; use std::{ cmp::max, @@ -56,7 +56,7 @@ where target_version_for_this_round, )?; - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); indices.into_iter().try_for_each(|index| { batch.delete::(&index.node_key)?; batch.delete::(&index) diff --git a/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_shard_pruner.rs b/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_shard_pruner.rs index 02c67859f5397..18f9ade09511b 100644 --- a/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_shard_pruner.rs +++ b/storage/aptosdb/src/pruner/state_merkle_pruner/state_merkle_shard_pruner.rs @@ -14,7 +14,7 @@ use crate::{ use anyhow::Result; use aptos_jellyfish_merkle::StaleNodeIndex; use aptos_logger::info; -use aptos_schemadb::{schema::KeyCodec, SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, schema::KeyCodec, DB}; use aptos_types::transaction::Version; use std::{marker::PhantomData, sync::Arc}; @@ -61,7 +61,7 @@ where target_version: Version, ) -> Result<()> { loop { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let (indices, next_version) = StateMerklePruner::get_stale_node_indices( &self.db_shard, current_progress, diff --git a/storage/aptosdb/src/pruner/state_merkle_pruner/test.rs b/storage/aptosdb/src/pruner/state_merkle_pruner/test.rs index ed5e8ffd2e598..491aab1e96763 100644 --- a/storage/aptosdb/src/pruner/state_merkle_pruner/test.rs +++ b/storage/aptosdb/src/pruner/state_merkle_pruner/test.rs @@ -3,7 +3,7 @@ use crate::{ db::{ - test_helper::{arb_state_kv_sets, update_store}, + test_helper::{arb_state_kv_sets_with_genesis, update_store}, AptosDB, }, pruner::{PrunerManager, StateKvPrunerManager, StateMerklePrunerManager}, @@ -14,26 +14,18 @@ use crate::{ }, state_merkle_db::StateMerkleDb, state_store::StateStore, - utils::new_sharded_kv_schema_batch, }; use aptos_config::config::{LedgerPrunerConfig, StateMerklePrunerConfig}; use aptos_crypto::{hash::CryptoHash, HashValue}; -use aptos_schemadb::SchemaBatch; -use aptos_storage_interface::{ - jmt_update_refs, jmt_updates, - state_store::{sharded_state_update_refs::ShardedStateUpdateRefs, NUM_STATE_SHARDS}, - DbReader, -}; +use aptos_storage_interface::{state_store::NUM_STATE_SHARDS, DbReader}; use aptos_temppath::TempPath; use aptos_types::{ state_store::{ state_key::StateKey, - state_storage_usage::StateStorageUsage, state_value::{StaleStateValueByKeyHashIndex, StaleStateValueIndex, StateValue}, }, transaction::Version, }; -use arr_macro::arr; use proptest::{prelude::*, proptest}; use std::{collections::HashMap, sync::Arc}; @@ -42,51 +34,7 @@ fn put_value_set( value_set: Vec<(StateKey, StateValue)>, version: Version, ) -> HashValue { - let mut sharded_value_set = arr![HashMap::new(); 16]; - let value_set: HashMap<_, _> = value_set - .iter() - .map(|(key, value)| { - sharded_value_set[key.get_shard_id() as usize].insert(key.clone(), Some(value.clone())); - (key, Some(value)) - }) - .collect(); - let jmt_updates = jmt_updates(&value_set); - - let root = state_store - .merklize_value_set( - jmt_update_refs(&jmt_updates), - version, - version.checked_sub(1), - ) - .unwrap(); - - let ledger_batch = SchemaBatch::new(); - let sharded_state_kv_batches = new_sharded_kv_schema_batch(); - let state_kv_metadata_batch = SchemaBatch::new(); - let enable_sharding = state_store.state_kv_db.enabled_sharding(); - state_store - .put_value_sets( - version, - &ShardedStateUpdateRefs::index_per_version_updates([value_set], 1), - StateStorageUsage::new_untracked(), - None, - &ledger_batch, - &sharded_state_kv_batches, - enable_sharding, - /*last_checkpoint_index=*/ None, - ) - .unwrap(); - state_store - .ledger_db - .metadata_db() - .write_schemas(ledger_batch) - .unwrap(); - state_store - .state_kv_db - .commit(version, state_kv_metadata_batch, sharded_state_kv_batches) - .unwrap(); - - root + state_store.commit_block_for_test(version, [value_set.into_iter().map(|(k, v)| (k, Some(v)))]) } fn verify_state_in_store( @@ -357,7 +305,7 @@ proptest! { #[test] fn test_state_value_pruner( - input in arb_state_kv_sets(10, 5, 5), + input in arb_state_kv_sets_with_genesis(5, 3, 5), ) { verify_state_value_pruner(input); } @@ -377,7 +325,7 @@ fn verify_state_value_pruner(inputs: Vec)>>) { user_pruning_window_offset: 0, }); for batch in inputs { - update_store(store, batch.clone().into_iter(), version, false); + update_store(store, batch.clone().into_iter(), version); for (k, v) in batch.iter() { if let Some((old_version, old_v_opt)) = current_state_values.insert(k.clone(), (version, v.clone())) diff --git a/storage/aptosdb/src/state_kv_db.rs b/storage/aptosdb/src/state_kv_db.rs index 331b170084b5d..ac3e2893668cd 100644 --- a/storage/aptosdb/src/state_kv_db.rs +++ b/storage/aptosdb/src/state_kv_db.rs @@ -11,20 +11,28 @@ use crate::{ state_value::StateValueSchema, state_value_by_key_hash::StateValueByKeyHashSchema, }, - utils::truncation_helper::{get_state_kv_commit_progress, truncate_state_kv_db_shards}, + utils::{ + truncation_helper::{get_state_kv_commit_progress, truncate_state_kv_db_shards}, + ShardedStateKvSchemaBatch, + }, }; use aptos_config::config::{RocksdbConfig, RocksdbConfigs, StorageDirPaths}; use aptos_crypto::hash::CryptoHash; use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_logger::prelude::info; +use aptos_metrics_core::TimerHelper; use aptos_rocksdb_options::gen_rocksdb_options; -use aptos_schemadb::{ReadOptions, SchemaBatch, DB}; +use aptos_schemadb::{ + batch::{SchemaBatch, WriteBatch}, + ReadOptions, DB, +}; use aptos_storage_interface::{state_store::NUM_STATE_SHARDS, Result}; use aptos_types::{ state_store::{state_key::StateKey, state_value::StateValue}, transaction::Version, }; use arr_macro::arr; +use itertools::Itertools; use rayon::prelude::*; use std::{ path::{Path, PathBuf}, @@ -112,11 +120,19 @@ impl StateKvDb { Ok(state_kv_db) } + pub(crate) fn new_sharded_native_batches(&self) -> ShardedStateKvSchemaBatch { + (0..NUM_STATE_SHARDS) + .map(|shard_id| self.db_shard(shard_id as u8).new_native_batch()) + .collect_vec() + .try_into() + .expect("known to be 16 shards") + } + pub(crate) fn commit( &self, version: Version, - state_kv_metadata_batch: SchemaBatch, - sharded_state_kv_batches: [SchemaBatch; NUM_STATE_SHARDS], + state_kv_metadata_batch: Option, + sharded_state_kv_batches: ShardedStateKvSchemaBatch, ) -> Result<()> { let _timer = OTHER_TIMERS_SECONDS .with_label_values(&["state_kv_db__commit"]) @@ -141,13 +157,9 @@ impl StateKvDb { } }); } - - { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["state_kv_db__commit_metadata"]) - .start_timer(); - self.state_kv_metadata_db - .write_schemas(state_kv_metadata_batch)?; + if let Some(batch) = state_kv_metadata_batch { + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["state_kv_db__commit_metadata"]); + self.state_kv_metadata_db.write_schemas(batch)?; } self.write_progress(version) @@ -233,7 +245,7 @@ impl StateKvDb { &self, version: Version, shard_id: u8, - batch: SchemaBatch, + mut batch: impl WriteBatch, ) -> Result<()> { batch.put::( &DbMetadataKey::StateKvShardCommitProgress(shard_id as usize), diff --git a/storage/aptosdb/src/state_merkle_db.rs b/storage/aptosdb/src/state_merkle_db.rs index 10d75f5b164f5..c4b904d6e2b52 100644 --- a/storage/aptosdb/src/state_merkle_db.rs +++ b/storage/aptosdb/src/state_merkle_db.rs @@ -15,14 +15,18 @@ use crate::{ versioned_node_cache::VersionedNodeCache, }; use aptos_config::config::{RocksdbConfig, RocksdbConfigs, StorageDirPaths}; -use aptos_crypto::{hash::CryptoHash, HashValue}; -use aptos_experimental_runtimes::thread_manager::{optimal_min_len, THREAD_MANAGER}; +use aptos_crypto::HashValue; +use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_jellyfish_merkle::{ node_type::NodeKey, JellyfishMerkleTree, TreeReader, TreeUpdateBatch, TreeWriter, }; use aptos_logger::prelude::*; +use aptos_metrics_core::TimerHelper; use aptos_rocksdb_options::gen_rocksdb_options; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{ + batch::{IntoRawBatch, RawBatch, SchemaBatch, WriteBatch}, + DB, +}; #[cfg(test)] use aptos_scratchpad::get_state_shard_id; use aptos_storage_interface::{ @@ -114,24 +118,24 @@ impl StateMerkleDb { pub(crate) fn commit( &self, version: Version, - top_levels_batch: SchemaBatch, - batches_for_shards: Vec, + top_levels_batch: impl IntoRawBatch, + batches_for_shards: Vec, ) -> Result<()> { ensure!( batches_for_shards.len() == NUM_STATE_SHARDS, "Shard count mismatch." ); - THREAD_MANAGER.get_io_pool().scope(|s| { - let mut batches = batches_for_shards.into_iter(); - for shard_id in 0..NUM_STATE_SHARDS { - let state_merkle_batch = batches.next().unwrap(); - s.spawn(move |_| { - self.commit_single_shard(version, shard_id as u8, state_merkle_batch) + THREAD_MANAGER.get_io_pool().install(|| { + batches_for_shards + .into_par_iter() + .enumerate() + .for_each(|(shard_id, batch)| { + self.db_shard(shard_id as u8) + .write_schemas(batch) .unwrap_or_else(|err| { panic!("Failed to commit state merkle shard {shard_id}: {err}") }); - }); - } + }) }); self.commit_top_levels(version, top_levels_batch) @@ -215,32 +219,26 @@ impl StateMerkleDb { Arc::clone(&self.state_merkle_db_shards[shard_id as usize]) } - pub(crate) fn commit_top_levels(&self, version: Version, batch: SchemaBatch) -> Result<()> { - batch.put::( - &DbMetadataKey::StateMerkleCommitProgress, - &DbMetadataValue::Version(version), - )?; - - info!(version = version, "Committing StateMerkleDb."); - self.state_merkle_metadata_db.write_schemas(batch) + pub(crate) fn db(&self, shard_id: Option) -> &DB { + if let Some(shard_id) = shard_id { + self.db_shard(shard_id) + } else { + self.metadata_db() + } } - pub(crate) fn commit_single_shard( + pub(crate) fn commit_top_levels( &self, version: Version, - shard_id: u8, - batch: SchemaBatch, + batch: impl IntoRawBatch, ) -> Result<()> { - batch.put::( - &DbMetadataKey::StateMerkleShardCommitProgress(shard_id as usize), - &DbMetadataValue::Version(version), - )?; - self.state_merkle_db_shards[shard_id as usize].write_schemas(batch) + info!(version = version, "Committing StateMerkleDb."); + self.state_merkle_metadata_db.write_schemas(batch) } pub fn get_with_proof_ext( &self, - state_key: &StateKey, + key: &HashValue, version: Version, root_depth: usize, ) -> Result<( @@ -248,7 +246,7 @@ impl StateMerkleDb { SparseMerkleProofExt, )> { JellyfishMerkleTree::new(self) - .get_with_proof_ext(state_key.hash(), version, root_depth) + .get_with_proof_ext(key, version, root_depth) .map_err(Into::into) } @@ -322,52 +320,63 @@ impl StateMerkleDb { fn create_jmt_commit_batch_for_shard( &self, + version: Version, shard_id: Option, tree_update_batch: &TreeUpdateBatch, previous_epoch_ending_version: Option, - ) -> Result { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["create_jmt_commit_batch_for_shard"]) - .start_timer(); + ) -> Result { + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["create_jmt_commit_batch_for_shard"]); - let batch = SchemaBatch::new(); + let mut batch = self.db(shard_id).new_native_batch(); let node_batch = tree_update_batch .node_batch .iter() .flatten() .collect::>(); - let num_nodes = node_batch.len(); - node_batch - .par_iter() - .with_min_len(optimal_min_len(num_nodes, 128)) - .try_for_each(|(node_key, node)| { - ensure!(node_key.get_shard_id() == shard_id, "shard_id mismatch"); - batch.put::(node_key, node) - })?; + node_batch.iter().try_for_each(|(node_key, node)| { + ensure!(node_key.get_shard_id() == shard_id, "shard_id mismatch"); + batch.put::(node_key, node) + })?; let stale_node_index_batch = tree_update_batch .stale_node_index_batch .iter() .flatten() .collect::>(); - let num_stale_nodes = stale_node_index_batch.len(); - stale_node_index_batch - .par_iter() - .with_min_len(optimal_min_len(num_stale_nodes, 128)) - .try_for_each(|row| { - ensure!(row.node_key.get_shard_id() == shard_id, "shard_id mismatch"); - if previous_epoch_ending_version.is_some() - && row.node_key.version() <= previous_epoch_ending_version.unwrap() - { - batch.put::(row, &()) - } else { - // These are processed by the state merkle pruner. - batch.put::(row, &()) - } - })?; + stale_node_index_batch.iter().try_for_each(|row| { + ensure!(row.node_key.get_shard_id() == shard_id, "shard_id mismatch"); + if previous_epoch_ending_version.is_some() + && row.node_key.version() <= previous_epoch_ending_version.unwrap() + { + batch.put::(row, &()) + } else { + // These are processed by the state merkle pruner. + batch.put::(row, &()) + } + })?; + + Self::put_progress(Some(version), shard_id, &mut batch)?; - Ok(batch) + batch.into_raw_batch(self.db(shard_id)) + } + + pub(crate) fn put_progress( + version: Option, + shard_id: Option, + batch: &mut impl WriteBatch, + ) -> Result<()> { + let key = if let Some(shard_id) = shard_id { + DbMetadataKey::StateMerkleShardCommitProgress(shard_id as usize) + } else { + DbMetadataKey::StateMerkleCommitProgress + }; + + if let Some(version) = version { + batch.put::(&key, &DbMetadataValue::Version(version)) + } else { + batch.delete::(&key) + } } // A non-sharded helper function accepting KV updates from all shards. @@ -378,7 +387,7 @@ impl StateMerkleDb { version: Version, base_version: Option, previous_epoch_ending_version: Option, - ) -> Result<(SchemaBatch, Vec, HashValue)> { + ) -> Result<(RawBatch, Vec, HashValue)> { let mut sharded_value_set: Vec)>> = Vec::new(); sharded_value_set.resize(NUM_STATE_SHARDS, Default::default()); @@ -425,7 +434,7 @@ impl StateMerkleDb { base_version: Option, shard_persisted_version: Option, previous_epoch_ending_version: Option, - ) -> Result<(Node, SchemaBatch)> { + ) -> Result<(Node, RawBatch)> { if let Some(shard_persisted_version) = shard_persisted_version { assert!(shard_persisted_version <= base_version.expect("Must have base version.")); } @@ -460,6 +469,7 @@ impl StateMerkleDb { } let batch = self.create_jmt_commit_batch_for_shard( + version, Some(shard_id), &tree_update_batch, previous_epoch_ending_version, @@ -477,8 +487,9 @@ impl StateMerkleDb { version: Version, base_version: Option, previous_epoch_ending_version: Option, - ) -> Result<(HashValue, SchemaBatch)> { + ) -> Result<(HashValue, RawBatch)> { assert!(shard_root_nodes.len() == 16); + let (root_hash, tree_update_batch) = JellyfishMerkleTree::new(self).put_top_levels_nodes( shard_root_nodes, base_version, @@ -498,12 +509,13 @@ impl StateMerkleDb { } let batch = self.create_jmt_commit_batch_for_shard( + version, None, &tree_update_batch, previous_epoch_ending_version, )?; - Ok((root_hash, batch)) + Ok((root_hash, batch.into_raw_batch(self.db(None))?)) } pub(crate) fn get_shard_persisted_versions( @@ -843,7 +855,7 @@ impl TreeWriter for StateMerkleDb { .with_label_values(&["tree_writer_write_batch"]) .start_timer(); // Get the top level batch and sharded batch from raw NodeBatch - let top_level_batch = SchemaBatch::new(); + let mut top_level_batch = SchemaBatch::new(); let mut jmt_shard_batches: Vec = Vec::with_capacity(NUM_STATE_SHARDS); jmt_shard_batches.resize_with(NUM_STATE_SHARDS, SchemaBatch::new); node_batch.iter().try_for_each(|(node_key, node)| { diff --git a/storage/aptosdb/src/state_store/buffered_state.rs b/storage/aptosdb/src/state_store/buffered_state.rs index 8a2a53a53bac9..a7580d6fafeb3 100644 --- a/storage/aptosdb/src/state_store/buffered_state.rs +++ b/storage/aptosdb/src/state_store/buffered_state.rs @@ -6,23 +6,21 @@ use crate::{ metrics::{LATEST_CHECKPOINT_VERSION, OTHER_TIMERS_SECONDS}, state_store::{ - persisted_state::PersistedState, state_snapshot_committer::StateSnapshotCommitter, - CurrentState, StateDb, + persisted_state::PersistedState, state_snapshot_committer::StateSnapshotCommitter, StateDb, }, }; use aptos_infallible::Mutex; -use aptos_logger::info; use aptos_metrics_core::TimerHelper; use aptos_storage_interface::{ - db_ensure as ensure, - state_store::{sharded_state_updates::ShardedStateUpdates, state_delta::StateDelta}, - AptosDbError, Result, + state_store::state_with_summary::{LedgerStateWithSummary, StateWithSummary}, + Result, }; +use aptos_types::transaction::Version; use std::{ sync::{ mpsc, mpsc::{Sender, SyncSender}, - Arc, + Arc, MutexGuard, }, thread::JoinHandle, }; @@ -30,21 +28,19 @@ use std::{ pub(crate) const ASYNC_COMMIT_CHANNEL_BUFFER_SIZE: u64 = 1; pub(crate) const TARGET_SNAPSHOT_INTERVAL_IN_VERSION: u64 = 100_000; -/// The in-memory buffered state that consists of two pieces: -/// `state_until_checkpoint`: The ready-to-commit data in range (last snapshot, latest checkpoint]. -/// `state_after_checkpoint`: The pending data from the latest checkpoint(exclusive) until the -/// latest version committed, which has not reached the next checkpoint. -/// Since these are divided by the latest checkpoint, it is guaranteed -/// state_until_checkpoint.current = state_after_checkpoint.base, same for their versions. +/// BufferedState manages a range of recent state checkpoints and asynchronously commits +/// the updates in batches. #[derive(Debug)] pub struct BufferedState { - /// state until the latest checkpoint. The `base` is the newest persisted state. - state_until_checkpoint: Option>, - /// state after the latest checkpoint. The `current` is the latest speculative state. - /// n.b. this is an `Arc` shared with the StateStore so that merely querying the latest state - /// does not require locking the buffered state. - state_after_checkpoint: Arc>, - state_commit_sender: SyncSender>>, + /// the current state and the last checkpoint. shared with outside world. + current_state: Arc>, + /// The most recent checkpoint sent for persistence, not guaranteed to have committed already. + last_snapshot: StateWithSummary, + /// channel to send a checkpoint for persistence asynchronously + state_commit_sender: SyncSender>, + /// Estimated number of items in the buffer. + estimated_items: usize, + /// The target number of items in the buffer between commits. target_items: usize, join_handle: Option>, } @@ -56,20 +52,21 @@ pub(crate) enum CommitMessage { } impl BufferedState { - pub(crate) fn new( + pub(crate) fn new_at_snapshot( state_db: &Arc, - state_after_checkpoint: StateDelta, + last_snapshot: StateWithSummary, target_items: usize, - current_state: Arc>, - persisted_state: Arc>, + out_current_state: Arc>, + out_persisted_state: Arc>, ) -> Self { let (state_commit_sender, state_commit_receiver) = mpsc::sync_channel(ASYNC_COMMIT_CHANNEL_BUFFER_SIZE as usize); let arc_state_db = Arc::clone(state_db); - persisted_state - .lock() - .set(state_after_checkpoint.base.clone()); - let persisted_state_clone = persisted_state.clone(); + *out_current_state.lock() = + LedgerStateWithSummary::new_at_checkpoint(last_snapshot.clone()); + out_persisted_state.lock().set(last_snapshot.clone()); + let persisted_state_clone = out_persisted_state.clone(); + let last_snapshot_clone = last_snapshot.clone(); // Create a new thread with receiver subscribing to state commit changes let join_handle = std::thread::Builder::new() .name("state-committer".to_string()) @@ -77,142 +74,110 @@ impl BufferedState { let committer = StateSnapshotCommitter::new( arc_state_db, state_commit_receiver, + last_snapshot_clone, persisted_state_clone, ); committer.run(); }) .expect("Failed to spawn state committer thread."); - current_state.lock().set(state_after_checkpoint.clone()); - let myself = Self { - state_until_checkpoint: None, - state_after_checkpoint: current_state.clone(), + Self::report_last_checkpoint_version(last_snapshot.version()); + Self { + current_state: out_current_state.clone(), + last_snapshot, state_commit_sender, + estimated_items: 0, target_items, // The join handle of the async state commit thread for graceful drop. join_handle: Some(join_handle), - }; - myself.report_latest_committed_version(); - myself + } } /// This method checks whether a commit is needed based on the target_items value and the number of items in state_until_checkpoint. /// If a commit is needed, it sends a CommitMessage::Data message to the StateSnapshotCommitter thread to commit the data. /// If sync_commit is true, it also sends a CommitMessage::Sync message to ensure that the commit is completed before returning. - fn maybe_commit(&mut self, sync_commit: bool) { - if sync_commit { - let (commit_sync_sender, commit_sync_receiver) = mpsc::channel(); - if let Some(to_commit) = self.state_until_checkpoint.take().map(Arc::from) { - self.state_commit_sender - .send(CommitMessage::Data(to_commit)) - .unwrap(); - } - self.state_commit_sender - .send(CommitMessage::Sync(commit_sync_sender)) - .unwrap(); - commit_sync_receiver.recv().unwrap(); // blocks until the to_commit is received. - } else if self.state_until_checkpoint.is_some() { - let take_out_to_commit = { - let state_until_checkpoint = - self.state_until_checkpoint.as_ref().expect("Must exist"); - state_until_checkpoint - .updates_since_base - .shards - .iter() - .map(|shard| shard.len()) - .sum::() - >= self.target_items - || state_until_checkpoint.current_version.map_or(0, |v| v + 1) - - state_until_checkpoint.base_version.map_or(0, |v| v + 1) - >= TARGET_SNAPSHOT_INTERVAL_IN_VERSION - }; - if take_out_to_commit { - let to_commit: Arc = self - .state_until_checkpoint - .take() - .map(Arc::from) - .expect("Must exist"); - info!( - base_version = to_commit.base_version, - version = to_commit.current_version, - "Sent StateDelta to async commit thread." - ); - self.state_commit_sender - .send(CommitMessage::Data(to_commit)) - .unwrap(); + fn maybe_commit(&mut self, checkpoint: Option, sync_commit: bool) { + if let Some(checkpoint) = checkpoint { + if !checkpoint.is_the_same(&self.last_snapshot) + && (sync_commit + || self.estimated_items >= self.target_items + || self.buffered_versions() >= TARGET_SNAPSHOT_INTERVAL_IN_VERSION) + { + self.enqueue_commit(checkpoint); } } + + if sync_commit { + self.drain_commits(); + } + } + + fn current_state_locked(&self) -> MutexGuard { + self.current_state.lock() + } + + fn buffered_versions(&self) -> u64 { + self.current_state_locked().next_version() - self.last_snapshot.next_version() + } + + fn enqueue_commit(&mut self, checkpoint: StateWithSummary) { + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["buffered_state___enqueue_commit"]); + + self.state_commit_sender + .send(CommitMessage::Data(checkpoint.clone())) + .unwrap(); + // n.b. if the latest state is not a (the latest) checkpoint, the items between them are + // not counted towards the next commit. If this becomes a concern we can count the items + // instead of putting it 0 here. + self.estimated_items = 0; + self.last_snapshot = checkpoint; + } + + fn drain_commits(&mut self) { + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["buffered_state___drain_commits"]); + + let (commit_sync_sender, commit_sync_receiver) = mpsc::channel(); + self.state_commit_sender + .send(CommitMessage::Sync(commit_sync_sender)) + .unwrap(); + commit_sync_receiver.recv().unwrap(); } pub(crate) fn sync_commit(&mut self) { - self.maybe_commit(true /* sync_commit */); + let checkpoint = self.current_state_locked().last_checkpoint().clone(); + self.maybe_commit(Some(checkpoint), true /* sync_commit */); } - fn report_latest_committed_version(&self) { - LATEST_CHECKPOINT_VERSION.set( - self.state_after_checkpoint - .lock() - .base_version - .map_or(-1, |v| v as i64), - ); + fn report_last_checkpoint_version(version: Option) { + LATEST_CHECKPOINT_VERSION.set(version.map_or(-1, |v| v as i64)); } /// This method updates the buffered state with new data. pub fn update( &mut self, - updates_until_next_checkpoint_since_current_option: Option<&ShardedStateUpdates>, - new_state_after_checkpoint: &StateDelta, + new_state: LedgerStateWithSummary, + estimated_new_items: usize, sync_commit: bool, ) -> Result<()> { - { - let _timer = OTHER_TIMERS_SECONDS.timer_with(&["update_current_state"]); - let mut state_after_checkpoint = self.state_after_checkpoint.lock(); - - assert!(new_state_after_checkpoint - .current - .is_family(&state_after_checkpoint.current)); - ensure!( - new_state_after_checkpoint.base_version >= state_after_checkpoint.base_version, - "new state base version smaller than state after checkpoint base version", - ); - if let Some(updates_until_next_checkpoint_since_current) = - updates_until_next_checkpoint_since_current_option - { - ensure!( - new_state_after_checkpoint.base_version > state_after_checkpoint.base_version, - "Diff between base and latest checkpoints provided, while they are the same.", - ); - state_after_checkpoint - .updates_since_base - .clone_merge(updates_until_next_checkpoint_since_current); - - let mut old_state = - state_after_checkpoint.replace_with(new_state_after_checkpoint.clone()); - old_state.current = state_after_checkpoint.base.clone(); - old_state.current_version = state_after_checkpoint.base_version; - - if let Some(ref mut delta) = self.state_until_checkpoint { - delta.merge(old_state); - } else { - self.state_until_checkpoint = Some(Box::new(old_state)); - } - } else { - ensure!( - new_state_after_checkpoint.base_version == state_after_checkpoint.base_version, - "Diff between base and latest checkpoints not provided.", - ); - state_after_checkpoint.set(new_state_after_checkpoint.clone()); - } - } - - // n.b. make sure these are called after self.state_after_checkpoint is unlocked. - // otherwise things reading the "pre-committed version" will be blocked by - // the buffered state lock. - self.maybe_commit(sync_commit); - self.report_latest_committed_version(); + let _timer = OTHER_TIMERS_SECONDS.timer_with(&["buffered_state___update"]); + + let old_state = self.current_state_locked().clone(); + assert!(new_state.is_descendant_of(&old_state)); + + self.estimated_items += estimated_new_items; + let version = new_state.last_checkpoint().version(); + + let last_checkpoint = new_state.last_checkpoint().clone(); + // Commit state only if there is a new checkpoint, eases testing and make estimated + // buffer size a tad more realistic. + let checkpoint_to_commit_opt = + (old_state.next_version() < last_checkpoint.next_version()).then_some(last_checkpoint); + *self.current_state_locked() = new_state; + self.maybe_commit(checkpoint_to_commit_opt, sync_commit); + Self::report_last_checkpoint_version(version); Ok(()) } - pub(crate) fn drain(&mut self) { + pub(crate) fn quit(&mut self) { if let Some(handle) = self.join_handle.take() { self.sync_commit(); self.state_commit_sender.send(CommitMessage::Exit).unwrap(); @@ -221,10 +186,15 @@ impl BufferedState { .expect("snapshot commit thread should join peacefully."); } } + + /// used by restore tooling + pub(crate) fn force_last_snapshot(&mut self, snapshot: StateWithSummary) { + self.last_snapshot = snapshot + } } impl Drop for BufferedState { fn drop(&mut self) { - self.drain() + self.quit() } } diff --git a/storage/aptosdb/src/state_store/current_state.rs b/storage/aptosdb/src/state_store/current_state.rs deleted file mode 100644 index 6b251c9dc4f2f..0000000000000 --- a/storage/aptosdb/src/state_store/current_state.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use aptos_storage_interface::state_store::state_delta::StateDelta; -use derive_more::{Deref, DerefMut}; - -#[derive(Clone, Debug, Deref, DerefMut)] -pub(crate) struct CurrentState { - #[deref] - #[deref_mut] - from_latest_checkpoint_to_current: StateDelta, -} - -impl CurrentState { - pub fn new_dummy() -> Self { - Self { - from_latest_checkpoint_to_current: StateDelta::new_empty(), - } - } - - pub fn set(&mut self, from_latest_checkpoint_to_current: StateDelta) { - self.from_latest_checkpoint_to_current = from_latest_checkpoint_to_current; - } - - pub fn get(&self) -> &StateDelta { - &self.from_latest_checkpoint_to_current - } -} diff --git a/storage/aptosdb/src/state_store/mod.rs b/storage/aptosdb/src/state_store/mod.rs index 9ff5d7221c0ca..d5c68b382e00a 100644 --- a/storage/aptosdb/src/state_store/mod.rs +++ b/storage/aptosdb/src/state_store/mod.rs @@ -21,12 +21,9 @@ use crate::{ state_kv_db::StateKvDb, state_merkle_db::StateMerkleDb, state_restore::{StateSnapshotRestore, StateSnapshotRestoreMode, StateValueWriter}, - state_store::{ - buffered_state::BufferedState, current_state::CurrentState, persisted_state::PersistedState, - }, + state_store::{buffered_state::BufferedState, persisted_state::PersistedState}, utils::{ iterators::PrefixedStateValueIterator, - new_sharded_kv_schema_batch, truncation_helper::{ find_tree_root_at_or_before, get_max_version_in_state_merkle_db, truncate_ledger_db, truncate_state_kv_db, truncate_state_merkle_db, @@ -34,9 +31,8 @@ use crate::{ ShardedStateKvSchemaBatch, }, }; -use anyhow::Context; use aptos_crypto::{ - hash::{CryptoHash, SPARSE_MERKLE_PLACEHOLDER_HASH}, + hash::{CryptoHash, CORRUPTION_SENTINEL, SPARSE_MERKLE_PLACEHOLDER_HASH}, HashValue, }; use aptos_db_indexer::db_indexer::InternalIndexerDB; @@ -44,23 +40,21 @@ use aptos_db_indexer_schemas::{ metadata::{MetadataKey, MetadataValue, StateSnapshotProgress}, schema::indexer_metadata::InternalIndexerMetadataSchema, }; -use aptos_executor::types::in_memory_state_calculator_v2::InMemoryStateCalculatorV2; -use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_infallible::Mutex; use aptos_jellyfish_merkle::iterator::JellyfishMerkleIterator; use aptos_logger::info; use aptos_metrics_core::TimerHelper; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::{NativeBatch, SchemaBatch, WriteBatch}; use aptos_scratchpad::SparseMerkleTree; use aptos_storage_interface::{ db_ensure as ensure, db_other_bail as bail, state_store::{ - sharded_state_update_refs::ShardedStateUpdateRefs, - state_delta::StateDelta, - state_view::{ - async_proof_fetcher::AsyncProofFetcher, - cached_state_view::{CachedStateView, ShardedStateCache}, - }, + state::{LedgerState, State}, + state_summary::{ProvableStateSummary, StateSummary}, + state_update_refs::{PerVersionStateUpdateRefs, StateUpdateRefs}, + state_view::cached_state_view::{ShardedStateCache, StateCacheShard}, + state_with_summary::{LedgerStateWithSummary, StateWithSummary}, + versioned_state_value::{StateCacheEntry, StateUpdateRef}, NUM_STATE_SHARDS, }, AptosDbError, DbReader, Result, StateSnapshotReceiver, @@ -74,16 +68,13 @@ use aptos_types::{ StaleStateValueByKeyHashIndex, StaleStateValueIndex, StateValue, StateValueChunkWithProof, }, - StateViewId, }, transaction::Version, - write_set::WriteSet, }; use claims::{assert_ge, assert_le}; use itertools::Itertools; use rayon::prelude::*; use std::{ - collections::HashSet, ops::Deref, sync::{Arc, MutexGuard}, }; @@ -92,7 +83,6 @@ pub(crate) mod buffered_state; mod state_merkle_batch_committer; mod state_snapshot_committer; -mod current_state; mod persisted_state; #[cfg(test)] mod state_store_test; @@ -124,7 +114,7 @@ pub(crate) struct StateStore { buffered_state: Mutex, /// CurrentState is shared between this and the buffered_state. /// On read, we don't need to lock the `buffered_state` to get the latest state. - current_state: Arc>, + current_state: Arc>, /// Tracks a persisted smt, any state older than that is guaranteed to be found in RocksDB persisted_state: Arc>, buffered_state_target_items: usize, @@ -182,29 +172,29 @@ impl DbReader for StateDb { /// Returns the proof of the given state key and version. fn get_state_proof_by_version_ext( &self, - state_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result { let (_, proof) = self .state_merkle_db - .get_with_proof_ext(state_key, version, root_depth)?; + .get_with_proof_ext(key_hash, version, root_depth)?; Ok(proof) } /// Get the state value with proof given the state key and version fn get_state_value_with_proof_by_version_ext( &self, - state_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result<(Option, SparseMerkleProofExt)> { let (leaf_data, proof) = self .state_merkle_db - .get_with_proof_ext(state_key, version, root_depth)?; + .get_with_proof_ext(key_hash, version, root_depth)?; Ok(( match leaf_data { - Some((_, (key, version))) => Some(self.expect_value_by_version(&key, version)?), + Some((_val_hash, (key, ver))) => Some(self.expect_value_by_version(&key, ver)?), None => None, }, proof, @@ -225,8 +215,12 @@ impl DbReader for StateDb { } impl DbReader for StateStore { - fn get_buffered_state_base(&self) -> Result> { - Ok(self.persisted_state().clone()) + fn get_persisted_state(&self) -> Result { + Ok(self.persisted_state_locked().state().clone()) + } + + fn get_persisted_state_summary(&self) -> Result { + Ok(self.persisted_state_locked().summary().clone()) } /// Returns the latest state snapshot strictly before `next_version` if any. @@ -262,23 +256,23 @@ impl DbReader for StateStore { /// Returns the proof of the given state key and version. fn get_state_proof_by_version_ext( &self, - state_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result { self.deref() - .get_state_proof_by_version_ext(state_key, version, root_depth) + .get_state_proof_by_version_ext(key_hash, version, root_depth) } /// Get the state value with proof extension given the state key and version fn get_state_value_with_proof_by_version_ext( &self, - state_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result<(Option, SparseMerkleProofExt)> { self.deref() - .get_state_value_with_proof_by_version_ext(state_key, version, root_depth) + .get_state_value_with_proof_by_version_ext(key_hash, version, root_depth) } } @@ -331,12 +325,12 @@ impl StateStore { state_kv_pruner, skip_usage, }); - let current_state = Arc::new(Mutex::new(CurrentState::new_dummy())); + let current_state = Arc::new(Mutex::new(LedgerStateWithSummary::new_dummy())); let persisted_state = Arc::new(Mutex::new(PersistedState::new_dummy())); let buffered_state = if empty_buffered_state_for_restore { - BufferedState::new( + BufferedState::new_at_snapshot( &state_db, - StateDelta::new_empty(), + StateWithSummary::new_empty(), buffered_state_target_items, current_state.clone(), persisted_state.clone(), @@ -486,7 +480,7 @@ impl StateStore { state_kv_pruner, skip_usage: false, }); - let current_state = Arc::new(Mutex::new(CurrentState::new_dummy())); + let current_state = Arc::new(Mutex::new(LedgerStateWithSummary::new_dummy())); let persisted_state = Arc::new(Mutex::new(PersistedState::new_dummy())); let _ = Self::create_buffered_state_from_latest_snapshot( &state_db, @@ -496,7 +490,7 @@ impl StateStore { current_state.clone(), persisted_state, )?; - let base_version = current_state.lock().base_version; + let base_version = current_state.lock().version(); Ok(base_version) } @@ -505,8 +499,8 @@ impl StateStore { buffered_state_target_items: usize, hack_for_tests: bool, check_max_versions_after_snapshot: bool, - current_state: Arc>, - persisted_state: Arc>, + out_current_state: Arc>, + out_persisted_state: Arc>, ) -> Result { let num_transactions = state_db .ledger_db @@ -533,16 +527,17 @@ impl StateStore { *SPARSE_MERKLE_PLACEHOLDER_HASH }; let usage = state_db.get_state_storage_usage(latest_snapshot_version)?; - let mut buffered_state = BufferedState::new( + let state = StateWithSummary::new_at_version( + latest_snapshot_version, + latest_snapshot_root_hash, + usage, + ); + let mut buffered_state = BufferedState::new_at_snapshot( state_db, - StateDelta::new_at_checkpoint( - latest_snapshot_root_hash, - usage, - latest_snapshot_version, - ), + state.clone(), buffered_state_target_items, - current_state.clone(), - persisted_state, + out_current_state.clone(), + out_persisted_state, ); // In some backup-restore tests we hope to open the db without consistency check. @@ -572,18 +567,6 @@ impl StateStore { num_transactions, ); } - let snapshot = state_db.get_state_snapshot_before(num_transactions)?; - let current_state_cloned = current_state.lock().get().clone(); - let speculative_state = current_state_cloned - .current - .freeze(¤t_state_cloned.base); - let latest_snapshot_state_view = CachedStateView::new_impl( - StateViewId::Miscellaneous, - num_transactions, - snapshot, - speculative_state, - Arc::new(AsyncProofFetcher::new(state_db.clone())), - ); let write_sets = state_db .ledger_db .write_set_db() @@ -600,41 +583,46 @@ impl StateStore { .filter(|(_idx, txn_info)| txn_info.has_state_checkpoint_hash()) .last() .map(|(idx, _)| idx); - latest_snapshot_state_view.prime_cache_by_write_set(&write_sets)?; - - let state_checkpoint_output = - InMemoryStateCalculatorV2::calculate_for_write_sets_after_snapshot( - &Arc::new(current_state_cloned), - &latest_snapshot_state_view.into_state_cache(), - last_checkpoint_index, - &write_sets, - )?; + + let state_update_refs = StateUpdateRefs::index_write_sets( + state.next_version(), + &write_sets, + write_sets.len(), + last_checkpoint_index, + ); + let current_state = out_current_state.lock().clone(); + let (new_state, _state_reads) = current_state.ledger_state().update_with_db_reader( + &state, + &state_update_refs, + state_db.clone(), + )?; + let new_state_summary = current_state.ledger_state_summary().update( + &ProvableStateSummary::new(state.summary().clone(), state_db.as_ref()), + &state_update_refs, + )?; + let updated = + LedgerStateWithSummary::from_state_and_summary(new_state, new_state_summary); // synchronously commit the snapshot at the last checkpoint here if not committed to disk yet. buffered_state.update( - state_checkpoint_output - .state_updates_before_last_checkpoint - .as_ref(), - &state_checkpoint_output.result_state, + updated, 0, /* estimated_items, doesn't matter since we sync-commit */ true, /* sync_commit */ )?; } - { - let current_state = current_state.lock(); - info!( - latest_snapshot_version = current_state.base_version, - latest_snapshot_root_hash = current_state.base.root_hash(), - latest_in_memory_version = current_state.current_version, - latest_in_memory_root_hash = current_state.current.root_hash(), - "StateStore initialization finished.", - ); - } + let current_state = out_current_state.lock().clone(); + info!( + latest_in_memory_version = current_state.version(), + latest_in_memory_root_hash = current_state.summary().root_hash(), + latest_snapshot_version = current_state.last_checkpoint().version(), + latest_snapshot_root_hash = current_state.last_checkpoint().summary().root_hash(), + "StateStore initialization finished.", + ); Ok(buffered_state) } pub fn reset(&self) { - self.buffered_state.lock().drain(); + self.buffered_state.lock().quit(); *self.buffered_state.lock() = Self::create_buffered_state_from_latest_snapshot( &self.state_db, self.buffered_state_target_items, @@ -650,18 +638,14 @@ impl StateStore { &self.buffered_state } - pub fn current_state(&self) -> MutexGuard { + pub fn current_state_locked(&self) -> MutexGuard { self.current_state.lock() } - pub fn persisted_state(&self) -> MutexGuard { + pub fn persisted_state_locked(&self) -> MutexGuard { self.persisted_state.lock() } - pub fn current_state_cloned(&self) -> StateDelta { - self.current_state().get().clone() - } - /// Returns the key, value pairs for a particular state key prefix at at desired version. This /// API can be used to get all resources of an account by passing the account address as the /// key prefix. @@ -690,83 +674,77 @@ impl StateStore { self.state_merkle_db.get_range_proof(rightmost_key, version) } - /// Put the write sets on top of current state - pub fn put_write_sets( + /// Without the executor and execution pipeline, the State and StateSummary for both the + /// latest version and the last checkpoint version need to be calculated before committing + /// to the DB. This is useful for the db-restore tooling and tests. + pub fn calculate_state_and_put_updates( &self, - write_sets: Vec, - first_version: Version, - batch: &SchemaBatch, - sharded_state_kv_batches: &ShardedStateKvSchemaBatch, - enable_sharding: bool, - ) -> Result<()> { - self.put_value_sets( - first_version, - &ShardedStateUpdateRefs::index_write_sets(&write_sets, write_sets.len()), - StateStorageUsage::new_untracked(), - None, // state cache - batch, + state_update_refs: &StateUpdateRefs, + ledger_batch: &mut SchemaBatch, + sharded_state_kv_batches: &mut ShardedStateKvSchemaBatch, + ) -> Result { + let current = self.current_state_locked().ledger_state(); + let persisted = self.persisted_state_locked().state().clone(); + let (new_state, reads) = + current.update_with_db_reader(&persisted, state_update_refs, self.state_db.clone())?; + + self.put_state_updates( + &new_state, + &state_update_refs.per_version, + &reads, + ledger_batch, sharded_state_kv_batches, - enable_sharding, - None, // last_checkpoint_index - ) + )?; + + Ok(new_state) } - /// Put the `value_state_sets` into its own CF. - pub fn put_value_sets( + pub fn put_state_updates( &self, - first_version: Version, - state_update_refs: &ShardedStateUpdateRefs, - expected_usage: StateStorageUsage, - sharded_state_cache: Option<&ShardedStateCache>, - ledger_batch: &SchemaBatch, - sharded_state_kv_batches: &ShardedStateKvSchemaBatch, - enable_sharding: bool, - last_checkpoint_index: Option, + state: &LedgerState, + state_update_refs: &PerVersionStateUpdateRefs, + state_reads: &ShardedStateCache, + ledger_batch: &mut SchemaBatch, + sharded_state_kv_batches: &mut ShardedStateKvSchemaBatch, ) -> Result<()> { let _timer = OTHER_TIMERS_SECONDS.timer_with(&["put_value_sets"]); + let current_state = self.current_state_locked().state().clone(); self.put_stats_and_indices( + ¤t_state, + state, state_update_refs, - first_version, - expected_usage, - sharded_state_cache, + state_reads, ledger_batch, sharded_state_kv_batches, - last_checkpoint_index, - enable_sharding, )?; - self.put_state_values( - first_version, - state_update_refs, - sharded_state_kv_batches, - enable_sharding, - ) + self.put_state_values(state_update_refs, sharded_state_kv_batches) } pub fn put_state_values( &self, - first_version: Version, - state_update_refs: &ShardedStateUpdateRefs, - sharded_state_kv_batches: &ShardedStateKvSchemaBatch, - enable_sharding: bool, + state_update_refs: &PerVersionStateUpdateRefs, + sharded_state_kv_batches: &mut ShardedStateKvSchemaBatch, ) -> Result<()> { let _timer = OTHER_TIMERS_SECONDS.timer_with(&["add_state_kv_batch"]); // TODO(aldenhu): put by refs; batch put sharded_state_kv_batches - .par_iter() + .par_iter_mut() .zip_eq(state_update_refs.shards.par_iter()) .try_for_each(|(batch, updates)| { - updates.iter().try_for_each(|(idx, key, val)| { - let ver = first_version + *idx as Version; - if enable_sharding { + updates.iter().try_for_each(|(key, update)| { + if self.state_kv_db.enabled_sharding() { batch.put::( - &(CryptoHash::hash(*key), ver), - &val.cloned(), + &(CryptoHash::hash(*key), update.version), + &update.value.cloned(), ) } else { - batch.put::(&((*key).clone(), ver), &val.cloned()) + batch.put::( + &((*key).clone(), update.version), + &update.value.cloned(), + ) } }) }) @@ -790,233 +768,169 @@ impl StateStore { /// extra stale index as 1 cover the latter case. pub fn put_stats_and_indices( &self, - state_update_refs: &ShardedStateUpdateRefs, - first_version: Version, - expected_usage: StateStorageUsage, - // If not None, it must contains all keys in the value_state_sets. + current_state: &State, + latest_state: &LedgerState, + state_update_refs: &PerVersionStateUpdateRefs, // TODO(grao): Restructure this function. - sharded_state_cache: Option<&ShardedStateCache>, - batch: &SchemaBatch, - sharded_state_kv_batches: &ShardedStateKvSchemaBatch, - last_checkpoint_index: Option, - enable_sharding: bool, + state_reads: &ShardedStateCache, + batch: &mut SchemaBatch, + sharded_state_kv_batches: &mut ShardedStateKvSchemaBatch, ) -> Result<()> { let _timer = OTHER_TIMERS_SECONDS.timer_with(&["put_stats_and_indices"]); - let base_version = first_version.checked_sub(1); - let mut usage = self.get_usage(base_version)?; - let base_version_usage = usage; - - let mut state_cache_with_version = &ShardedStateCache::default(); - if let Some(base_version) = base_version { - let _timer = OTHER_TIMERS_SECONDS.timer_with(&["put_stats_and_indices__total_get"]); - if let Some(sharded_state_cache) = sharded_state_cache { - // For some entries the base value version is None, here is to fiil those in. - // See `ShardedStateCache`. - self.prepare_version_in_cache(base_version, sharded_state_cache)?; - state_cache_with_version = sharded_state_cache; - } else { - // TODO(aldenhu): get all updates from StateDelta directly - let key_set = { - let _timer = OTHER_TIMERS_SECONDS - .timer_with(&["put_stats_and_indices__get_all_updates"]); - state_update_refs - .shards - .iter() - .flat_map(|shard| shard.iter()) - .map(|(_idx, key, _val)| key) - .collect::>() - }; - // TODO(aldenhu): maybe parallel by shard instead of individual keys? - THREAD_MANAGER.get_high_pri_io_pool().scope(|s| { - for key in key_set { - let cache = state_cache_with_version.shard(key.get_shard_id()); - s.spawn(move |_| { - let _timer = OTHER_TIMERS_SECONDS - .timer_with(&["put_stats_and_indices__get_state_value"]); - let version_and_value = self - .state_db - .get_state_value_with_version_by_version(key, base_version) - .expect("Must succeed."); - if let Some((version, value)) = version_and_value { - cache.insert((*key).clone(), (Some(version), Some(value))); - } else { - cache.insert((*key).clone(), (Some(base_version), None)); - } - }); - } - }); - } - } - - // TODO(aldenhu): trust usage delta from execution, once it's always part of the state update. - let usage_deltas = Self::put_stale_state_value_index( - first_version, + Self::put_stale_state_value_index( state_update_refs, sharded_state_kv_batches, - enable_sharding, - &mut state_cache_with_version, - expected_usage.is_untracked() || base_version.is_none(), // ignore_state_cache_miss + self.state_kv_db.enabled_sharding(), + state_reads, + latest_state.usage().is_untracked() || current_state.version().is_none(), // ignore_state_cache_miss ); { let _timer = OTHER_TIMERS_SECONDS.timer_with(&["put_stats_and_indices__put_usage"]); - let num_versions = state_update_refs.num_versions; - for i in 0..num_versions { - let mut items_delta = 0; - let mut bytes_delta = 0; - for usage_delta in usage_deltas.iter() { - items_delta += usage_delta[i].0; - bytes_delta += usage_delta[i].1; - } - usage = StateStorageUsage::new( - (usage.items() as i64 + items_delta) as usize, - (usage.bytes() as i64 + bytes_delta) as usize, - ); - if (i == num_versions - 1) || Some(i) == last_checkpoint_index { - let version = first_version + i as u64; - info!("Write usage at version {version}, {usage:?}."); - batch.put::(&version, &usage.into())? - } + if latest_state.last_checkpoint().next_version() > current_state.next_version() { + // has a checkpoint in the chunk + Self::put_usage(latest_state.last_checkpoint(), batch)?; } + if !latest_state.is_checkpoint() { + // latest state isn't a checkpoint + Self::put_usage(latest_state, batch)?; + } + STATE_ITEMS.set(latest_state.usage().items() as i64); + TOTAL_STATE_BYTES.set(latest_state.usage().bytes() as i64); } - if !expected_usage.is_untracked() { - ensure!( - expected_usage == usage, - "Calculated state db usage at version {} not expected. expected: {:?}, calculated: {:?}, base version: {:?}, base version usage: {:?}", - first_version + state_update_refs.num_versions as u64 - 1, - expected_usage, - usage, - base_version, - base_version_usage, - ); - } - - STATE_ITEMS.set(usage.items() as i64); - TOTAL_STATE_BYTES.set(usage.bytes() as i64); - Ok(()) } fn put_stale_state_value_index( - first_version: Version, - state_update_refs: &ShardedStateUpdateRefs, - sharded_state_kv_batches: &ShardedStateKvSchemaBatch, + state_update_refs: &PerVersionStateUpdateRefs, + sharded_state_kv_batches: &mut ShardedStateKvSchemaBatch, enable_sharding: bool, - sharded_state_cache: &mut &ShardedStateCache, + sharded_state_cache: &ShardedStateCache, ignore_state_cache_miss: bool, - ) -> Vec> { + ) { let _timer = OTHER_TIMERS_SECONDS.timer_with(&["put_stale_kv_index"]); - let num_versions = state_update_refs.num_versions; + // calculate total state size in bytes - let usage_deltas: Vec> = sharded_state_cache + sharded_state_cache + .shards .par_iter() .zip_eq(state_update_refs.shards.par_iter()) - .zip_eq(sharded_state_kv_batches.par_iter()) + .zip_eq(sharded_state_kv_batches.par_iter_mut()) .enumerate() - .map(|(shard_id, ((cache, updates), batch))| { - let _timer = - OTHER_TIMERS_SECONDS.timer_with(&[&format!("put_stale_kv_index__{shard_id}")]); - - let mut usage_delta = Vec::with_capacity(num_versions); - let mut iter = updates.iter(); - - for idx in 0..num_versions { - let version = first_version + idx as Version; - let ver_iter = iter.take_while_ref(|(i, _key, _val)| *i == idx); - - let mut items_delta = 0; - let mut bytes_delta = 0; - - for (_idx, key, value) in ver_iter { - if let Some(value) = value { - items_delta += 1; - bytes_delta += (key.size() + value.size()) as i64; - } else { - // Update the stale index of the tombstone at current version to - // current version. - if enable_sharding { - batch - .put::( - &StaleStateValueByKeyHashIndex { - stale_since_version: version, - version, - state_key_hash: key.hash(), - }, - &(), - ) - .unwrap(); - } else { - batch - .put::( - &StaleStateValueIndex { - stale_since_version: version, - version, - state_key: (*key).clone(), - }, - &(), - ) - .unwrap(); - } - } - - let old_version_and_value_opt = if let Some((old_version, old_value_opt)) = - cache.insert((*key).clone(), (Some(version), value.cloned())) - { - old_value_opt.map(|value| (old_version, value)) - } else { - // n.b. all updated state items must be read and recorded in the state cache, - // otherwise we can't calculate the correct usage. The is_untracked() hack - // is to allow some db tests without real execution layer to pass. - assert!(ignore_state_cache_miss, "Must cache read."); - None - }; - - if let Some((old_version, old_value)) = old_version_and_value_opt { - let old_version = old_version - .context("Must have old version in cache.") - .unwrap(); - items_delta -= 1; - bytes_delta -= (key.size() + old_value.size()) as i64; - // stale index of the old value at its version. - if enable_sharding { - batch - .put::( - &StaleStateValueByKeyHashIndex { - stale_since_version: version, - version: old_version, - state_key_hash: key.hash(), - }, - &(), - ) - .unwrap(); - } else { - batch - .put::( - &StaleStateValueIndex { - stale_since_version: version, - version: old_version, - state_key: (*key).clone(), - }, - &(), - ) - .unwrap(); - } - } - } - usage_delta.push((items_delta, bytes_delta)); + .for_each(|(shard_id, ((cache, updates), batch))| { + Self::put_stale_state_value_index_for_shard( + shard_id, + state_update_refs.first_version, + state_update_refs.num_versions, + cache, + updates, + batch, + enable_sharding, + ignore_state_cache_miss, + ); + }) + } + + fn put_stale_state_value_index_for_shard<'kv>( + shard_id: usize, + first_version: Version, + num_versions: usize, + cache: &StateCacheShard, + updates: &[(&'kv StateKey, StateUpdateRef<'kv>)], + batch: &mut NativeBatch, + enable_sharding: bool, + ignore_state_cache_miss: bool, + ) { + let _timer = OTHER_TIMERS_SECONDS.timer_with(&[&format!("put_stale_kv_index__{shard_id}")]); + + let mut iter = updates.iter(); + for version in first_version..first_version + num_versions as Version { + let ver_iter = iter.take_while_ref(|(_k, u)| u.version == version); + + for (key, update) in ver_iter { + if update.value.is_none() { + // This is a tome stone, can be pruned once this `version` goes out of + // the pruning window. + Self::put_state_kv_index(batch, enable_sharding, version, version, key); } - usage_delta - }) - .collect(); - usage_deltas + // TODO(aldenhu): cache changes here, should consume it. + let old_entry = cache + .insert( + (*key).clone(), + StateCacheEntry::from_state_update_ref(update), + ) + .unwrap_or_else(|| { + // n.b. all updated state items must be read and recorded in the state cache, + // otherwise we can't calculate the correct usage. The is_untracked() hack + // is to allow some db tests without real execution layer to pass. + assert!(ignore_state_cache_miss, "Must cache read."); + StateCacheEntry::NonExistent + }); + + if let StateCacheEntry::Value { + version: old_version, + value: _, + } = old_entry + { + // The value at `old_version` can be pruned once the pruning window hits + // this `version`. + Self::put_state_kv_index(batch, enable_sharding, version, old_version, key) + } + } + } + } + + fn put_state_kv_index( + batch: &mut NativeBatch, + enable_sharding: bool, + stale_since_version: Version, + version: Version, + key: &StateKey, + ) { + if enable_sharding { + batch + .put::( + &StaleStateValueByKeyHashIndex { + stale_since_version, + version, + state_key_hash: key.hash(), + }, + &(), + ) + .unwrap(); + } else { + batch + .put::( + &StaleStateValueIndex { + stale_since_version, + version, + state_key: (*key).clone(), + }, + &(), + ) + .unwrap(); + } + } + + fn put_usage(state: &State, batch: &mut SchemaBatch) -> Result<()> { + if let Some(version) = state.version() { + let usage = state.usage(); + info!("Write usage at version {version}, {usage:?}."); + batch.put::(&version, &usage.into())?; + } else { + assert_eq!(state.usage().items(), 0); + assert_eq!(state.usage().bytes(), 0); + } + + Ok(()) } pub(crate) fn shard_state_value_batch( &self, - sharded_batch: &ShardedStateKvSchemaBatch, + sharded_batch: &mut ShardedStateKvSchemaBatch, values: &StateValueBatch, enable_sharding: bool, ) -> Result<()> { @@ -1040,27 +954,6 @@ impl StateStore { Ok(()) } - /// Merklize the results generated by `value_state_sets` to `batch` and return the result root - /// hashes for each write set. - #[cfg(test)] - pub fn merklize_value_set( - &self, - value_set: Vec<(HashValue, Option<&(HashValue, StateKey)>)>, - version: Version, - base_version: Option, - ) -> Result { - let (top_levels_batch, sharded_batch, root_hash) = - self.state_merkle_db.merklize_value_set( - value_set, - version, - base_version, - /*previous_epoch_ending_version=*/ None, - )?; - self.state_merkle_db - .commit(version, top_levels_batch, sharded_batch)?; - Ok(root_hash) - } - pub fn get_root_hash(&self, version: Version) -> Result { self.state_merkle_db.get_root_hash(version) } @@ -1187,42 +1080,37 @@ impl StateStore { Ok(keys) } - fn prepare_version_in_cache( - &self, - base_version: Version, - sharded_state_cache: &ShardedStateCache, - ) -> Result<()> { - THREAD_MANAGER.get_high_pri_io_pool().scope(|s| { - sharded_state_cache.par_iter().for_each(|shard| { - shard.iter_mut().for_each(|mut entry| { - match entry.value() { - (None, Some(_)) => s.spawn(move |_| { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["put_stats_and_indices__get_state_value"]) - .start_timer(); - let version_and_value = self - .state_db - .get_state_value_with_version_by_version(entry.key(), base_version) - .expect("Must succeed."); - if let Some((version, _)) = version_and_value { - entry.0 = Some(version); - } else { - unreachable!(); - } - }), - _ => { - // I just want a counter. - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["put_stats_and_indices__skip"]) - .start_timer(); - }, - }; - }) - }); - }); + pub fn init_state_ignoring_summary(&self, version: Option) -> Result<()> { + let usage = self.get_usage(version)?; + let state = State::new_at_version(version, usage); + let ledger_state = LedgerState::new(state.clone(), state); + self.set_state_ignoring_summary(ledger_state); Ok(()) } + + pub fn set_state_ignoring_summary(&self, ledger_state: LedgerState) { + let smt = SparseMerkleTree::new(*CORRUPTION_SENTINEL); + let last_checkpoint_summary = + StateSummary::new_at_version(ledger_state.last_checkpoint().version(), smt.clone()); + let summary = StateSummary::new_at_version(ledger_state.version(), smt.clone()); + + let last_checkpoint = StateWithSummary::new( + ledger_state.last_checkpoint().clone(), + last_checkpoint_summary.clone(), + ); + let latest = StateWithSummary::new(ledger_state.latest().clone(), summary); + let current = LedgerStateWithSummary::from_latest_and_last_checkpoint( + latest, + last_checkpoint.clone(), + ); + + self.persisted_state_locked().set(last_checkpoint.clone()); + *self.current_state_locked() = current; + self.buffered_state + .lock() + .force_last_snapshot(last_checkpoint); + } } impl StateValueWriter for StateStore { @@ -1236,8 +1124,8 @@ impl StateValueWriter for StateStore { let _timer = OTHER_TIMERS_SECONDS .with_label_values(&["state_value_writer_write_chunk"]) .start_timer(); - let batch = SchemaBatch::new(); - let sharded_schema_batch = new_sharded_kv_schema_batch(); + let mut batch = SchemaBatch::new(); + let mut sharded_schema_batch = self.state_kv_db.new_sharded_native_batches(); batch.put::( &DbMetadataKey::StateSnapshotKvRestoreProgress(version), @@ -1258,19 +1146,19 @@ impl StateValueWriter for StateStore { .write_keys_to_indexer_db(&keys, version, progress)?; } self.shard_state_value_batch( - &sharded_schema_batch, + &mut sharded_schema_batch, node_batch, self.state_kv_db.enabled_sharding(), )?; self.state_kv_db - .commit(version, batch, sharded_schema_batch) + .commit(version, Some(batch), sharded_schema_batch) } fn kv_finish(&self, version: Version, usage: StateStorageUsage) -> Result<()> { self.ledger_db.metadata_db().put_usage(version, usage)?; if let Some(internal_indexer_db) = self.internal_indexer_db.as_ref() { if version > 0 { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch.put::( &MetadataKey::LatestVersion, &MetadataValue::Version(version - 1), @@ -1348,3 +1236,94 @@ impl StateValueWriter for StateStore { Ok(main_db_progress) } } + +#[cfg(test)] +mod test_only { + use crate::state_store::StateStore; + use aptos_crypto::HashValue; + use aptos_schemadb::batch::SchemaBatch; + use aptos_storage_interface::state_store::{ + state_summary::ProvableStateSummary, state_update_refs::StateUpdateRefs, + state_with_summary::LedgerStateWithSummary, + }; + use aptos_types::{ + state_store::{state_key::StateKey, state_value::StateValue}, + transaction::Version, + }; + use itertools::Itertools; + + impl StateStore { + /// assumes state checkpoint at the last version + pub fn commit_block_for_test< + UpdateIter: IntoIterator)>, + VersionIter: IntoIterator, + >( + &self, + first_version: Version, + updates_by_version: VersionIter, + ) -> HashValue { + assert_eq!(first_version, self.current_state_locked().next_version()); + + let updates_by_version = updates_by_version + .into_iter() + .map(|updates| updates.into_iter().collect_vec()) + .collect_vec(); + let num_versions = updates_by_version.len(); + assert!(num_versions > 0); + let last_version = first_version + num_versions as Version - 1; + + let state_update_refs = StateUpdateRefs::index( + first_version, + updates_by_version + .iter() + .map(|updates| updates.iter().map(|(k, v)| (k, v.as_ref()))), + num_versions, + Some(num_versions - 1), + ); + + let mut ledger_batch = SchemaBatch::new(); + let mut sharded_state_kv_batches = self.state_kv_db.new_sharded_native_batches(); + + let new_ledger_state = self + .calculate_state_and_put_updates( + &state_update_refs, + &mut ledger_batch, + &mut sharded_state_kv_batches, + ) + .unwrap(); + + self.ledger_db + .metadata_db() + .write_schemas(ledger_batch) + .unwrap(); + self.state_kv_db + .commit(last_version, None, sharded_state_kv_batches) + .unwrap(); + + let current = self.current_state_locked().ledger_state_summary(); + let persisted = self.persisted_state_locked().summary().clone(); + + let new_state_summary = current + .update( + &ProvableStateSummary::new(persisted, self.state_db.as_ref()), + &state_update_refs, + ) + .unwrap(); + let root_hash = new_state_summary.root_hash(); + + self.buffered_state + .lock() + .update( + LedgerStateWithSummary::from_state_and_summary( + new_ledger_state, + new_state_summary, + ), + 0, /* estimated_items, doesn't matter since we sync-commit */ + true, /* sync_commit */ + ) + .unwrap(); + + root_hash + } + } +} diff --git a/storage/aptosdb/src/state_store/persisted_state.rs b/storage/aptosdb/src/state_store/persisted_state.rs index a2655a1a796fb..d94a28fb88b24 100644 --- a/storage/aptosdb/src/state_store/persisted_state.rs +++ b/storage/aptosdb/src/state_store/persisted_state.rs @@ -3,12 +3,12 @@ use crate::metrics::OTHER_TIMERS_SECONDS; use aptos_metrics_core::TimerHelper; -use aptos_scratchpad::{SparseMerkleTree, SUBTREE_DROPPER}; -use aptos_types::state_store::state_value::StateValue; +use aptos_scratchpad::SUBTREE_DROPPER; +use aptos_storage_interface::state_store::state_with_summary::StateWithSummary; use std::ops::Deref; pub struct PersistedState { - smt: SparseMerkleTree, + persisted: StateWithSummary, } impl PersistedState { @@ -16,27 +16,27 @@ impl PersistedState { pub fn new_dummy() -> Self { Self { - smt: SparseMerkleTree::new_empty(), + persisted: StateWithSummary::new_empty(), } } - pub fn get(&self) -> &SparseMerkleTree { + pub fn get(&self) -> &StateWithSummary { let _timer = OTHER_TIMERS_SECONDS.timer_with(&["get_persisted_state"]); // The back pressure is on the getting side (which is the execution side) so that it's less // likely for a lot of blocks locking the same old base SMT. SUBTREE_DROPPER.wait_for_backlog_drop(Self::MAX_PENDING_DROPS); - &self.smt + &self.persisted } - pub fn set(&mut self, smt: SparseMerkleTree) { - self.smt = smt + pub fn set(&mut self, persisted: StateWithSummary) { + self.persisted = persisted; } } impl Deref for PersistedState { - type Target = SparseMerkleTree; + type Target = StateWithSummary; fn deref(&self) -> &Self::Target { self.get() diff --git a/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs b/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs index 63c4c39d9656a..d361caec7a11c 100644 --- a/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs +++ b/storage/aptosdb/src/state_store/state_merkle_batch_committer.rs @@ -10,20 +10,18 @@ use crate::{ state_store::{buffered_state::CommitMessage, persisted_state::PersistedState, StateDb}, }; use anyhow::{anyhow, ensure, Result}; -use aptos_crypto::HashValue; use aptos_infallible::Mutex; use aptos_jellyfish_merkle::node_type::NodeKey; use aptos_logger::{info, trace}; use aptos_metrics_core::TimerHelper; -use aptos_schemadb::SchemaBatch; -use aptos_storage_interface::state_store::state_delta::StateDelta; +use aptos_schemadb::batch::RawBatch; +use aptos_storage_interface::state_store::{state::State, state_with_summary::StateWithSummary}; use std::sync::{mpsc::Receiver, Arc}; pub struct StateMerkleBatch { - pub top_levels_batch: SchemaBatch, - pub batches_for_shards: Vec, - pub root_hash: HashValue, - pub state_delta: Arc, + pub top_levels_batch: RawBatch, + pub batches_for_shards: Vec, + pub snapshot: StateWithSummary, } pub(crate) struct StateMerkleBatchCommitter { @@ -53,18 +51,16 @@ impl StateMerkleBatchCommitter { let StateMerkleBatch { top_levels_batch, batches_for_shards, - root_hash, - state_delta, + snapshot, } = state_merkle_batch; - let current_version = state_delta - .current_version + let current_version = snapshot + .version() .expect("Current version should not be None"); // commit jellyfish merkle nodes - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["commit_jellyfish_merkle_nodes"]) - .start_timer(); + let _timer = + OTHER_TIMERS_SECONDS.timer_with(&["commit_jellyfish_merkle_nodes"]); self.state_db .state_merkle_db .commit(current_version, top_levels_batch, batches_for_shards) @@ -80,8 +76,8 @@ impl StateMerkleBatchCommitter { } info!( version = current_version, - base_version = state_delta.base_version, - root_hash = root_hash, + base_version = self.persisted_state.lock().version(), + root_hash = snapshot.summary().root_hash(), "State snapshot committed." ); LATEST_SNAPSHOT_VERSION.set(current_version as i64); @@ -92,14 +88,13 @@ impl StateMerkleBatchCommitter { .epoch_snapshot_pruner .maybe_set_pruner_target_db_version(current_version); - self.check_usage_consistency(&state_delta).unwrap(); + self.check_usage_consistency(&snapshot).unwrap(); - state_delta.base.log_generation("buffered_state_commit"); - state_delta - .current - .log_generation("buffered_state_in_mem_base"); - - self.persisted_state.lock().set(state_delta.current.clone()); + snapshot + .summary() + .global_state_summary + .log_generation("buffered_state_commit"); + self.persisted_state.lock().set(snapshot); }, CommitMessage::Sync(finish_sender) => finish_sender.send(()).unwrap(), CommitMessage::Exit => { @@ -110,9 +105,9 @@ impl StateMerkleBatchCommitter { trace!("State merkle batch committing thread exit.") } - fn check_usage_consistency(&self, state_delta: &StateDelta) -> Result<()> { - let version = state_delta - .current_version + fn check_usage_consistency(&self, state: &State) -> Result<()> { + let version = state + .version() .ok_or_else(|| anyhow!("Committing without version."))?; let usage_from_ledger_db = self.state_db.ledger_db.metadata_db().get_usage(version)?; @@ -131,12 +126,12 @@ impl StateMerkleBatchCommitter { leaf_count_from_jmt, ); - let usage_from_smt = state_delta.current.usage(); - if !usage_from_smt.is_untracked() { + let usage_from_in_mem_state = state.usage(); + if !usage_from_in_mem_state.is_untracked() { ensure!( - usage_from_smt == usage_from_ledger_db, + usage_from_in_mem_state == usage_from_ledger_db, "State storage usage info inconsistent. from smt: {:?}, from ledger_db: {:?}", - usage_from_smt, + usage_from_in_mem_state, usage_from_ledger_db, ); } diff --git a/storage/aptosdb/src/state_store/state_snapshot_committer.rs b/storage/aptosdb/src/state_store/state_snapshot_committer.rs index f7c14dcc9738c..15cacedab2ee2 100644 --- a/storage/aptosdb/src/state_store/state_snapshot_committer.rs +++ b/storage/aptosdb/src/state_store/state_snapshot_committer.rs @@ -13,14 +13,15 @@ use crate::{ }, versioned_node_cache::VersionedNodeCache, }; +use aptos_crypto::hash::CryptoHash; use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_infallible::Mutex; use aptos_logger::trace; +use aptos_metrics_core::TimerHelper; use aptos_storage_interface::{ - jmt_update_refs, jmt_updates, - state_store::{state_delta::StateDelta, NUM_STATE_SHARDS}, - Result, + jmt_update_refs, state_store::state_with_summary::StateWithSummary, Result, }; +use itertools::Itertools; use rayon::prelude::*; use static_assertions::const_assert; use std::{ @@ -34,7 +35,9 @@ use std::{ pub(crate) struct StateSnapshotCommitter { state_db: Arc, - state_snapshot_commit_receiver: Receiver>>, + /// Last snapshot merklized and sent for persistence, not guaranteed to have committed already. + last_snapshot: StateWithSummary, + state_snapshot_commit_receiver: Receiver>, state_merkle_batch_commit_sender: SyncSender>, join_handle: Option>, } @@ -44,7 +47,8 @@ impl StateSnapshotCommitter { pub fn new( state_db: Arc, - state_snapshot_commit_receiver: Receiver>>, + state_snapshot_commit_receiver: Receiver>, + last_snapshot: StateWithSummary, persisted_state: Arc>, ) -> Self { // Note: This is to ensure we cache nodes in memory from previous batches before they get committed to DB. @@ -68,18 +72,19 @@ impl StateSnapshotCommitter { .expect("Failed to spawn state merkle batch committer thread."); Self { state_db, + last_snapshot, state_snapshot_commit_receiver, state_merkle_batch_commit_sender, join_handle: Some(join_handle), } } - pub fn run(self) { + pub fn run(mut self) { while let Ok(msg) = self.state_snapshot_commit_receiver.recv() { match msg { - CommitMessage::Data(delta_to_commit) => { - let version = delta_to_commit.current_version.expect("Cannot be empty"); - let base_version = delta_to_commit.base_version; + CommitMessage::Data(snapshot) => { + let version = snapshot.version().expect("Cannot be empty"); + let base_version = self.last_snapshot.version(); let previous_epoch_ending_version = self .state_db .ledger_db @@ -89,9 +94,8 @@ impl StateSnapshotCommitter { .map(|(v, _e)| v); let (shard_root_nodes, batches_for_shards) = { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["calculate_batches_for_shards"]) - .start_timer(); + let _timer = + OTHER_TIMERS_SECONDS.timer_with(&["calculate_batches_for_shards"]); let shard_persisted_versions = self .state_db @@ -100,25 +104,42 @@ impl StateSnapshotCommitter { .unwrap(); THREAD_MANAGER.get_non_exe_cpu_pool().install(|| { - (0..NUM_STATE_SHARDS as u8) - .into_par_iter() - .map(|shard_id| { - let node_hashes = delta_to_commit - .current - .new_node_hashes_since(&delta_to_commit.base, shard_id); + snapshot + .make_delta(&self.last_snapshot) + .shards + .par_iter() + .enumerate() + .map(|(shard_id, updates)| { + let node_hashes = snapshot + .summary() + .global_state_summary + .new_node_hashes_since( + &self.last_snapshot.summary().global_state_summary, + shard_id as u8, + ); + // TODO(aldenhu): iterator of refs + let updates = { + let _timer = + OTHER_TIMERS_SECONDS.timer_with(&["hash_jmt_updates"]); + + updates + .iter() + .map(|(k, w)| { + ( + CryptoHash::hash(&k), + w.value.map(|v| (CryptoHash::hash(&v), k)), + ) + }) + .collect_vec() + }; + self.state_db.state_merkle_db.merklize_value_set_for_shard( - shard_id, - jmt_update_refs(&jmt_updates( - &delta_to_commit.updates_since_base.shards - [shard_id as usize] - .iter() - .map(|(k, v)| (k, v.as_ref())) - .collect(), - )), + shard_id as u8, + jmt_update_refs(&updates), Some(&node_hashes), version, base_version, - shard_persisted_versions[shard_id as usize], + shard_persisted_versions[shard_id], previous_epoch_ending_version, ) }) @@ -130,9 +151,8 @@ impl StateSnapshotCommitter { }; let (root_hash, top_levels_batch) = { - let _timer = OTHER_TIMERS_SECONDS - .with_label_values(&["calculate_top_levels_batch"]) - .start_timer(); + let _timer = + OTHER_TIMERS_SECONDS.timer_with(&["calculate_top_levels_batch"]); self.state_db .state_merkle_db .calculate_top_levels( @@ -143,13 +163,21 @@ impl StateSnapshotCommitter { ) .expect("Error calculating StateMerkleBatch for top levels.") }; + assert_eq!( + root_hash, + snapshot.summary().root_hash(), + "root hash mismatch: jmt: {}, smt: {}", + root_hash, + snapshot.summary().root_hash(), + ); + + self.last_snapshot = snapshot.clone(); self.state_merkle_batch_commit_sender .send(CommitMessage::Data(StateMerkleBatch { top_levels_batch, batches_for_shards, - root_hash, - state_delta: delta_to_commit, + snapshot, })) .unwrap(); }, diff --git a/storage/aptosdb/src/state_store/state_store_test.rs b/storage/aptosdb/src/state_store/state_store_test.rs index 2308deb9d97f5..c96eaa4123ab5 100644 --- a/storage/aptosdb/src/state_store/state_store_test.rs +++ b/storage/aptosdb/src/state_store/state_store_test.rs @@ -4,19 +4,16 @@ use super::*; use crate::{ - db::test_helper::{arb_state_kv_sets, update_store}, + db::test_helper::{arb_state_kv_sets_with_genesis, update_store}, schema::jellyfish_merkle_node::JellyfishMerkleNodeSchema, state_restore::StateSnapshotRestore, - utils::new_sharded_kv_schema_batch, AptosDB, }; use aptos_jellyfish_merkle::{ node_type::{Node, NodeKey}, TreeReader, }; -use aptos_storage_interface::{ - jmt_update_refs, jmt_updates, DbReader, DbWriter, StateSnapshotReceiver, -}; +use aptos_storage_interface::{DbReader, DbWriter, StateSnapshotReceiver}; use aptos_temppath::TempPath; use aptos_types::{ account_address::AccountAddress, @@ -25,54 +22,15 @@ use aptos_types::{ state_store::state_key::inner::StateKeyTag, AptosCoinType, }; -use arr_macro::arr; use proptest::{collection::hash_map, prelude::*}; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; fn put_value_set( state_store: &StateStore, value_set: Vec<(StateKey, StateValue)>, version: Version, - base_version: Option, ) -> HashValue { - let mut sharded_value_set = arr![HashMap::new(); 16]; - let value_set: HashMap<_, _> = value_set - .iter() - .map(|(key, value)| { - sharded_value_set[key.get_shard_id() as usize].insert(key.clone(), Some(value.clone())); - (key, Some(value)) - }) - .collect(); - let jmt_updates = jmt_updates(&value_set); - - let root = state_store - .merklize_value_set(jmt_update_refs(&jmt_updates), version, base_version) - .unwrap(); - let ledger_batch = SchemaBatch::new(); - let sharded_state_kv_batches = new_sharded_kv_schema_batch(); - let state_kv_metadata_batch = SchemaBatch::new(); - state_store - .put_value_sets( - version, - &ShardedStateUpdateRefs::index_per_version_updates([value_set.clone().into_iter()], 1), - StateStorageUsage::new_untracked(), - None, - &ledger_batch, - &sharded_state_kv_batches, - /*put_state_value_indices=*/ false, - /*last_checkpoint_index=*/ None, - ) - .unwrap(); - state_store - .ledger_db - .metadata_db() - .write_schemas(ledger_batch) - .unwrap(); - state_store - .state_kv_db - .commit(version, state_kv_metadata_batch, sharded_state_kv_batches) - .unwrap(); - root + state_store.commit_block_for_test(version, [value_set.into_iter().map(|(k, v)| (k, Some(v)))]) } fn verify_value_and_proof( @@ -140,7 +98,6 @@ fn test_state_store_reader_writer() { store, vec![(key1.clone(), value1.clone())], 0, /* version */ - None, ); verify_value_and_proof(store, key1.clone(), Some(&value1), 0, root); @@ -158,7 +115,6 @@ fn test_state_store_reader_writer() { (key3.clone(), value3.clone()), ], 1, /* version */ - Some(0), ); verify_value_and_proof(store, key1, Some(&value1_update), 1, root); @@ -209,7 +165,6 @@ fn test_get_values_by_key_prefix() { (key2.clone(), value2_v0.clone()), ], 0, - None, ); let key_value_map = traverse_values(store, &account_key_prefix, 0); @@ -229,7 +184,6 @@ fn test_get_values_by_key_prefix() { (key4.clone(), value4_v1.clone()), ], 1, - Some(0), ); // Ensure that we still get only values for key1 and key2 for version 0 after the update @@ -252,7 +206,7 @@ fn test_get_values_by_key_prefix() { let account1_key_prefix = StateKeyPrefix::new(StateKeyTag::AccessPath, address1.to_vec()); - put_value_set(store, vec![(key5.clone(), value5_v2.clone())], 2, Some(1)); + put_value_set(store, vec![(key5.clone(), value5_v2.clone())], 2); // address1 did not exist in version 0 and 1. let key_value_map = traverse_values(store, &account1_key_prefix, 0); @@ -275,19 +229,18 @@ pub fn test_get_state_snapshot_before() { // Empty store assert_eq!(store.get_state_snapshot_before(0).unwrap(), None,); - // put in genesis - let kv = vec![(StateKey::raw(b"key"), StateValue::from(b"value".to_vec()))]; - let hash = put_value_set(store, kv.clone(), 0, None); + // put in genesis (version 0) + let kv = vec![( + StateKey::raw(b"key"), + Some(StateValue::from(b"value".to_vec())), + )]; + let hash = store.commit_block_for_test(0, [kv.clone()]); assert_eq!(store.get_state_snapshot_before(0).unwrap(), None); assert_eq!(store.get_state_snapshot_before(1).unwrap(), Some((0, hash))); assert_eq!(store.get_state_snapshot_before(2).unwrap(), Some((0, hash))); - // hack: VersionData expected on every version, so duplicate the data at version 1 - let usage = store.get_usage(Some(0)).unwrap(); - db.ledger_db.metadata_db().put_usage(1, usage).unwrap(); - - // put in another version - put_value_set(store, kv, 2, Some(0)); + // put in snapshot at version 2 + let hash = store.commit_block_for_test(1, [vec![], kv]); assert_eq!(store.get_state_snapshot_before(4).unwrap(), Some((2, hash))); assert_eq!(store.get_state_snapshot_before(3).unwrap(), Some((2, hash))); assert_eq!(store.get_state_snapshot_before(2).unwrap(), Some((0, hash))); @@ -298,7 +251,7 @@ pub fn test_get_state_snapshot_before() { // Here we are adding another non-root node, and removing the root node, to verify if there is // a node at version X but the root node at version X doesn't exist, we shouldn't return // version X. - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch .put::( &NodeKey::new(2, NibblePath::new_odd(vec![0])), @@ -317,7 +270,7 @@ pub fn test_get_state_snapshot_before() { Some(2) ); - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); batch .delete::(&NodeKey::new_empty_path(2)) .unwrap(); @@ -339,30 +292,33 @@ proptest! { #[test] fn test_get_account_iter( - input in hash_map(any::(), any::(), 1..200) + kvs_per_version in arb_state_kv_sets_with_genesis(5, 3, 5) ) { - // Convert to a vector so iteration order becomes deterministic. - let kvs: Vec<_> = input.into_iter().collect(); - let tmp_dir = TempPath::new(); let db = AptosDB::new_for_test(&tmp_dir); let store = &db.state_store; - init_store(store, kvs.clone().into_iter()); + for (ver, kvs) in kvs_per_version.iter().cloned().enumerate() { + store.commit_block_for_test(ver as Version, [kvs]); + } + // Ordered by key hash, tracking the latest state (None if deleted) + let mut expected: BTreeMap> = BTreeMap::new(); // Test iterator at each version. - for i in 0..kvs.len() { - let actual_values = db + for (ver, kvs) in kvs_per_version.into_iter().enumerate() { + expected.extend(kvs.into_iter().map(|(k, v)| (k.hash(), v.map(|v| (k, v))))); + let actual = db .get_backup_handler() - .get_state_item_iter(i as Version, 0, usize::MAX) + .get_state_item_iter(ver as Version, 0, usize::MAX) .unwrap() .collect::>>() .unwrap(); - let mut expected_values: Vec<_> = kvs[..=i] - .iter() - .map(|(key, value)| (key.clone(), value.clone())) - .collect(); - expected_values.sort_unstable_by_key(|item| item.0.hash()); - prop_assert_eq!(actual_values, expected_values); + + prop_assert!( + itertools::equal( + actual.iter(), + expected.iter().filter_map(|(_h, kv)| kv.as_ref()) + ) + ); } } @@ -475,7 +431,7 @@ proptest! { let tmp_dir1 = TempPath::new(); let db1 = AptosDB::new_for_test_with_sharding(&tmp_dir1, 1000); let store1 = &db1.state_store; - init_sharded_store(store1, input.clone().into_iter()); + init_store(store1, input.clone().into_iter()); let version = (input.len() - 1) as Version; let expected_root_hash = store1.get_root_hash(version).unwrap(); @@ -568,7 +524,7 @@ proptest! { #[test] fn test_get_usage( - input in arb_state_kv_sets(10, 5, 5) + input in arb_state_kv_sets_with_genesis(5, 3, 5) ) { let tmp_dir = TempPath::new(); let db = AptosDB::new_for_test(&tmp_dir); @@ -577,7 +533,7 @@ proptest! { let mut version = 0; for batch in input { let next_version = version + batch.len() as Version; - let root_hash = update_store(store, batch.into_iter(), version, false); + let root_hash = update_store(store, batch.into_iter(), version); let last_version = next_version - 1; let snapshot = db @@ -625,14 +581,5 @@ proptest! { // Initializes the state store by inserting one key at each version. fn init_store(store: &StateStore, input: impl Iterator) { - update_store( - store, - input.into_iter().map(|(k, v)| (k, Some(v))), - 0, - false, - ); -} - -fn init_sharded_store(store: &StateStore, input: impl Iterator) { - update_store(store, input.into_iter().map(|(k, v)| (k, Some(v))), 0, true); + update_store(store, input.into_iter().map(|(k, v)| (k, Some(v))), 0); } diff --git a/storage/aptosdb/src/transaction_store/mod.rs b/storage/aptosdb/src/transaction_store/mod.rs index cb7e15a1ee1a1..a95c8b11b2870 100644 --- a/storage/aptosdb/src/transaction_store/mod.rs +++ b/storage/aptosdb/src/transaction_store/mod.rs @@ -9,7 +9,7 @@ use aptos_db_indexer_schemas::{ schema::transaction_by_account::TransactionByAccountSchema, utils::AccountTransactionVersionIter, }; -use aptos_schemadb::SchemaBatch; +use aptos_schemadb::batch::SchemaBatch; use aptos_storage_interface::{AptosDbError, Result}; use aptos_types::{ account_address::AccountAddress, @@ -82,7 +82,7 @@ impl TransactionStore { pub fn prune_transaction_by_account( &self, transactions: &[Transaction], - db_batch: &SchemaBatch, + db_batch: &mut SchemaBatch, ) -> Result<()> { for transaction in transactions { if let Some(txn) = transaction.try_as_signed_user_txn() { diff --git a/storage/aptosdb/src/utils/mod.rs b/storage/aptosdb/src/utils/mod.rs index ac8d76901ddb9..7bdfb3b53fba8 100644 --- a/storage/aptosdb/src/utils/mod.rs +++ b/storage/aptosdb/src/utils/mod.rs @@ -5,19 +5,14 @@ pub mod iterators; pub(crate) mod truncation_helper; use crate::schema::db_metadata::{DbMetadataKey, DbMetadataSchema}; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::NativeBatch, DB}; use aptos_storage_interface::{state_store::NUM_STATE_SHARDS, Result}; use aptos_types::transaction::Version; -use arr_macro::arr; -pub(crate) type ShardedStateKvSchemaBatch = [SchemaBatch; NUM_STATE_SHARDS]; +pub(crate) type ShardedStateKvSchemaBatch<'db> = [NativeBatch<'db>; NUM_STATE_SHARDS]; pub(crate) fn get_progress(db: &DB, progress_key: &DbMetadataKey) -> Result> { Ok(db .get::(progress_key)? .map(|v| v.expect_version())) } - -pub(crate) fn new_sharded_kv_schema_batch() -> ShardedStateKvSchemaBatch { - arr![SchemaBatch::new(); 16] -} diff --git a/storage/aptosdb/src/utils/truncation_helper.rs b/storage/aptosdb/src/utils/truncation_helper.rs index 72a330cabe5ca..a3edf7580ab9c 100644 --- a/storage/aptosdb/src/utils/truncation_helper.rs +++ b/storage/aptosdb/src/utils/truncation_helper.rs @@ -32,8 +32,9 @@ use crate::{ use aptos_jellyfish_merkle::{node_type::NodeKey, StaleNodeIndex}; use aptos_logger::info; use aptos_schemadb::{ + batch::SchemaBatch, schema::{Schema, SeekKeyCodec}, - SchemaBatch, DB, + DB, }; use aptos_storage_interface::Result; use aptos_types::{proof::position::Position, transaction::Version}; @@ -125,11 +126,11 @@ pub(crate) fn truncate_state_kv_db_single_shard( shard_id: u8, target_version: Version, ) -> Result<()> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); delete_state_value_and_index( state_kv_db.db_shard(shard_id), target_version + 1, - &batch, + &mut batch, state_kv_db.enabled_sharding(), )?; state_kv_db.commit_single_shard(target_version, shard_id, batch) @@ -156,12 +157,13 @@ pub(crate) fn truncate_state_merkle_db( )? .expect("Must exist."); - let top_levels_batch = SchemaBatch::new(); + let mut top_levels_batch = SchemaBatch::new(); delete_nodes_and_stale_indices_at_or_after_version( state_merkle_db.metadata_db(), current_version, - &top_levels_batch, + None, // shard_id + &mut top_levels_batch, )?; state_merkle_db.commit_top_levels(version_before, top_levels_batch)?; @@ -188,13 +190,14 @@ pub(crate) fn truncate_state_merkle_db_single_shard( shard_id: u8, target_version: Version, ) -> Result<()> { - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); delete_nodes_and_stale_indices_at_or_after_version( state_merkle_db.db_shard(shard_id), target_version + 1, - &batch, + Some(shard_id), + &mut batch, )?; - state_merkle_db.commit_single_shard(target_version, shard_id, batch) + state_merkle_db.db_shard(shard_id).write_schemas(batch) } pub(crate) fn find_tree_root_at_or_before( @@ -288,7 +291,7 @@ pub(crate) fn num_frozen_nodes_in_accumulator(num_leaves: u64) -> u64 { fn truncate_transaction_accumulator( transaction_accumulator_db: &DB, start_version: Version, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> { let mut iter = transaction_accumulator_db.iter::()?; iter.seek_to_last(); @@ -316,30 +319,30 @@ fn truncate_ledger_db_single_batch( transaction_store: &TransactionStore, start_version: Version, ) -> Result<()> { - let batch = LedgerDbSchemaBatches::new(); + let mut batch = LedgerDbSchemaBatches::new(); delete_transaction_index_data( ledger_db, transaction_store, start_version, - &batch.transaction_db_batches, + &mut batch.transaction_db_batches, )?; delete_per_epoch_data( &ledger_db.metadata_db_arc(), start_version, - &batch.ledger_metadata_db_batches, + &mut batch.ledger_metadata_db_batches, )?; - delete_per_version_data(ledger_db, start_version, &batch)?; + delete_per_version_data(ledger_db, start_version, &mut batch)?; - delete_event_data(ledger_db, start_version, &batch.event_db_batches)?; + delete_event_data(ledger_db, start_version, &mut batch.event_db_batches)?; truncate_transaction_accumulator( ledger_db.transaction_accumulator_db_raw(), start_version, - &batch.transaction_accumulator_db_batches, + &mut batch.transaction_accumulator_db_batches, )?; - let progress_batch = SchemaBatch::new(); + let mut progress_batch = SchemaBatch::new(); progress_batch.put::( &DbMetadataKey::LedgerCommitProgress, &DbMetadataValue::Version(start_version - 1), @@ -353,7 +356,7 @@ fn delete_transaction_index_data( ledger_db: &LedgerDb, transaction_store: &TransactionStore, start_version: Version, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> { let transactions = ledger_db .transaction_db() @@ -378,7 +381,7 @@ fn delete_transaction_index_data( fn delete_per_epoch_data( ledger_db: &DB, start_version: Version, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> { let mut iter = ledger_db.iter::()?; iter.seek_to_last(); @@ -414,32 +417,32 @@ fn delete_per_epoch_data( fn delete_per_version_data( ledger_db: &LedgerDb, start_version: Version, - batch: &LedgerDbSchemaBatches, + batch: &mut LedgerDbSchemaBatches, ) -> Result<()> { delete_per_version_data_impl::( ledger_db.transaction_accumulator_db_raw(), start_version, - &batch.transaction_accumulator_db_batches, + &mut batch.transaction_accumulator_db_batches, )?; delete_per_version_data_impl::( ledger_db.transaction_info_db_raw(), start_version, - &batch.transaction_info_db_batches, + &mut batch.transaction_info_db_batches, )?; delete_per_version_data_impl::( ledger_db.transaction_db_raw(), start_version, - &batch.transaction_db_batches, + &mut batch.transaction_db_batches, )?; delete_per_version_data_impl::( &ledger_db.metadata_db_arc(), start_version, - &batch.ledger_metadata_db_batches, + &mut batch.ledger_metadata_db_batches, )?; delete_per_version_data_impl::( ledger_db.write_set_db_raw(), start_version, - &batch.write_set_db_batches, + &mut batch.write_set_db_batches, )?; Ok(()) @@ -448,7 +451,7 @@ fn delete_per_version_data( fn delete_per_version_data_impl( ledger_db: &DB, start_version: Version, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> where S: Schema, @@ -474,7 +477,7 @@ where fn delete_event_data( ledger_db: &LedgerDb, start_version: Version, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> { if let Some(latest_version) = ledger_db.event_db().latest_version()? { if latest_version >= start_version { @@ -483,15 +486,20 @@ fn delete_event_data( latest_version = latest_version, "Truncate event data." ); - ledger_db.event_db().prune_events( + let num_events_per_version = ledger_db.event_db().prune_event_indices( start_version, latest_version + 1, - batch, // Assuming same data will be overwritten into indices, we don't bother to deal // with the existence or placement of indices // TODO: prune data from internal indices None, )?; + ledger_db.event_db().prune_events( + num_events_per_version, + start_version, + latest_version + 1, + batch, + )?; } } Ok(()) @@ -500,7 +508,7 @@ fn delete_event_data( fn delete_state_value_and_index( state_kv_db_shard: &DB, start_version: Version, - batch: &SchemaBatch, + batch: &mut SchemaBatch, enable_sharding: bool, ) -> Result<()> { if enable_sharding { @@ -532,7 +540,7 @@ fn delete_state_value_and_index( fn delete_stale_node_index_at_or_after_version( db: &DB, version: Version, - batch: &SchemaBatch, + batch: &mut SchemaBatch, ) -> Result<()> where S: Schema, @@ -552,7 +560,8 @@ where fn delete_nodes_and_stale_indices_at_or_after_version( db: &DB, version: Version, - batch: &SchemaBatch, + shard_id: Option, + batch: &mut SchemaBatch, ) -> Result<()> { delete_stale_node_index_at_or_after_version::(db, version, batch)?; delete_stale_node_index_at_or_after_version::( @@ -566,7 +575,7 @@ fn delete_nodes_and_stale_indices_at_or_after_version( batch.delete::(&key)?; } - Ok(()) + StateMerkleDb::put_progress(version.checked_sub(1), shard_id, batch) } struct Progress { diff --git a/storage/backup/backup-cli/src/backup_types/transaction/restore.rs b/storage/backup/backup-cli/src/backup_types/transaction/restore.rs index dbd94a1f61cc2..607271f34f73f 100644 --- a/storage/backup/backup-cli/src/backup_types/transaction/restore.rs +++ b/storage/backup/backup-cli/src/backup_types/transaction/restore.rs @@ -513,6 +513,8 @@ impl TransactionRestoreBatchController { >, ) -> Result<()> { let (first_version, _) = self.replay_from_version.unwrap(); + restore_handler.force_state_version_for_kv_restore(first_version.checked_sub(1))?; + let mut base_version = first_version; let mut offset = 0u64; let replay_start = Instant::now(); diff --git a/storage/backup/backup-cli/src/utils/test_utils.rs b/storage/backup/backup-cli/src/utils/test_utils.rs index a5a9a9102743f..626932ecdf984 100644 --- a/storage/backup/backup-cli/src/utils/test_utils.rs +++ b/storage/backup/backup-cli/src/utils/test_utils.rs @@ -4,12 +4,8 @@ use aptos_backup_service::start_backup_service; use aptos_config::utils::get_available_port; -use aptos_db::{ - db::test_helper::{arb_blocks_to_commit, update_in_memory_state}, - AptosDB, -}; +use aptos_db::{db::test_helper::arb_blocks_to_commit, AptosDB}; use aptos_proptest_helpers::ValueGenerator; -use aptos_storage_interface::DbReader; use aptos_temppath::TempPath; use aptos_types::{ ledger_info::LedgerInfoWithSignatures, @@ -35,23 +31,13 @@ pub fn tmp_db_with_random_content() -> ( ) { let (tmpdir, db) = tmp_db_empty(); let mut cur_ver: Version = 0; - let mut in_memory_state = db - .get_pre_committed_ledger_summary() - .unwrap() - .state - .as_ref() - .clone(); - let _ancestor = in_memory_state.base.clone(); let blocks = ValueGenerator::new().generate(arb_blocks_to_commit()); for (txns_to_commit, ledger_info_with_sigs) in &blocks { - update_in_memory_state(&mut in_memory_state, txns_to_commit.as_slice()); db.save_transactions_for_test( txns_to_commit, cur_ver, /* first_version */ - cur_ver.checked_sub(1), Some(ledger_info_with_sigs), true, /* sync_commit */ - &in_memory_state, ) .unwrap(); cur_ver += txns_to_commit.len() as u64; diff --git a/storage/db-tool/src/bootstrap.rs b/storage/db-tool/src/bootstrap.rs index 9557ee076dceb..0cf63f1aabfdc 100644 --- a/storage/db-tool/src/bootstrap.rs +++ b/storage/db-tool/src/bootstrap.rs @@ -66,13 +66,13 @@ impl Command { .reader .get_pre_committed_ledger_summary() .with_context(|| format_err!("Failed to get latest tree state."))?; - println!("Db has {} transactions", ledger_summary.num_transactions()); + println!("Db has {} transactions", ledger_summary.next_version()); if let Some(waypoint) = self.waypoint_to_verify { ensure!( - waypoint.version() == ledger_summary.num_transactions(), + waypoint.version() == ledger_summary.next_version(), "Trying to generate waypoint at version {}, but DB has {} transactions.", waypoint.version(), - ledger_summary.num_transactions(), + ledger_summary.next_version(), ) } diff --git a/storage/indexer/src/db_indexer.rs b/storage/indexer/src/db_indexer.rs index bea35ad596415..13af504bb7bf3 100644 --- a/storage/indexer/src/db_indexer.rs +++ b/storage/indexer/src/db_indexer.rs @@ -21,7 +21,7 @@ use aptos_db_indexer_schemas::{ }, }; use aptos_logger::warn; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::{ db_ensure as ensure, db_other_bail as bail, AptosDbError, DbReader, Result, }; @@ -93,7 +93,7 @@ impl InternalIndexerDB { progress: StateSnapshotProgress, ) -> Result<()> { // add state value to internal indexer - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); for state_key in keys { batch.put::(state_key, &())?; } @@ -413,7 +413,7 @@ impl DBIndexer { let num_transactions = self.get_num_of_transactions(version, end_version)?; // This promises num_transactions should be readable from main db let mut db_iter = self.get_main_db_iter(version, num_transactions)?; - let batch = SchemaBatch::new(); + let mut batch = SchemaBatch::new(); let mut event_keys: HashSet = HashSet::new(); db_iter.try_for_each(|res| { let (txn, events, writeset) = res?; diff --git a/storage/indexer/src/db_v2.rs b/storage/indexer/src/db_v2.rs index fae7813789d5a..d3ce01c7f9695 100644 --- a/storage/indexer/src/db_v2.rs +++ b/storage/indexer/src/db_v2.rs @@ -11,7 +11,7 @@ use aptos_db_indexer_schemas::{ }; use aptos_logger::info; use aptos_resource_viewer::{AnnotatedMoveValue, AptosValueAnnotator}; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::{ db_other_bail as bail, state_store::state_view::db_state_view::DbStateViewAtVersion, AptosDbError, DbReader, Result, diff --git a/storage/indexer/src/lib.rs b/storage/indexer/src/lib.rs index 86229a0ff26ae..4e27c75d22e59 100644 --- a/storage/indexer/src/lib.rs +++ b/storage/indexer/src/lib.rs @@ -22,7 +22,7 @@ use aptos_db_indexer_schemas::{ use aptos_logger::warn; use aptos_resource_viewer::{AnnotatedMoveValue, AptosValueAnnotator}; use aptos_rocksdb_options::gen_rocksdb_options; -use aptos_schemadb::{SchemaBatch, DB}; +use aptos_schemadb::{batch::SchemaBatch, DB}; use aptos_storage_interface::{ db_ensure, db_other_bail, state_store::state_view::db_state_view::DbStateViewAtVersion, AptosDbError, DbReader, Result, diff --git a/storage/jellyfish-merkle/src/iterator/mod.rs b/storage/jellyfish-merkle/src/iterator/mod.rs index 7c996c1baa29c..2a55db62a9b73 100644 --- a/storage/jellyfish-merkle/src/iterator/mod.rs +++ b/storage/jellyfish-merkle/src/iterator/mod.rs @@ -171,7 +171,7 @@ where match reader.get_node(¤t_node_key)? { Node::Internal(_) => unreachable!("Should have reached the bottom of the tree."), Node::Leaf(leaf_node) => { - if leaf_node.account_key() < starting_key { + if leaf_node.account_key() < &starting_key { Self::cleanup_stack(&mut parent_stack); if parent_stack.is_empty() { done = true; @@ -296,7 +296,7 @@ where // None. self.done = true; return Some(Ok(( - leaf_node.account_key(), + *leaf_node.account_key(), leaf_node.value_index().clone(), ))); }, @@ -333,7 +333,7 @@ where self.parent_stack.push(visit_info); }, Ok(Node::Leaf(leaf_node)) => { - let ret = (leaf_node.account_key(), leaf_node.value_index().clone()); + let ret = (*leaf_node.account_key(), leaf_node.value_index().clone()); Self::cleanup_stack(&mut self.parent_stack); return Some(Ok(ret)); }, diff --git a/storage/jellyfish-merkle/src/lib.rs b/storage/jellyfish-merkle/src/lib.rs index 0dfe8bd964305..557c224ad10cd 100644 --- a/storage/jellyfish-merkle/src/lib.rs +++ b/storage/jellyfish-merkle/src/lib.rs @@ -709,13 +709,13 @@ where key: HashValue, version: Version, ) -> Result<(Option<(HashValue, (K, Version))>, SparseMerkleProof)> { - self.get_with_proof_ext(key, version, 0) + self.get_with_proof_ext(&key, version, 0) .map(|(value, proof_ext)| (value, proof_ext.into())) } pub fn get_with_proof_ext( &self, - key: HashValue, + key: &HashValue, version: Version, target_root_depth: usize, ) -> Result<(Option<(HashValue, (K, Version))>, SparseMerkleProofExt)> { @@ -975,7 +975,7 @@ where { let existing_leaf_key = existing_leaf_node.account_key(); - if kvs.len() == 1 && kvs[0].0 == existing_leaf_key { + if kvs.len() == 1 && &kvs[0].0 == existing_leaf_key { if let (key, Some((value_hash, state_key))) = kvs[0] { let new_leaf_node = Node::new_leaf(key, *value_hash, (state_key.clone(), version)); Ok(Some(new_leaf_node)) diff --git a/storage/jellyfish-merkle/src/node_type/mod.rs b/storage/jellyfish-merkle/src/node_type/mod.rs index 2fb0b33ad7565..31f375ccdadc2 100644 --- a/storage/jellyfish-merkle/src/node_type/mod.rs +++ b/storage/jellyfish-merkle/src/node_type/mod.rs @@ -719,8 +719,8 @@ where } /// Gets the account key, the hashed account address. - pub fn account_key(&self) -> HashValue { - self.account_key + pub fn account_key(&self) -> &HashValue { + &self.account_key } /// Gets the associated value hash. diff --git a/storage/jellyfish-merkle/src/restore/mod.rs b/storage/jellyfish-merkle/src/restore/mod.rs index 673bd95de1655..2a66df585ef5a 100644 --- a/storage/jellyfish-merkle/src/restore/mod.rs +++ b/storage/jellyfish-merkle/src/restore/mod.rs @@ -259,7 +259,7 @@ where // Hack: prevent any chunk to be added. Some(HashValue::new([0xFF; HashValue::LENGTH])) } else { - self.previous_leaf.as_ref().map(|leaf| leaf.account_key()) + self.previous_leaf.as_ref().map(|leaf| *leaf.account_key()) } } @@ -350,7 +350,7 @@ where if let Some(prev_leaf) = &self.previous_leaf { let skip_until = chunk .iter() - .find_position(|(key, _hash)| key.hash() > prev_leaf.account_key()); + .find_position(|(key, _hash)| key.hash() > *prev_leaf.account_key()); chunk = match skip_until { None => { info!("Skipping entire chunk."); @@ -375,7 +375,7 @@ where let hashed_key = key.hash(); if let Some(ref prev_leaf) = self.previous_leaf { ensure!( - hashed_key > prev_leaf.account_key(), + &hashed_key > prev_leaf.account_key(), "State keys must come in increasing order.", ) } @@ -691,7 +691,7 @@ where proof .verify( self.expected_root_hash, - SparseMerkleLeafNode::new(previous_key, previous_leaf.value_hash()), + SparseMerkleLeafNode::new(*previous_key, previous_leaf.value_hash()), left_siblings, ) .map_err(Into::into) diff --git a/storage/schemadb/Cargo.toml b/storage/schemadb/Cargo.toml index d97fb51caca5a..bf676d3880ac2 100644 --- a/storage/schemadb/Cargo.toml +++ b/storage/schemadb/Cargo.toml @@ -14,7 +14,7 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } -aptos-infallible = { workspace = true } +aptos-drop-helper = { workspace = true } aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } aptos-storage-interface = { workspace = true } diff --git a/storage/schemadb/src/batch.rs b/storage/schemadb/src/batch.rs new file mode 100644 index 0000000000000..6f0921f478f00 --- /dev/null +++ b/storage/schemadb/src/batch.rs @@ -0,0 +1,254 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + metrics::{APTOS_SCHEMADB_DELETES_SAMPLED, APTOS_SCHEMADB_PUT_BYTES_SAMPLED, TIMER}, + schema::{KeyCodec, Schema, ValueCodec}, + ColumnFamilyName, DB, +}; +use aptos_drop_helper::DropHelper; +use aptos_metrics_core::TimerHelper; +use aptos_storage_interface::Result as DbResult; +use std::{ + collections::HashMap, + fmt::{Debug, Formatter}, +}; + +#[derive(Debug, Default)] +pub struct BatchStats { + put_sizes: HashMap>, + num_deletes: HashMap, +} + +impl BatchStats { + fn put(&mut self, cf_name: ColumnFamilyName, size: usize) { + self.put_sizes.entry(cf_name).or_default().push(size); + } + + fn delete(&mut self, cf_name: ColumnFamilyName) { + *self.num_deletes.entry(cf_name).or_default() += 1 + } + + fn commit(&self) { + for (cf_name, put_sizes) in &self.put_sizes { + for put_size in put_sizes { + APTOS_SCHEMADB_PUT_BYTES_SAMPLED + .with_label_values(&[cf_name]) + .observe(*put_size as f64); + } + } + for (cf_name, num_deletes) in &self.num_deletes { + APTOS_SCHEMADB_DELETES_SAMPLED + .with_label_values(&[cf_name]) + .inc_by(*num_deletes as u64); + } + } +} + +#[derive(Debug)] +pub struct SampledBatchStats { + inner: Option, +} + +impl SampledBatchStats { + pub fn put(&mut self, cf_name: ColumnFamilyName, size: usize) { + if let Some(inner) = self.inner.as_mut() { + inner.put(cf_name, size) + } + } + + pub fn delete(&mut self, cf_name: ColumnFamilyName) { + if let Some(inner) = self.inner.as_mut() { + inner.delete(cf_name) + } + } + + pub fn commit(&self) { + if let Some(inner) = self.inner.as_ref() { + inner.commit() + } + } +} + +impl Default for SampledBatchStats { + fn default() -> Self { + const SAMPLING_PCT: usize = 1; + + Self { + inner: (rand::random::() % 100 < SAMPLING_PCT).then_some(Default::default()), + } + } +} + +#[derive(Default)] +pub struct RawBatch { + pub inner: rocksdb::WriteBatch, + pub stats: SampledBatchStats, +} + +pub trait IntoRawBatch { + fn into_raw_batch(self, db: &DB) -> DbResult; +} + +impl IntoRawBatch for RawBatch { + fn into_raw_batch(self, _db: &DB) -> DbResult { + Ok(self) + } +} + +pub trait WriteBatch: IntoRawBatch { + fn stats(&mut self) -> &mut SampledBatchStats; + + /// Adds an insert/update operation to the batch. + fn put(&mut self, key: &S::Key, value: &S::Value) -> DbResult<()> { + let key = >::encode_key(key)?; + let value = >::encode_value(value)?; + + self.stats() + .put(S::COLUMN_FAMILY_NAME, key.len() + value.len()); + self.raw_put(S::COLUMN_FAMILY_NAME, key, value) + } + + fn raw_put(&mut self, cf_name: ColumnFamilyName, key: Vec, value: Vec) -> DbResult<()>; + + /// Adds a delete operation to the batch. + fn delete(&mut self, key: &S::Key) -> DbResult<()> { + let key = >::encode_key(key)?; + + self.stats().delete(S::COLUMN_FAMILY_NAME); + self.raw_delete(S::COLUMN_FAMILY_NAME, key) + } + + fn raw_delete(&mut self, cf_name: ColumnFamilyName, key: Vec) -> DbResult<()>; +} + +#[derive(Debug)] +pub enum WriteOp { + Value { key: Vec, value: Vec }, + Deletion { key: Vec }, +} + +/// `SchemaBatch` holds a collection of updates that can be applied to a DB atomically. The updates +/// will be applied in the order in which they are added to the `SchemaBatch`. +#[derive(Debug, Default)] +pub struct SchemaBatch { + rows: DropHelper>>, + stats: SampledBatchStats, +} + +impl SchemaBatch { + /// Creates an empty batch. + pub fn new() -> Self { + Self::default() + } + + /// keep these on the struct itself so that we don't need to update each call site. + pub fn put(&mut self, key: &S::Key, value: &S::Value) -> DbResult<()> { + ::put::(self, key, value) + } + + pub fn delete(&mut self, key: &S::Key) -> DbResult<()> { + ::delete::(self, key) + } +} + +impl WriteBatch for SchemaBatch { + fn stats(&mut self) -> &mut SampledBatchStats { + &mut self.stats + } + + fn raw_put(&mut self, cf_name: ColumnFamilyName, key: Vec, value: Vec) -> DbResult<()> { + self.rows + .entry(cf_name) + .or_default() + .push(WriteOp::Value { key, value }); + + Ok(()) + } + + fn raw_delete(&mut self, cf_name: ColumnFamilyName, key: Vec) -> DbResult<()> { + self.rows + .entry(cf_name) + .or_default() + .push(WriteOp::Deletion { key }); + + Ok(()) + } +} + +impl IntoRawBatch for SchemaBatch { + fn into_raw_batch(self, db: &DB) -> DbResult { + let _timer = TIMER.timer_with(&["schema_batch_to_raw_batch", &db.name]); + + let Self { rows, stats } = self; + + let mut db_batch = rocksdb::WriteBatch::default(); + for (cf_name, rows) in rows.iter() { + let cf_handle = db.get_cf_handle(cf_name)?; + for write_op in rows { + match write_op { + WriteOp::Value { key, value } => db_batch.put_cf(cf_handle, key, value), + WriteOp::Deletion { key } => db_batch.delete_cf(cf_handle, key), + } + } + } + + Ok(RawBatch { + inner: db_batch, + stats, + }) + } +} + +/// Similar to SchemaBatch, but wraps around rocksdb::WriteBatch directly. +/// For that to work, a reference to the DB needs to be held. +pub struct NativeBatch<'db> { + db: &'db DB, + raw_batch: RawBatch, +} + +impl<'db> Debug for NativeBatch<'db> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "NativeBatch for DB {} ", self.db.name) + } +} + +impl<'db> NativeBatch<'db> { + /// Creates an empty batch. + pub fn new(db: &'db DB) -> Self { + Self { + db, + raw_batch: RawBatch::default(), + } + } +} + +impl<'db> WriteBatch for NativeBatch<'db> { + fn stats(&mut self) -> &mut SampledBatchStats { + &mut self.raw_batch.stats + } + + fn raw_put(&mut self, cf_name: ColumnFamilyName, key: Vec, value: Vec) -> DbResult<()> { + self.raw_batch + .inner + .put_cf(&self.db.get_cf_handle(cf_name)?, &key, &value); + + Ok(()) + } + + fn raw_delete(&mut self, cf_name: ColumnFamilyName, key: Vec) -> DbResult<()> { + self.raw_batch + .inner + .delete_cf(&self.db.get_cf_handle(cf_name)?, &key); + + Ok(()) + } +} + +impl<'db> IntoRawBatch for NativeBatch<'db> { + fn into_raw_batch(self, _db: &DB) -> DbResult { + let Self { db: _, raw_batch } = self; + + Ok(raw_batch) + } +} diff --git a/storage/schemadb/src/lib.rs b/storage/schemadb/src/lib.rs index a1ef74b9ce751..8422b7cbad11b 100644 --- a/storage/schemadb/src/lib.rs +++ b/storage/schemadb/src/lib.rs @@ -17,95 +17,33 @@ mod metrics; #[macro_use] pub mod schema; +pub mod batch; pub mod iterator; use crate::{ metrics::{ APTOS_SCHEMADB_BATCH_COMMIT_BYTES, APTOS_SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS, - APTOS_SCHEMADB_DELETES_SAMPLED, APTOS_SCHEMADB_GET_BYTES, - APTOS_SCHEMADB_GET_LATENCY_SECONDS, APTOS_SCHEMADB_ITER_BYTES, - APTOS_SCHEMADB_ITER_LATENCY_SECONDS, APTOS_SCHEMADB_PUT_BYTES_SAMPLED, - APTOS_SCHEMADB_SEEK_LATENCY_SECONDS, + APTOS_SCHEMADB_GET_BYTES, APTOS_SCHEMADB_GET_LATENCY_SECONDS, APTOS_SCHEMADB_ITER_BYTES, + APTOS_SCHEMADB_ITER_LATENCY_SECONDS, APTOS_SCHEMADB_SEEK_LATENCY_SECONDS, }, schema::{KeyCodec, Schema, SeekKeyCodec, ValueCodec}, }; use anyhow::format_err; -use aptos_infallible::Mutex; use aptos_logger::prelude::*; +use aptos_metrics_core::TimerHelper; use aptos_storage_interface::{AptosDbError, Result as DbResult}; +use batch::{IntoRawBatch, NativeBatch, WriteBatch}; use iterator::{ScanDirection, SchemaIterator}; -use rand::Rng; use rocksdb::ErrorKind; /// Type alias to `rocksdb::ReadOptions`. See [`rocksdb doc`](https://github.com/pingcap/rust-rocksdb/blob/master/src/rocksdb_options.rs) pub use rocksdb::{ BlockBasedOptions, Cache, ColumnFamilyDescriptor, DBCompressionType, Options, ReadOptions, SliceTransform, DEFAULT_COLUMN_FAMILY_NAME, }; -use std::{ - collections::{HashMap, HashSet}, - iter::Iterator, - path::Path, -}; +use std::{collections::HashSet, fmt::Debug, iter::Iterator, path::Path}; pub type ColumnFamilyName = &'static str; -#[derive(Debug)] -enum WriteOp { - Value { key: Vec, value: Vec }, - Deletion { key: Vec }, -} - -/// `SchemaBatch` holds a collection of updates that can be applied to a DB atomically. The updates -/// will be applied in the order in which they are added to the `SchemaBatch`. -#[derive(Debug)] -pub struct SchemaBatch { - rows: Mutex>>, -} - -impl Default for SchemaBatch { - fn default() -> Self { - Self { - rows: Mutex::new(HashMap::new()), - } - } -} - -impl SchemaBatch { - /// Creates an empty batch. - pub fn new() -> Self { - Self::default() - } - - /// Adds an insert/update operation to the batch. - pub fn put( - &self, - key: &S::Key, - value: &S::Value, - ) -> aptos_storage_interface::Result<()> { - let key = >::encode_key(key)?; - let value = >::encode_value(value)?; - self.rows - .lock() - .entry(S::COLUMN_FAMILY_NAME) - .or_default() - .push(WriteOp::Value { key, value }); - - Ok(()) - } - - /// Adds a delete operation to the batch. - pub fn delete(&self, key: &S::Key) -> DbResult<()> { - let key = >::encode_key(key)?; - self.rows - .lock() - .entry(S::COLUMN_FAMILY_NAME) - .or_default() - .push(WriteOp::Deletion { key }); - - Ok(()) - } -} - #[derive(Debug)] enum OpenMode<'a> { ReadWrite, @@ -265,10 +203,14 @@ impl DB { .map_err(Into::into) } + pub fn new_native_batch(&self) -> NativeBatch { + NativeBatch::new(self) + } + /// Writes single record. pub fn put(&self, key: &S::Key, value: &S::Value) -> DbResult<()> { // Not necessary to use a batch, but we'd like a central place to bump counters. - let batch = SchemaBatch::new(); + let mut batch = self.new_native_batch(); batch.put::(key, value)?; self.write_schemas(batch) } @@ -276,7 +218,7 @@ impl DB { /// Deletes a single record. pub fn delete(&self, key: &S::Key) -> DbResult<()> { // Not necessary to use a batch, but we'd like a central place to bump counters. - let batch = SchemaBatch::new(); + let mut batch = self.new_native_batch(); batch.delete::(key)?; self.write_schemas(batch) } @@ -314,59 +256,17 @@ impl DB { } /// Writes a group of records wrapped in a [`SchemaBatch`]. - pub fn write_schemas(&self, batch: SchemaBatch) -> DbResult<()> { - // Function to determine if the counter should be sampled based on a sampling percentage - fn should_sample(sampling_percentage: usize) -> bool { - // Generate a random number between 0 and 100 - let random_value = rand::thread_rng().gen_range(0, 100); - - // Sample the counter if the random value is less than the sampling percentage - random_value <= sampling_percentage - } + pub fn write_schemas(&self, batch: impl IntoRawBatch) -> DbResult<()> { + let _timer = APTOS_SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS.timer_with(&[&self.name]); - let _timer = APTOS_SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS - .with_label_values(&[&self.name]) - .start_timer(); - let rows_locked = batch.rows.lock(); - let sampling_rate_pct = 1; - let sampled_kv_bytes = should_sample(sampling_rate_pct); - - let mut db_batch = rocksdb::WriteBatch::default(); - for (cf_name, rows) in rows_locked.iter() { - let cf_handle = self.get_cf_handle(cf_name)?; - for write_op in rows { - match write_op { - WriteOp::Value { key, value } => db_batch.put_cf(cf_handle, key, value), - WriteOp::Deletion { key } => db_batch.delete_cf(cf_handle, key), - } - } - } - let serialized_size = db_batch.size_in_bytes(); + let raw_batch = batch.into_raw_batch(self)?; + let serialized_size = raw_batch.inner.size_in_bytes(); self.inner - .write_opt(db_batch, &default_write_options()) + .write_opt(raw_batch.inner, &default_write_options()) .into_db_res()?; - // Bump counters only after DB write succeeds. - if sampled_kv_bytes { - for (cf_name, rows) in rows_locked.iter() { - for write_op in rows { - match write_op { - WriteOp::Value { key, value } => { - APTOS_SCHEMADB_PUT_BYTES_SAMPLED - .with_label_values(&[cf_name]) - .observe((key.len() + value.len()) as f64); - }, - WriteOp::Deletion { key: _ } => { - APTOS_SCHEMADB_DELETES_SAMPLED - .with_label_values(&[cf_name]) - .inc(); - }, - } - } - } - } - + raw_batch.stats.commit(); APTOS_SCHEMADB_BATCH_COMMIT_BYTES .with_label_values(&[&self.name]) .observe(serialized_size as f64); diff --git a/storage/schemadb/src/metrics.rs b/storage/schemadb/src/metrics.rs index 4627a5b92995c..cbaf4f703ca4d 100644 --- a/storage/schemadb/src/metrics.rs +++ b/storage/schemadb/src/metrics.rs @@ -116,3 +116,13 @@ pub static APTOS_SCHEMADB_DELETES_SAMPLED: Lazy = Lazy::new(|| { ) .unwrap() }); + +pub static TIMER: Lazy = Lazy::new(|| { + register_histogram_vec!( + "aptos_schema_db_timer_seconds", + "Various timers for performance analysis.", + &["name", "sub_name"], + exponential_buckets(/*start=*/ 1e-9, /*factor=*/ 2.0, /*count=*/ 32).unwrap(), + ) + .unwrap() +}); diff --git a/storage/schemadb/tests/db.rs b/storage/schemadb/tests/db.rs index 9853332ff710f..d0f768f808bce 100644 --- a/storage/schemadb/tests/db.rs +++ b/storage/schemadb/tests/db.rs @@ -4,9 +4,10 @@ use anyhow::Result; use aptos_schemadb::{ + batch::SchemaBatch, define_schema, schema::{KeyCodec, Schema, ValueCodec}, - ColumnFamilyName, SchemaBatch, DB, + ColumnFamilyName, DB, }; use aptos_storage_interface::AptosDbError; use byteorder::{LittleEndian, ReadBytesExt}; @@ -194,7 +195,7 @@ fn gen_expected_values(values: &[(u32, u32)]) -> Vec<(TestField, TestField)> { fn test_single_schema_batch() { let db = TestDB::new(); - let db_batch = SchemaBatch::new(); + let mut db_batch = SchemaBatch::new(); db_batch .put::(&TestField(0), &TestField(0)) .unwrap(); @@ -232,7 +233,7 @@ fn test_single_schema_batch() { fn test_two_schema_batches() { let db = TestDB::new(); - let db_batch1 = SchemaBatch::new(); + let mut db_batch1 = SchemaBatch::new(); db_batch1 .put::(&TestField(0), &TestField(0)) .unwrap(); @@ -250,7 +251,7 @@ fn test_two_schema_batches() { gen_expected_values(&[(0, 0), (1, 1)]), ); - let db_batch2 = SchemaBatch::new(); + let mut db_batch2 = SchemaBatch::new(); db_batch2.delete::(&TestField(3)).unwrap(); db_batch2 .put::(&TestField(3), &TestField(3)) @@ -330,7 +331,7 @@ fn test_report_size() { let db = TestDB::new(); for i in 0..1000 { - let db_batch = SchemaBatch::new(); + let mut db_batch = SchemaBatch::new(); db_batch .put::(&TestField(i), &TestField(i)) .unwrap(); diff --git a/storage/scratchpad/Cargo.toml b/storage/scratchpad/Cargo.toml index 132cbe2001043..dcc122e957659 100644 --- a/storage/scratchpad/Cargo.toml +++ b/storage/scratchpad/Cargo.toml @@ -15,10 +15,10 @@ rust-version = { workspace = true } [dependencies] aptos-crypto = { workspace = true } aptos-drop-helper = { workspace = true } -aptos-experimental-runtimes = { workspace = true } aptos-infallible = { workspace = true } aptos-metrics-core = { workspace = true } aptos-types = { workspace = true } +aptos-vm = { workspace = true } bitvec = { workspace = true } criterion = { workspace = true, optional = true } itertools = { workspace = true } diff --git a/storage/scratchpad/benches/sparse_merkle.rs b/storage/scratchpad/benches/sparse_merkle.rs index 3789a693d3d04..e08c4ed553921 100644 --- a/storage/scratchpad/benches/sparse_merkle.rs +++ b/storage/scratchpad/benches/sparse_merkle.rs @@ -85,10 +85,7 @@ impl Benches { blocks: block_sizes .iter() .map(|block_size| Block { - smt: SparseMerkleTree::new( - *SPARSE_MERKLE_PLACEHOLDER_HASH, - StateStorageUsage::new_untracked(), - ), + smt: SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH), updates: Self::gen_updates(&mut rng, &keys, *block_size), proof_reader: ProofReader::new(Vec::new()), }) @@ -113,10 +110,7 @@ impl Benches { let updates = Self::gen_updates(&mut rng, &keys, *block_size); let proof_reader = Self::gen_proof_reader(&mut naive_base_smt, &updates); Block { - smt: SparseMerkleTree::new( - naive_base_smt.get_root_hash(), - StateStorageUsage::new_untracked(), - ), + smt: SparseMerkleTree::new(naive_base_smt.get_root_hash()), updates, proof_reader, } diff --git a/storage/scratchpad/src/sparse_merkle/mod.rs b/storage/scratchpad/src/sparse_merkle/mod.rs index e600b2dda2d78..f186b938be2cc 100644 --- a/storage/scratchpad/src/sparse_merkle/mod.rs +++ b/storage/scratchpad/src/sparse_merkle/mod.rs @@ -97,7 +97,6 @@ use aptos_metrics_core::IntGaugeHelper; use aptos_types::{ nibble::{nibble_path::NibblePath, Nibble}, proof::SparseMerkleProofExt, - state_store::state_storage_usage::StateStorageUsage, }; use std::{ collections::{BTreeMap, HashMap}, @@ -114,7 +113,6 @@ const BITS_IN_BYTE: usize = 8; #[derive(Debug)] struct Inner { root: Option>, - usage: StateStorageUsage, children: Mutex>>>, family: HashValue, generation: u64, @@ -141,11 +139,10 @@ impl Drop for Inner { } impl Inner { - fn new(root: SubTree, usage: StateStorageUsage) -> Arc { + fn new(root: SubTree) -> Arc { let family = HashValue::random(); let me = Arc::new(Self { root: Some(root), - usage, children: Mutex::new(Vec::new()), family, generation: 0, @@ -159,14 +156,9 @@ impl Inner { self.root.as_ref().expect("Root must exist.") } - fn spawn( - self: &Arc, - child_root: SubTree, - child_usage: StateStorageUsage, - ) -> Arc { + fn spawn(self: &Arc, child_root: SubTree) -> Arc { let child = Arc::new(Self { root: Some(child_root), - usage: child_usage, children: Mutex::new(Vec::new()), family: self.family, generation: self.generation + 1, @@ -198,27 +190,26 @@ where /// Constructs a Sparse Merkle Tree with a root hash. This is often used when we restart and /// the scratch pad and the storage have identical state, so we use a single root hash to /// represent the entire state. - pub fn new(root_hash: HashValue, usage: StateStorageUsage) -> Self { + pub fn new(root_hash: HashValue) -> Self { let root = if root_hash != *SPARSE_MERKLE_PLACEHOLDER_HASH { SubTree::new_unknown(root_hash) } else { - assert!(usage.is_untracked() || usage == StateStorageUsage::zero()); SubTree::new_empty() }; Self { - inner: Inner::new(root, usage), + inner: Inner::new(root), } } #[cfg(test)] fn new_test(root_hash: HashValue) -> Self { - Self::new(root_hash, StateStorageUsage::new_untracked()) + Self::new(root_hash) } pub fn new_empty() -> Self { Self { - inner: Inner::new(SubTree::new_empty(), StateStorageUsage::zero()), + inner: Inner::new(SubTree::new_empty()), } } @@ -246,7 +237,7 @@ where #[cfg(test)] fn new_with_root(root: SubTree) -> Self { Self { - inner: Inner::new(root, StateStorageUsage::new_untracked()), + inner: Inner::new(root), } } @@ -271,8 +262,8 @@ where self.inner.family == other.inner.family } - pub fn usage(&self) -> StateStorageUsage { - self.inner.usage + pub fn is_descendant_of(&self, other: &Self) -> bool { + self.is_family(other) && self.generation() >= other.generation() } /// Compares an old and a new SMTs and return the newly created node hashes in between. @@ -417,7 +408,7 @@ where ) -> Result { self.clone() .freeze(self) - .batch_update(updates, StateStorageUsage::Untracked, proof_reader) + .batch_update(updates, proof_reader) .map(FrozenSparseMerkleTree::unfreeze) } @@ -466,9 +457,9 @@ impl FrozenSparseMerkleTree where V: Clone + CryptoHash + ArcAsyncDrop, { - fn spawn(&self, child_root: SubTree, child_usage: StateStorageUsage) -> Self { + fn spawn(&self, child_root: SubTree) -> Self { let smt = SparseMerkleTree { - inner: self.smt.inner.spawn(child_root, child_usage), + inner: self.smt.inner.spawn(child_root), }; smt.log_generation("spawn"); @@ -494,7 +485,6 @@ where pub fn batch_update( &self, updates: Vec<(HashValue, Option<&V>)>, - usage: StateStorageUsage, proof_reader: &impl ProofRead, ) -> Result { // Flatten, dedup and sort the updates with a btree map since the updates between different @@ -506,9 +496,6 @@ where .collect::>(); if kvs.is_empty() { - if !usage.is_untracked() { - assert_eq!(self.smt.inner.usage, usage); - } Ok(self.clone()) } else { let current_root = self.smt.root_weak(); @@ -518,7 +505,7 @@ where proof_reader, self.smt.inner.generation + 1, )?; - Ok(self.spawn(root, usage)) + Ok(self.spawn(root)) } } @@ -567,16 +554,18 @@ where } } // end loop } - - pub fn usage(&self) -> StateStorageUsage { - self.smt.usage() - } } /// A type that implements `ProofRead` can provide proof for keys in persistent storage. pub trait ProofRead: Sync { /// Gets verified proof for this key in persistent storage. - fn get_proof(&self, key: HashValue) -> Option<&SparseMerkleProofExt>; + fn get_proof(&self, key: HashValue, root_depth: usize) -> Option; +} + +impl ProofRead for () { + fn get_proof(&self, _key: HashValue, _root_depth: usize) -> Option { + unimplemented!() + } } /// All errors `update` can possibly return. diff --git a/storage/scratchpad/src/sparse_merkle/test_utils/proof_reader.rs b/storage/scratchpad/src/sparse_merkle/test_utils/proof_reader.rs index 9a5195acd7364..9ba8d505a451a 100644 --- a/storage/scratchpad/src/sparse_merkle/test_utils/proof_reader.rs +++ b/storage/scratchpad/src/sparse_merkle/test_utils/proof_reader.rs @@ -17,7 +17,11 @@ impl ProofReader { } impl ProofRead for ProofReader { - fn get_proof(&self, key: HashValue) -> Option<&SparseMerkleProofExt> { - self.0.get(&key) + fn get_proof(&self, key: HashValue, root_depth: usize) -> Option { + let ret = self.0.get(&key); + if let Some(proof) = ret { + assert!(proof.root_depth() <= root_depth); + } + ret.cloned() } } diff --git a/storage/scratchpad/src/sparse_merkle/test_utils/proptest_helpers.rs b/storage/scratchpad/src/sparse_merkle/test_utils/proptest_helpers.rs index 0cea1a3a60f8f..42d28669df803 100644 --- a/storage/scratchpad/src/sparse_merkle/test_utils/proptest_helpers.rs +++ b/storage/scratchpad/src/sparse_merkle/test_utils/proptest_helpers.rs @@ -9,7 +9,7 @@ use crate::{ }; use aptos_crypto::{hash::SPARSE_MERKLE_PLACEHOLDER_HASH, HashValue}; use aptos_drop_helper::ArcAsyncDrop; -use aptos_types::state_store::{state_storage_usage::StateStorageUsage, state_value::StateValue}; +use aptos_types::state_store::state_value::StateValue; use proptest::{ collection::{hash_set, vec}, prelude::*, @@ -76,10 +76,7 @@ pub fn test_smt_correctness_impl(input: Vec) { let mut naive_q = VecDeque::new(); naive_q.push_back(NaiveSmt::new::(&[])); let mut updater_q = VecDeque::new(); - updater_q.push_back(SparseMerkleTree::new( - *SPARSE_MERKLE_PLACEHOLDER_HASH, - StateStorageUsage::zero(), - )); + updater_q.push_back(SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH)); for action in input { match action { diff --git a/storage/scratchpad/src/sparse_merkle/updater.rs b/storage/scratchpad/src/sparse_merkle/updater.rs index 0105e40f1b96c..8f74959b22dc9 100644 --- a/storage/scratchpad/src/sparse_merkle/updater.rs +++ b/storage/scratchpad/src/sparse_merkle/updater.rs @@ -15,10 +15,19 @@ use aptos_crypto::{ HashValue, }; use aptos_drop_helper::ArcAsyncDrop; -use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; use aptos_types::proof::{definition::NodeInProof, SparseMerkleLeafNode, SparseMerkleProofExt}; +use aptos_vm::AptosVM; +use once_cell::sync::Lazy; use std::cmp::Ordering; +static POOL: Lazy = Lazy::new(|| { + rayon::ThreadPoolBuilder::new() + .num_threads(AptosVM::get_num_proof_reading_threads()) + .thread_name(|index| format!("smt_update_{}", index)) + .build() + .unwrap() +}); + type Result = std::result::Result; type InMemSubTree = super::node::SubTree; @@ -99,19 +108,19 @@ impl InMemSubTreeInfo { } #[derive(Clone)] -enum PersistedSubTreeInfo<'a> { - ProofPathInternal { proof: &'a SparseMerkleProofExt }, +enum PersistedSubTreeInfo { + ProofPathInternal { proof: SparseMerkleProofExt }, ProofSibling { hash: HashValue }, Leaf { leaf: SparseMerkleLeafNode }, } #[derive(Clone)] -enum SubTreeInfo<'a, V: ArcAsyncDrop> { +enum SubTreeInfo { InMem(InMemSubTreeInfo), - Persisted(PersistedSubTreeInfo<'a>), + Persisted(PersistedSubTreeInfo), } -impl<'a, V: Clone + CryptoHash + Send + Sync + 'static> SubTreeInfo<'a, V> { +impl<'a, V: Clone + CryptoHash + Send + Sync + 'static> SubTreeInfo { fn new_empty() -> Self { Self::InMem(InMemSubTreeInfo::Empty) } @@ -133,7 +142,7 @@ impl<'a, V: Clone + CryptoHash + Send + Sync + 'static> SubTreeInfo<'a, V> { } } - fn new_on_proof_path(proof: &'a SparseMerkleProofExt, depth: usize) -> Self { + fn new_on_proof_path(proof: SparseMerkleProofExt, depth: usize) -> Self { match proof.bottom_depth().cmp(&depth) { Ordering::Greater => Self::Persisted(PersistedSubTreeInfo::ProofPathInternal { proof }), Ordering::Equal => match proof.leaf() { @@ -150,7 +159,7 @@ impl<'a, V: Clone + CryptoHash + Send + Sync + 'static> SubTreeInfo<'a, V> { proof_reader: &'a impl ProofRead, ) -> Result { let proof = proof_reader - .get_proof(a_descendant_key) + .get_proof(a_descendant_key, depth) .ok_or(UpdateError::MissingProof)?; if depth > proof.bottom_depth() { return Err(UpdateError::ShortProof { @@ -247,7 +256,8 @@ impl<'a, V: Clone + CryptoHash + Send + Sync + 'static> SubTreeInfo<'a, V> { PersistedSubTreeInfo::ProofPathInternal { proof } => { let sibling_child = SubTreeInfo::new_proof_sibling(proof.sibling_at_depth(depth + 1).unwrap()); - let on_path_child = SubTreeInfo::new_on_proof_path(proof, depth + 1); + let on_path_child = + SubTreeInfo::new_on_proof_path(myself.expect_into_proof(), depth + 1); swap_if(on_path_child, sibling_child, a_descendent_key.bit(depth)) }, PersistedSubTreeInfo::ProofSibling { .. } => unreachable!(), @@ -271,11 +281,18 @@ impl<'a, V: Clone + CryptoHash + Send + Sync + 'static> SubTreeInfo<'a, V> { }, } } + + fn expect_into_proof(self) -> SparseMerkleProofExt { + match self { + SubTreeInfo::Persisted(PersistedSubTreeInfo::ProofPathInternal { proof }) => proof, + _ => unreachable!("Known variant."), + } + } } pub struct SubTreeUpdater<'a, V: ArcAsyncDrop> { depth: usize, - info: SubTreeInfo<'a, V>, + info: SubTreeInfo, updates: &'a [(HashValue, Option<&'a V>)], generation: u64, } @@ -312,9 +329,7 @@ impl<'a, V: ArcAsyncDrop + Clone + CryptoHash> SubTreeUpdater<'a, V> { && left.updates.len() >= MIN_PARALLELIZABLE_SIZE && right.updates.len() >= MIN_PARALLELIZABLE_SIZE { - THREAD_MANAGER - .get_exe_cpu_pool() - .join(|| left.run(proof_reader), || right.run(proof_reader)) + POOL.join(|| left.run(proof_reader), || right.run(proof_reader)) } else { (left.run(proof_reader), right.run(proof_reader)) }; diff --git a/storage/storage-interface/Cargo.toml b/storage/storage-interface/Cargo.toml index cd23b5c67a832..24475a51b314f 100644 --- a/storage/storage-interface/Cargo.toml +++ b/storage/storage-interface/Cargo.toml @@ -15,30 +15,27 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } aptos-crypto = { workspace = true } -aptos-drop-helper = { workspace = true } -aptos-experimental-runtimes = { workspace = true } -aptos-logger = { workspace = true } +aptos-experimental-layered-map = { workspace = true } aptos-metrics-core = { workspace = true } aptos-scratchpad = { workspace = true } aptos-secure-net = { workspace = true } aptos-types = { workspace = true } -aptos-vm = { workspace = true } arr_macro = { workspace = true } bcs = { workspace = true } -crossbeam-channel = { workspace = true } dashmap = { workspace = true } +derive_more = { workspace = true } +itertools = { workspace = true } once_cell = { workspace = true } parking_lot = { workspace = true } proptest = { workspace = true } proptest-derive = { workspace = true } +rand = { workspace = true } rayon = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } -threadpool = { workspace = true } [dev-dependencies] aptos-types = { workspace = true, features = ["fuzzing"] } -assert_unordered = { workspace = true } [features] default = [] diff --git a/storage/storage-interface/src/chunk_to_commit.rs b/storage/storage-interface/src/chunk_to_commit.rs index 5148bfd23c709..5ff766224e44c 100644 --- a/storage/storage-interface/src/chunk_to_commit.rs +++ b/storage/storage-interface/src/chunk_to_commit.rs @@ -2,8 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 use crate::state_store::{ - sharded_state_update_refs::ShardedStateUpdateRefs, sharded_state_updates::ShardedStateUpdates, - state_delta::StateDelta, state_view::cached_state_view::ShardedStateCache, + state::LedgerState, + state_summary::LedgerStateSummary, + state_update_refs::StateUpdateRefs, + state_view::cached_state_view::ShardedStateCache, + state_with_summary::{LedgerStateWithSummary, StateWithSummary}, }; use aptos_types::transaction::{Transaction, TransactionInfo, TransactionOutput, Version}; @@ -13,11 +16,10 @@ pub struct ChunkToCommit<'a> { pub transactions: &'a [Transaction], pub transaction_outputs: &'a [TransactionOutput], pub transaction_infos: &'a [TransactionInfo], - pub base_state_version: Option, - pub latest_in_memory_state: &'a StateDelta, - pub state_update_refs: &'a ShardedStateUpdateRefs<'a>, - pub state_updates_until_last_checkpoint: Option<&'a ShardedStateUpdates>, - pub sharded_state_cache: Option<&'a ShardedStateCache>, + pub state: &'a LedgerState, + pub state_summary: &'a LedgerStateSummary, + pub state_update_refs: &'a StateUpdateRefs<'a>, + pub state_reads: &'a ShardedStateCache, pub is_reconfig: bool, } @@ -37,4 +39,31 @@ impl<'a> ChunkToCommit<'a> { pub fn expect_last_version(&self) -> Version { self.next_version() - 1 } + + pub fn result_ledger_state_with_summary(&self) -> LedgerStateWithSummary { + let latest = StateWithSummary::new( + self.state.latest().clone(), + self.state_summary.latest().clone(), + ); + let last_checkpoint = StateWithSummary::new( + self.state.last_checkpoint().clone(), + self.state_summary.last_checkpoint().clone(), + ); + LedgerStateWithSummary::from_latest_and_last_checkpoint(latest, last_checkpoint) + } + + pub fn estimated_total_state_updates(&self) -> usize { + let for_last_checkpoint = self + .state_update_refs + .for_last_checkpoint + .as_ref() + .map_or(0, |x| x.len()); + let for_latest = self + .state_update_refs + .for_latest + .as_ref() + .map_or(0, |x| x.len()); + + for_latest + for_last_checkpoint + } } diff --git a/storage/storage-interface/src/ledger_summary.rs b/storage/storage-interface/src/ledger_summary.rs index db0daa5a848fe..0a223b9855115 100644 --- a/storage/storage-interface/src/ledger_summary.rs +++ b/storage/storage-interface/src/ledger_summary.rs @@ -1,114 +1,52 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{ - state_store::{ - state_delta::StateDelta, - state_view::{async_proof_fetcher::AsyncProofFetcher, cached_state_view::CachedStateView}, - }, - DbReader, -}; -use anyhow::Result; -use aptos_crypto::HashValue; +use crate::state_store::{state::LedgerState, state_summary::LedgerStateSummary}; use aptos_types::{ proof::accumulator::{InMemoryAccumulator, InMemoryTransactionAccumulator}, - state_store::{state_storage_usage::StateStorageUsage, StateViewId}, transaction::Version, }; use std::sync::Arc; -/// A wrapper of the in-memory state sparse merkle tree and the transaction accumulator that -/// represent a specific state collectively. Usually it is a state after executing a block. #[derive(Clone, Debug)] pub struct LedgerSummary { - /// The in-memory representation of state after execution. - pub state: Arc, - - /// The in-memory Merkle Accumulator representing a blockchain state consistent with the - /// `state_tree`. + pub state: LedgerState, + pub state_summary: LedgerStateSummary, pub transaction_accumulator: Arc, } impl LedgerSummary { - pub fn state(&self) -> &Arc { - &self.state - } - - pub fn txn_accumulator(&self) -> &Arc { - &self.transaction_accumulator - } - - pub fn version(&self) -> Option { - self.num_transactions().checked_sub(1) - } - - pub fn num_transactions(&self) -> u64 { - self.txn_accumulator().num_leaves() - } - - pub fn state_id(&self) -> HashValue { - self.txn_accumulator().root_hash() - } - pub fn new( - state: Arc, + state: LedgerState, + state_summary: LedgerStateSummary, transaction_accumulator: Arc, ) -> Self { - assert_eq!( - state.current_version.map_or(0, |v| v + 1), - transaction_accumulator.num_leaves() - ); + state_summary.assert_versions_match(&state); + Self { state, + state_summary, transaction_accumulator, } } - pub fn new_at_state_checkpoint( - state_root_hash: HashValue, - state_usage: StateStorageUsage, - frozen_subtrees_in_accumulator: Vec, - num_leaves_in_accumulator: u64, - ) -> Self { - let state = Arc::new(StateDelta::new_at_checkpoint( - state_root_hash, - state_usage, - num_leaves_in_accumulator.checked_sub(1), - )); - let transaction_accumulator = Arc::new( - InMemoryAccumulator::new(frozen_subtrees_in_accumulator, num_leaves_in_accumulator) - .expect("The startup info read from storage should be valid."), - ); + pub fn next_version(&self) -> Version { + self.transaction_accumulator.num_leaves() + } - Self::new(state, transaction_accumulator) + pub fn version(&self) -> Option { + self.next_version().checked_sub(1) } pub fn new_empty() -> Self { + let state = LedgerState::new_empty(); + let state_summary = LedgerStateSummary::new_empty(); Self::new( - Arc::new(StateDelta::new_empty()), + state, + state_summary, Arc::new(InMemoryAccumulator::new_empty()), ) } - - pub fn is_same_view(&self, rhs: &Self) -> bool { - self.state().has_same_current_state(rhs.state()) - && self.transaction_accumulator.root_hash() == rhs.transaction_accumulator.root_hash() - } - - pub fn verified_state_view( - &self, - id: StateViewId, - reader: Arc, - proof_fetcher: Arc, - ) -> Result { - Ok(CachedStateView::new( - id, - reader, - self.transaction_accumulator.num_leaves(), - self.state.current.clone(), - proof_fetcher, - )?) - } } impl Default for LedgerSummary { diff --git a/storage/storage-interface/src/lib.rs b/storage/storage-interface/src/lib.rs index 9c6c66cf4c3f0..99c81cd807e10 100644 --- a/storage/storage-interface/src/lib.rs +++ b/storage/storage-interface/src/lib.rs @@ -2,7 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use aptos_crypto::{hash::CryptoHash, HashValue}; +use aptos_crypto::HashValue; pub use aptos_types::indexer::indexer_db_reader::Order; use aptos_types::{ account_address::AccountAddress, @@ -31,7 +31,7 @@ use aptos_types::{ write_set::WriteSet, }; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, sync::Arc}; +use std::sync::Arc; use thiserror::Error; pub mod block_info; @@ -43,8 +43,10 @@ mod metrics; pub mod mock; pub mod state_store; -use crate::chunk_to_commit::ChunkToCommit; -use aptos_scratchpad::SparseMerkleTree; +use crate::{ + chunk_to_commit::ChunkToCommit, + state_store::{state::State, state_summary::StateSummary}, +}; pub use aptos_types::block_info::BlockHeight; use aptos_types::state_store::state_key::prefix::StateKeyPrefix; pub use errors::AptosDbError; @@ -354,7 +356,7 @@ pub trait DbReader: Send + Sync { /// Returns the proof of the given state key and version. fn get_state_proof_by_version_ext( &self, - state_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result; @@ -369,7 +371,7 @@ pub trait DbReader: Send + Sync { /// This is used by aptos core (executor) internally. fn get_state_value_with_proof_by_version_ext( &self, - state_key: &StateKey, + key_hash: &HashValue, version: Version, root_depth: usize, ) -> Result<(Option, SparseMerkleProofExt)>; @@ -378,8 +380,9 @@ pub trait DbReader: Send + Sync { /// Used by the Db-bootstrapper. fn get_pre_committed_ledger_summary(&self) -> Result; - /// Get the oldest in memory state tree. - fn get_buffered_state_base(&self) -> Result>; + fn get_persisted_state(&self) -> Result; + + fn get_persisted_state_summary(&self) -> Result; /// Get the ledger info of the epoch that `known_version` belongs to. fn get_epoch_ending_ledger_info( @@ -485,7 +488,7 @@ pub trait DbReader: Send + Sync { state_key: &StateKey, version: Version, ) -> Result<(Option, SparseMerkleProof)> { - self.get_state_value_with_proof_by_version_ext(state_key, version, 0) + self.get_state_value_with_proof_by_version_ext(state_key.crypto_hash_ref(), version, 0) .map(|(value, proof_ext)| (value, proof_ext.into())) } @@ -658,15 +661,6 @@ impl SaveTransactionsRequest { } } -pub fn jmt_updates( - state_updates: &HashMap<&StateKey, Option<&StateValue>>, -) -> Vec<(HashValue, Option<(HashValue, StateKey)>)> { - state_updates - .iter() - .map(|(k, v_opt)| (k.hash(), v_opt.as_ref().map(|v| (v.hash(), (*k).clone())))) - .collect() -} - pub fn jmt_update_refs( jmt_updates: &[(HashValue, Option<(HashValue, K)>)], ) -> Vec<(HashValue, Option<&(HashValue, K)>)> { diff --git a/storage/storage-interface/src/metrics.rs b/storage/storage-interface/src/metrics.rs index 8cbf89671b042..2c87dbc920349 100644 --- a/storage/storage-interface/src/metrics.rs +++ b/storage/storage-interface/src/metrics.rs @@ -6,7 +6,7 @@ use aptos_metrics_core::{exponential_buckets, register_histogram_vec, HistogramVec}; use once_cell::sync::Lazy; -pub static TIMER: Lazy = Lazy::new(|| { +pub(crate) static TIMER: Lazy = Lazy::new(|| { register_histogram_vec!( "aptos_storage_interface_timer_seconds", "Various timers for performance analysis.", diff --git a/storage/storage-interface/src/mock.rs b/storage/storage-interface/src/mock.rs index 5d3d367cc35b4..7cf747b56d4d4 100644 --- a/storage/storage-interface/src/mock.rs +++ b/storage/storage-interface/src/mock.rs @@ -5,6 +5,7 @@ //! This module provides mock dbreader for tests. use crate::{errors::AptosDbError, DbReader, DbWriter, Result}; +use aptos_crypto::HashValue; use aptos_types::{ proof::SparseMerkleProofExt, state_store::{ @@ -25,7 +26,7 @@ impl DbReader for MockDbReaderWriter { fn get_state_proof_by_version_ext( &self, - _state_key: &StateKey, + _key_hash: &HashValue, _version: Version, _root_depth: usize, ) -> Result { diff --git a/storage/storage-interface/src/state_store/mod.rs b/storage/storage-interface/src/state_store/mod.rs index e6e30c8654052..05accea0ad883 100644 --- a/storage/storage-interface/src/state_store/mod.rs +++ b/storage/storage-interface/src/state_store/mod.rs @@ -1,9 +1,12 @@ // Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -pub mod sharded_state_update_refs; -pub mod sharded_state_updates; +pub mod state; pub mod state_delta; +pub mod state_summary; +pub mod state_update_refs; pub mod state_view; +pub mod state_with_summary; +pub mod versioned_state_value; pub const NUM_STATE_SHARDS: usize = 16; diff --git a/storage/storage-interface/src/state_store/sharded_state_update_refs.rs b/storage/storage-interface/src/state_store/sharded_state_update_refs.rs deleted file mode 100644 index f98ba4732c28e..0000000000000 --- a/storage/storage-interface/src/state_store/sharded_state_update_refs.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{metrics::TIMER, state_store::NUM_STATE_SHARDS}; -use aptos_metrics_core::TimerHelper; -use aptos_types::{ - state_store::{state_key::StateKey, state_value::StateValue}, - write_set::WriteSet, -}; -use arr_macro::arr; - -pub type StateUpdateRefWithOffset<'kv> = (usize, &'kv StateKey, Option<&'kv StateValue>); - -pub struct ShardedStateUpdateRefs<'kv> { - /// (idx, key, value) tuple per update, sharded - /// Converting to Box<[]> to release over-allocated memory during construction - pub shards: [Box<[StateUpdateRefWithOffset<'kv>]>; NUM_STATE_SHARDS], - pub num_versions: usize, -} - -impl<'kv> ShardedStateUpdateRefs<'kv> { - pub fn index_write_sets( - write_sets: impl IntoIterator, - num_write_sets: usize, - ) -> Self { - Self::index_per_version_updates( - write_sets - .into_iter() - .map(|write_set| write_set.state_update_refs()), - num_write_sets, - ) - } - - pub fn index_per_version_updates< - UpdateIter: IntoIterator)>, - VersionIter: IntoIterator, - >( - updates_by_version: VersionIter, - num_versions: usize, - ) -> Self { - let _timer = TIMER.timer_with(&["index_state_updates"]); - - // Over-allocate a bit to minimize re-allocation. - let mut shards = arr![Vec::with_capacity(num_versions / 8); 16]; - - let mut versions_seen = 0; - for (idx, update_iter) in updates_by_version.into_iter().enumerate() { - versions_seen += 1; - - for (key, value) in update_iter.into_iter() { - shards[key.get_shard_id() as usize].push((idx, key, value)); - } - } - assert_eq!(versions_seen, num_versions); - - Self { - shards: shards.map(|shard| shard.into_boxed_slice()), - num_versions, - } - } -} diff --git a/storage/storage-interface/src/state_store/sharded_state_updates.rs b/storage/storage-interface/src/state_store/sharded_state_updates.rs deleted file mode 100644 index 4abf2c5e9be9a..0000000000000 --- a/storage/storage-interface/src/state_store/sharded_state_updates.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; -use aptos_types::state_store::{state_key::StateKey, state_value::StateValue}; -use arr_macro::arr; -use rayon::iter::{ - IndexedParallelIterator, IntoParallelIterator, IntoParallelRefIterator, - IntoParallelRefMutIterator, ParallelIterator, -}; -use std::collections::HashMap; - -#[derive(Clone, Debug)] -pub struct ShardedStateUpdates { - pub shards: [HashMap>; 16], -} - -impl ShardedStateUpdates { - pub fn new_empty() -> Self { - Self { - shards: arr![HashMap::new(); 16], - } - } - - pub fn all_shards_empty(&self) -> bool { - self.shards.iter().all(|shard| shard.is_empty()) - } - - pub fn total_len(&self) -> usize { - self.shards.iter().map(|shard| shard.len()).sum() - } - - pub fn merge(&mut self, other: Self) { - THREAD_MANAGER.get_exe_cpu_pool().install(|| { - self.shards - .par_iter_mut() - .zip_eq(other.shards.into_par_iter()) - .for_each(|(l, r)| { - l.extend(r); - }) - }) - } - - pub fn clone_merge(&mut self, other: &Self) { - THREAD_MANAGER.get_exe_cpu_pool().install(|| { - self.shards - .par_iter_mut() - .zip_eq(other.shards.par_iter()) - .for_each(|(l, r)| { - l.extend(r.clone()); - }) - }) - } - - pub fn insert( - &mut self, - key: StateKey, - value: Option, - ) -> Option> { - self.shards[key.get_shard_id() as usize].insert(key, value) - } -} diff --git a/storage/storage-interface/src/state_store/state.rs b/storage/storage-interface/src/state_store/state.rs new file mode 100644 index 0000000000000..d8c80784d2082 --- /dev/null +++ b/storage/storage-interface/src/state_store/state.rs @@ -0,0 +1,286 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + metrics::TIMER, + state_store::{ + state_delta::StateDelta, + state_update_refs::{BatchedStateUpdateRefs, StateUpdateRefs}, + state_view::cached_state_view::{CachedStateView, ShardedStateCache, StateCacheShard}, + versioned_state_value::{StateUpdate, StateUpdateRef}, + NUM_STATE_SHARDS, + }, + DbReader, +}; +use anyhow::Result; +use aptos_experimental_layered_map::{LayeredMap, MapLayer}; +use aptos_metrics_core::TimerHelper; +use aptos_types::{ + state_store::{state_key::StateKey, state_storage_usage::StateStorageUsage, StateViewId}, + transaction::Version, +}; +use derive_more::Deref; +use itertools::Itertools; +use rayon::prelude::*; +use std::{collections::HashMap, sync::Arc}; + +/// Represents the blockchain state at a given version. +/// n.b. the state can be either persisted or speculative. +#[derive(Clone, Debug)] +pub struct State { + /// The next version. If this is 0, the state is the "pre-genesis" empty state. + next_version: Version, + /// The updates made to the state at the current version. + /// N.b. this is not directly iteratable, one needs to make a `StateDelta` + /// between this and a `base_version` to list the updates or create a + /// new `State` at a descendant version. + shards: Arc<[MapLayer; NUM_STATE_SHARDS]>, + /// The total usage of the state at the current version. + usage: StateStorageUsage, +} + +impl State { + pub fn new_with_updates( + version: Option, + shards: Arc<[MapLayer; NUM_STATE_SHARDS]>, + usage: StateStorageUsage, + ) -> Self { + Self { + next_version: version.map_or(0, |v| v + 1), + shards, + usage, + } + } + + pub fn new_at_version(version: Option, usage: StateStorageUsage) -> Self { + Self::new_with_updates( + version, + Arc::new(arr_macro::arr![MapLayer::new_family("state"); 16]), + usage, + ) + } + + pub fn new_empty() -> Self { + Self::new_at_version(None, StateStorageUsage::zero()) + } + + pub fn next_version(&self) -> Version { + self.next_version + } + + pub fn version(&self) -> Option { + self.next_version.checked_sub(1) + } + + pub fn usage(&self) -> StateStorageUsage { + self.usage + } + + pub fn shards(&self) -> &[MapLayer; NUM_STATE_SHARDS] { + &self.shards + } + + pub fn make_delta(&self, base: &State) -> StateDelta { + let _timer = TIMER.timer_with(&["state__make_delta"]); + self.clone().into_delta(base.clone()) + } + + pub fn into_delta(self, base: State) -> StateDelta { + StateDelta::new(base, self) + } + + pub fn is_the_same(&self, rhs: &Self) -> bool { + Arc::ptr_eq(&self.shards, &rhs.shards) + } + + pub fn is_descendant_of(&self, rhs: &State) -> bool { + self.shards[0].is_descendant_of(&rhs.shards[0]) + } + + pub fn update( + &self, + persisted: &State, + updates: &BatchedStateUpdateRefs, + state_cache: &ShardedStateCache, + ) -> Self { + let _timer = TIMER.timer_with(&["state__update"]); + + // 1. The update batch must begin at self.next_version(). + assert_eq!(self.next_version(), updates.first_version); + // 2. The cache must be at a version equal or newer than `persisted`, otherwise + // updates between the cached version and the persisted version are potentially + // missed during the usage calculation. + assert!( + persisted.next_version() <= state_cache.next_version(), + "persisted: {}, cache: {}", + persisted.next_version(), + state_cache.next_version(), + ); + // 3. `self` must be at a version equal or newer than the cache, because we assume + // it is overlayed on top of the cache. + assert!(self.next_version() >= state_cache.next_version()); + + let overlay = self.make_delta(persisted); + let (shards, usage_delta_per_shard): (Vec<_>, Vec<_>) = ( + state_cache.shards.as_slice(), + overlay.shards.as_slice(), + updates.shards.as_slice(), + ) + .into_par_iter() + .map(|(cache, overlay, updates)| { + ( + // TODO(aldenhu): change interface to take iter of ref + overlay.new_layer( + &updates + .iter() + .map(|(k, u)| ((*k).clone(), (*u).cloned())) + .collect_vec(), + ), + Self::usage_delta_for_shard(cache, overlay, updates), + ) + }) + .unzip(); + let shards = Arc::new(shards.try_into().expect("Known to be 16 shards.")); + let usage = self.update_usage(usage_delta_per_shard); + + State::new_with_updates(updates.last_version(), shards, usage) + } + + fn update_usage(&self, usage_delta_per_shard: Vec<(i64, i64)>) -> StateStorageUsage { + assert_eq!(usage_delta_per_shard.len(), NUM_STATE_SHARDS); + + let (items_delta, bytes_delta) = usage_delta_per_shard + .into_iter() + .fold((0, 0), |(i1, b1), (i2, b2)| (i1 + i2, b1 + b2)); + StateStorageUsage::new( + (self.usage().items() as i64 + items_delta) as usize, + (self.usage().bytes() as i64 + bytes_delta) as usize, + ) + } + + fn usage_delta_for_shard<'kv>( + cache: &StateCacheShard, + overlay: &LayeredMap, + updates: &HashMap<&'kv StateKey, StateUpdateRef<'kv>>, + ) -> (i64, i64) { + let mut items_delta: i64 = 0; + let mut bytes_delta: i64 = 0; + for (k, v) in updates { + let key_size = k.size(); + if let Some(value) = v.value { + items_delta += 1; + bytes_delta += (key_size + value.size()) as i64; + } + + // TODO(aldenhu): avoid cloning the state value (by not using DashMap) + // n.b. all updated state items must be read and recorded in the state cache, + // otherwise we can't calculate the correct usage. + let old_value = overlay + .get(k) + .map(|update| update.value) + .or_else(|| cache.get(k).map(|entry| entry.value().to_state_value_opt())) + .expect("Must cache read"); + if let Some(old_v) = old_value { + items_delta -= 1; + bytes_delta -= (key_size + old_v.size()) as i64; + } + } + (items_delta, bytes_delta) + } +} + +/// At a given version, the state and the last checkpoint state at or before the version. +#[derive(Clone, Debug, Deref)] +pub struct LedgerState { + last_checkpoint: State, + #[deref] + latest: State, +} + +impl LedgerState { + pub fn new(latest: State, last_checkpoint: State) -> Self { + assert!(latest.is_descendant_of(&latest)); + + Self { + latest, + last_checkpoint, + } + } + + pub fn new_empty() -> Self { + let state = State::new_empty(); + Self::new(state.clone(), state) + } + + pub fn latest(&self) -> &State { + &self.latest + } + + pub fn last_checkpoint(&self) -> &State { + &self.last_checkpoint + } + + pub fn is_checkpoint(&self) -> bool { + self.latest.is_the_same(&self.last_checkpoint) + } + + /// In the execution pipeline, at the time of state update, the reads during execution + /// have already been recorded. + pub fn update_with_memorized_reads( + &self, + persisted_snapshot: &State, + updates: &StateUpdateRefs, + reads: &ShardedStateCache, + ) -> LedgerState { + let _timer = TIMER.timer_with(&["ledger_state__update"]); + + let last_checkpoint = if let Some(updates) = &updates.for_last_checkpoint { + self.latest().update(persisted_snapshot, updates, reads) + } else { + self.last_checkpoint.clone() + }; + + let base_of_latest = if updates.for_last_checkpoint.is_none() { + self.latest() + } else { + &last_checkpoint + }; + let latest = if let Some(updates) = &updates.for_latest { + base_of_latest.update(persisted_snapshot, updates, reads) + } else { + base_of_latest.clone() + }; + + LedgerState::new(latest, last_checkpoint) + } + + /// Old values of the updated keys are read from the DbReader at the version of the + /// `persisted_snapshot`. + pub fn update_with_db_reader( + &self, + persisted_snapshot: &State, + updates: &StateUpdateRefs, + reader: Arc, + ) -> Result<(LedgerState, ShardedStateCache)> { + let state_view = CachedStateView::new_impl( + StateViewId::Miscellaneous, + reader, + persisted_snapshot.clone(), + self.latest().clone(), + ); + state_view.prime_cache(updates)?; + + let updated = self.update_with_memorized_reads( + persisted_snapshot, + updates, + state_view.memorized_reads(), + ); + let state_reads = state_view.into_memorized_reads(); + Ok((updated, state_reads)) + } + + pub fn is_the_same(&self, other: &Self) -> bool { + self.latest.is_the_same(&other.latest) + && self.last_checkpoint.is_the_same(&other.last_checkpoint) + } +} diff --git a/storage/storage-interface/src/state_store/state_delta.rs b/storage/storage-interface/src/state_store/state_delta.rs index 6e5e0a456f3c7..386ef9dc341f3 100644 --- a/storage/storage-interface/src/state_store/state_delta.rs +++ b/storage/storage-interface/src/state_store/state_delta.rs @@ -1,14 +1,11 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::state_store::sharded_state_updates::ShardedStateUpdates; -use aptos_crypto::HashValue; -use aptos_drop_helper::DropHelper; -use aptos_scratchpad::SparseMerkleTree; -use aptos_types::{ - state_store::{state_storage_usage::StateStorageUsage, state_value::StateValue}, - transaction::Version, -}; +use crate::state_store::{state::State, versioned_state_value::StateUpdate, NUM_STATE_SHARDS}; +use aptos_experimental_layered_map::LayeredMap; +use aptos_types::{state_store::state_key::StateKey, transaction::Version}; +use itertools::Itertools; +use std::sync::Arc; /// This represents two state sparse merkle trees at their versions in memory with the updates /// reflecting the difference of `current` on top of `base`. @@ -19,100 +16,44 @@ use aptos_types::{ /// when the next checkpoint is calculated. #[derive(Clone, Debug)] pub struct StateDelta { - pub base: SparseMerkleTree, - pub base_version: Option, - pub current: SparseMerkleTree, - pub current_version: Option, - pub updates_since_base: DropHelper, + pub base: State, + pub current: State, + pub shards: Arc<[LayeredMap; NUM_STATE_SHARDS]>, } impl StateDelta { - pub fn new( - base: SparseMerkleTree, - base_version: Option, - current: SparseMerkleTree, - current_version: Option, - updates_since_base: ShardedStateUpdates, - ) -> Self { - assert!(base.is_family(¤t)); - assert!(base_version.map_or(0, |v| v + 1) <= current_version.map_or(0, |v| v + 1)); + pub fn new(base: State, current: State) -> Self { + assert!(current.is_descendant_of(&base)); + + let shards = Arc::new( + current + .shards() + .iter() + .zip_eq(base.shards().iter()) + .map(|(current, base)| current.view_layers_after(base)) + .collect_vec() + .try_into() + .expect("Known to be 16 shards."), + ); + Self { base, - base_version, current, - current_version, - updates_since_base: DropHelper::new(updates_since_base), + shards, } } - pub fn new_empty_with_version(version: Option) -> StateDelta { - let smt = SparseMerkleTree::new_empty(); - Self::new( - smt.clone(), - version, - smt, - version, - ShardedStateUpdates::new_empty(), - ) - } - - pub fn new_empty() -> Self { - Self::new_empty_with_version(None) - } - - pub fn new_at_checkpoint( - root_hash: HashValue, - usage: StateStorageUsage, - checkpoint_version: Option, - ) -> Self { - let smt = SparseMerkleTree::new(root_hash, usage); - Self::new( - smt.clone(), - checkpoint_version, - smt, - checkpoint_version, - ShardedStateUpdates::new_empty(), - ) - } - - pub fn merge(&mut self, other: StateDelta) { - assert!(other.follow(self)); - - self.current = other.current; - self.current_version = other.current_version; - self.updates_since_base - .merge(other.updates_since_base.into_inner()); - } - - pub fn follow(&self, other: &StateDelta) -> bool { - self.base_version == other.current_version && other.current.has_same_root_hash(&self.base) - } - - pub fn has_same_current_state(&self, other: &StateDelta) -> bool { - self.current_version == other.current_version - && self.current.has_same_root_hash(&other.current) - } - - pub fn base_root_hash(&self) -> HashValue { - self.base.root_hash() - } - - pub fn root_hash(&self) -> HashValue { - self.current.root_hash() - } - pub fn next_version(&self) -> Version { - self.current_version.map_or(0, |v| v + 1) + self.current.next_version() } - pub fn replace_with(&mut self, mut rhs: Self) -> Self { - std::mem::swap(self, &mut rhs); - rhs + pub fn base_version(&self) -> Option { + self.base.version() } -} -impl Default for StateDelta { - fn default() -> Self { - Self::new_empty() + /// Get the state update for a given state key. + /// `None` indicates the key is not updated in the delta. + pub fn get_state_update(&self, state_key: &StateKey) -> Option { + self.shards[state_key.get_shard_id() as usize].get(state_key) } } diff --git a/storage/storage-interface/src/state_store/state_summary.rs b/storage/storage-interface/src/state_store/state_summary.rs new file mode 100644 index 0000000000000..97d882391e641 --- /dev/null +++ b/storage/storage-interface/src/state_store/state_summary.rs @@ -0,0 +1,236 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + metrics::TIMER, + state_store::{ + state::LedgerState, + state_update_refs::{BatchedStateUpdateRefs, StateUpdateRefs}, + }, + DbReader, +}; +use anyhow::Result; +use aptos_crypto::{ + hash::{CryptoHash, CORRUPTION_SENTINEL}, + HashValue, +}; +use aptos_metrics_core::TimerHelper; +use aptos_scratchpad::{ProofRead, SparseMerkleTree}; +use aptos_types::{ + proof::SparseMerkleProofExt, state_store::state_value::StateValue, transaction::Version, +}; +use derive_more::Deref; +use itertools::Itertools; +use rayon::prelude::*; + +/// The data structure through which the entire state at a given +/// version can be summarized to a concise digest (the root hash). +#[derive(Clone, Debug)] +pub struct StateSummary { + /// The next version. If this is 0, the state is the "pre-genesis" empty state. + next_version: Version, + pub global_state_summary: SparseMerkleTree, +} + +impl StateSummary { + pub fn new_at_version( + version: Option, + global_state_summary: SparseMerkleTree, + ) -> Self { + Self { + next_version: version.map_or(0, |v| v + 1), + global_state_summary, + } + } + + pub fn new_empty() -> Self { + Self { + next_version: 0, + global_state_summary: SparseMerkleTree::new_empty(), + } + } + + pub fn root_hash(&self) -> HashValue { + self.global_state_summary.root_hash() + } + + pub fn next_version(&self) -> Version { + self.next_version + } + + pub fn version(&self) -> Option { + self.next_version.checked_sub(1) + } + + pub fn is_descendant_of(&self, other: &Self) -> bool { + self.global_state_summary + .is_descendant_of(&other.global_state_summary) + } + + pub fn update( + &self, + persisted: &ProvableStateSummary, + updates: &BatchedStateUpdateRefs, + ) -> Result { + let _timer = TIMER.timer_with(&["state_summary__update"]); + + assert_ne!(self.global_state_summary.root_hash(), *CORRUPTION_SENTINEL); + + // Persisted must be before or at my version. + assert!(persisted.next_version() <= self.next_version()); + // Updates must start at exactly my version. + assert_eq!(updates.first_version(), self.next_version()); + + let smt_updates = updates + .shards + .par_iter() // clone hashes and sort items in parallel + // TODO(aldenhu): smt per shard? + .flat_map(|shard| { + shard + .iter() + .sorted_by(|(k1, _u1), (k2, _u2)| { + k1.crypto_hash_ref().cmp(k2.crypto_hash_ref()) + }) + .map(|(k, u)| (CryptoHash::hash(*k), u.value)) + .collect::>() + }) + .collect::>(); + + // TODO(aldenhu): smt leaf not carry StateValue + let smt = self + .global_state_summary + .freeze(&persisted.global_state_summary) + .batch_update(smt_updates, persisted)? + .unfreeze(); + + Ok(Self { + next_version: updates.next_version(), + global_state_summary: smt, + }) + } +} + +/// At a given version, the summaries of the state and the last checkpoint state at or before the version. +#[derive(Clone, Debug, Deref)] +pub struct LedgerStateSummary { + #[deref] + latest: StateSummary, + last_checkpoint: StateSummary, +} + +impl LedgerStateSummary { + pub fn new(last_checkpoint: StateSummary, latest: StateSummary) -> Self { + assert!(last_checkpoint.next_version() <= latest.next_version()); + + Self { + last_checkpoint, + latest, + } + } + + pub fn new_empty() -> Self { + let state_summary = StateSummary::new_empty(); + Self::new(state_summary.clone(), state_summary) + } + + pub fn next_version(&self) -> Version { + self.latest.next_version() + } + + pub fn assert_versions_match(&self, state: &LedgerState) { + assert_eq!(self.next_version(), state.next_version()); + assert_eq!( + self.last_checkpoint.next_version(), + state.last_checkpoint().next_version() + ); + } + + pub fn latest(&self) -> &StateSummary { + &self.latest + } + + pub fn last_checkpoint(&self) -> &StateSummary { + &self.last_checkpoint + } + + pub fn update( + &self, + persisted: &ProvableStateSummary, + updates: &StateUpdateRefs, + ) -> Result { + let _timer = TIMER.timer_with(&["ledger_state_summary__update"]); + + let last_checkpoint = if let Some(updates) = &updates.for_last_checkpoint { + self.latest.update(persisted, updates)? + } else { + self.last_checkpoint.clone() + }; + + let base_of_latest = if updates.for_last_checkpoint.is_none() { + self.latest() + } else { + &last_checkpoint + }; + let latest = if let Some(updates) = &updates.for_latest { + base_of_latest.update(persisted, updates)? + } else { + base_of_latest.clone() + }; + + Ok(Self::new(last_checkpoint, latest)) + } +} + +#[derive(Deref)] +pub struct ProvableStateSummary<'db> { + #[deref] + state_summary: StateSummary, + db: &'db (dyn DbReader + Sync), +} + +impl<'db> ProvableStateSummary<'db> { + pub fn new_persisted(db: &'db (dyn DbReader + Sync)) -> Result { + Ok(Self::new(db.get_persisted_state_summary()?, db)) + } + + pub fn new(state_summary: StateSummary, db: &'db (dyn DbReader + Sync)) -> Self { + Self { state_summary, db } + } + + fn get_proof( + &self, + key: &HashValue, + version: Version, + root_depth: usize, + ) -> Result { + if rand::random::() % 10000 == 0 { + // 1 out of 10000 times, verify the proof. + let (val_opt, proof) = self + .db + // check the full proof + .get_state_value_with_proof_by_version_ext(key, version, 0)?; + proof.verify( + self.state_summary.global_state_summary.root_hash(), + *key, + val_opt.as_ref(), + )?; + Ok(proof) + } else { + Ok(self + .db + .get_state_proof_by_version_ext(key, version, root_depth)?) + } + } +} + +impl<'db> ProofRead for ProvableStateSummary<'db> { + // TODO(aldenhu): return error + fn get_proof(&self, key: HashValue, root_depth: usize) -> Option { + self.version().map(|ver| { + let _timer = TIMER.timer_with(&["provable_state_summary__get_proof"]); + + self.get_proof(&key, ver, root_depth) + .expect("Failed to get account state with proof by version.") + }) + } +} diff --git a/storage/storage-interface/src/state_store/state_update_refs.rs b/storage/storage-interface/src/state_store/state_update_refs.rs new file mode 100644 index 0000000000000..1c16f60c7a181 --- /dev/null +++ b/storage/storage-interface/src/state_store/state_update_refs.rs @@ -0,0 +1,210 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + metrics::TIMER, + state_store::{versioned_state_value::StateUpdateRef, NUM_STATE_SHARDS}, +}; +use aptos_metrics_core::TimerHelper; +use aptos_types::{ + state_store::{state_key::StateKey, state_value::StateValue}, + transaction::Version, + write_set::WriteSet, +}; +use arr_macro::arr; +use itertools::Itertools; +use rayon::iter::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator}; +use std::collections::HashMap; + +pub struct PerVersionStateUpdateRefs<'kv> { + pub first_version: Version, + pub num_versions: usize, + /// Converting to Vec to Box<[]> to release over-allocated memory during construction + pub shards: [Box<[(&'kv StateKey, StateUpdateRef<'kv>)]>; NUM_STATE_SHARDS], +} + +impl<'kv> PerVersionStateUpdateRefs<'kv> { + pub fn index< + UpdateIter: IntoIterator)>, + VersionIter: IntoIterator, + >( + first_version: Version, + updates_by_version: VersionIter, + num_versions: usize, + ) -> Self { + let _timer = TIMER.timer_with(&["index_state_updates__per_version"]); + + // Over-allocate a bit to minimize re-allocation. + let mut shards = arr![Vec::with_capacity(num_versions / 8); 16]; + + let mut versions_seen = 0; + for update_iter in updates_by_version.into_iter() { + let version = first_version + versions_seen as Version; + versions_seen += 1; + + for (key, value) in update_iter.into_iter() { + shards[key.get_shard_id() as usize].push((key, StateUpdateRef { version, value })); + } + } + assert_eq!(versions_seen, num_versions); + + Self { + first_version, + shards: shards.map(|shard| shard.into_boxed_slice()), + num_versions, + } + } +} + +#[derive(Clone, Debug)] +pub struct BatchedStateUpdateRefs<'kv> { + pub first_version: Version, + pub num_versions: usize, + pub shards: [HashMap<&'kv StateKey, StateUpdateRef<'kv>>; NUM_STATE_SHARDS], +} + +impl<'kv> BatchedStateUpdateRefs<'kv> { + pub fn new_empty(first_version: Version, num_versions: usize) -> Self { + Self { + first_version, + num_versions, + shards: arr![HashMap::new(); 16], + } + } + + pub fn first_version(&self) -> Version { + self.first_version + } + + pub fn next_version(&self) -> Version { + self.first_version + self.num_versions as Version + } + + pub fn last_version(&self) -> Option { + self.next_version().checked_sub(1) + } + + pub fn len(&self) -> usize { + self.shards.iter().map(|shard| shard.len()).sum() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +pub struct StateUpdateRefs<'kv> { + pub per_version: PerVersionStateUpdateRefs<'kv>, + pub for_last_checkpoint: Option>, + pub for_latest: Option>, +} + +impl<'kv> StateUpdateRefs<'kv> { + pub fn index_write_sets( + first_version: Version, + write_sets: impl IntoIterator, + num_write_sets: usize, + last_checkpoint_index: Option, + ) -> Self { + Self::index( + first_version, + write_sets + .into_iter() + .map(|write_set| write_set.state_update_refs()), + num_write_sets, + last_checkpoint_index, + ) + } + + pub fn index< + UpdateIter: IntoIterator)>, + VersionIter: IntoIterator, + >( + first_version: Version, + updates_by_version: VersionIter, + num_versions: usize, + last_checkpoint_index: Option, + ) -> Self { + let per_version = + PerVersionStateUpdateRefs::index(first_version, updates_by_version, num_versions); + + let (for_last_checkpoint, for_latest) = + Self::collect_updates(&per_version, last_checkpoint_index); + Self { + per_version, + for_last_checkpoint, + for_latest, + } + } + + pub fn last_inner_checkpoint_index(&self) -> Option { + self.for_last_checkpoint + .as_ref() + .map(|updates| updates.num_versions - 1) + } + + fn collect_updates( + per_version_updates: &PerVersionStateUpdateRefs<'kv>, + last_checkpoint_index: Option, + ) -> ( + Option>, + Option>, + ) { + let _timer = TIMER.timer_with(&["index_state_updates__collect_batch"]); + + let mut shard_iters = per_version_updates + .shards + .iter() + .map(|shard| shard.iter().cloned()) + .collect::>(); + + let mut first_version_to_collect = per_version_updates.first_version; + let mut remaining_versions = per_version_updates.num_versions; + let updates_for_last_checkpoint = last_checkpoint_index.map(|idx| { + let num_versions = idx + 1; + let ret = Self::collect_some_updates( + first_version_to_collect, + num_versions, + &mut shard_iters, + ); + first_version_to_collect += num_versions as Version; + remaining_versions -= num_versions; + ret + }); + let updates_for_latest = if remaining_versions == 0 { + None + } else { + Some(Self::collect_some_updates( + first_version_to_collect, + remaining_versions, + &mut shard_iters, + )) + }; + + // Assert that all updates are consumed. + assert!(shard_iters.iter_mut().all(|iter| iter.next().is_none())); + + (updates_for_last_checkpoint, updates_for_latest) + } + + fn collect_some_updates( + first_version: Version, + num_versions: usize, + shard_iters: &mut [impl Iterator)> + Clone + Send], + ) -> BatchedStateUpdateRefs<'kv> { + let mut ret = BatchedStateUpdateRefs::new_empty(first_version, num_versions); + // exclusive + let end_version = first_version + num_versions as Version; + shard_iters + .par_iter_mut() + .zip_eq(ret.shards.par_iter_mut()) + .for_each(|(shard_iter, dedupped)| { + dedupped.extend( + shard_iter + // n.b. take_while_ref so that in the next step we can process the rest of the entries from the iters. + .take_while_ref(|(_k, u)| u.version < end_version), + ) + }); + ret + } +} diff --git a/storage/storage-interface/src/state_store/state_view/async_proof_fetcher.rs b/storage/storage-interface/src/state_store/state_view/async_proof_fetcher.rs deleted file mode 100644 index 720e8e02ce52d..0000000000000 --- a/storage/storage-interface/src/state_store/state_view/async_proof_fetcher.rs +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{metrics::TIMER, DbReader}; -use anyhow::{anyhow, Result}; -use aptos_crypto::{hash::CryptoHash, HashValue}; -use aptos_logger::{error, sample, sample::SampleRate}; -use aptos_types::{ - proof::SparseMerkleProofExt, - state_store::{state_key::StateKey, state_value::StateValue}, - transaction::Version, -}; -use aptos_vm::AptosVM; -use crossbeam_channel::{unbounded, Receiver, Sender}; -use once_cell::sync::Lazy; -use std::{ - collections::HashMap, - string::ToString, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, - }, - time::Duration, -}; -use threadpool::ThreadPool; - -static IO_POOL: Lazy = Lazy::new(|| { - ThreadPool::with_name( - "proof_reader".to_string(), - AptosVM::get_num_proof_reading_threads(), - ) -}); - -struct Proof { - state_key_hash: HashValue, - proof: SparseMerkleProofExt, -} - -pub struct AsyncProofFetcher { - reader: Arc, - data_sender: Sender, - data_receiver: Receiver, - num_proofs_to_read: AtomicUsize, -} - -impl AsyncProofFetcher { - pub fn new(reader: Arc) -> Self { - let (data_sender, data_receiver) = unbounded(); - - Self { - reader, - data_sender, - data_receiver, - num_proofs_to_read: AtomicUsize::new(0), - } - } - - pub fn fetch_state_value( - &self, - state_key: &StateKey, - version: Version, - ) -> Result> { - let _timer = TIMER - .with_label_values(&["async_proof_fetcher_fetch"]) - .start_timer(); - Ok(self - .reader - .get_state_value_with_version_by_version(state_key, version)?) - } - - pub fn fetch_state_value_with_version_and_schedule_proof_read( - &self, - state_key: &StateKey, - version: Version, - subtree_root_depth: usize, - subtree_root_hash: Option, - ) -> Result> { - let version_and_value_opt = self.fetch_state_value(state_key, version)?; - self.schedule_proof_read( - state_key.clone(), - version, - subtree_root_depth, - subtree_root_hash, - version_and_value_opt.as_ref().map(|v| { - let state_value = &v.1; - state_value.hash() - }), - ); - Ok(version_and_value_opt) - } - - pub fn get_proof_cache(&self) -> HashMap { - self.wait() - } - - // Waits scheduled proof read to finish, and returns all read proofs. - // - // This is only expected to be called in a single thread, after all reads being scheduled. - fn wait(&self) -> HashMap { - let _timer = TIMER.with_label_values(&["wait_async_proof"]).start_timer(); - // TODO(grao): Find a way to verify the proof. - let mut proofs = HashMap::new(); - for _ in 0..self.num_proofs_to_read.load(Ordering::SeqCst) { - let data = self - .data_receiver - .recv() - .expect("Failed to receive proof on the channel."); - let Proof { - state_key_hash, - proof, - } = data; - proofs.insert(state_key_hash, proof); - } - self.num_proofs_to_read.store(0, Ordering::SeqCst); - proofs - } - - // Schedules proof reading work in a background running thread pool. - fn schedule_proof_read( - &self, - state_key: StateKey, - version: Version, - subtree_root_depth: usize, - subtree_root_hash: Option, - value_hash: Option, - ) { - let _timer = TIMER - .with_label_values(&["schedule_async_proof_read"]) - .start_timer(); - self.num_proofs_to_read.fetch_add(1, Ordering::SeqCst); - let reader = self.reader.clone(); - let data_sender = self.data_sender.clone(); - IO_POOL.execute(move || { - let proof = reader - .get_state_proof_by_version_ext(&state_key, version, subtree_root_depth) - .expect("Proof reading should succeed."); - // NOTE: Drop the reader here to make sure reader has shorter lifetime than the async - // proof fetcher. - drop(reader); - if let Some(subtree_root_hash) = subtree_root_hash { - proof - .verify_by_hash(subtree_root_hash, state_key.hash(), value_hash) - .map_err(|err| { - anyhow!( - "Proof is invalid for key {:?} with subtree root hash {:?}, depth {}, at version {}: {}.", - state_key, - subtree_root_hash, - subtree_root_depth, - version, - err - ) - }) - .expect("Failed to verify proof."); - } - match data_sender.send(Proof { - state_key_hash: state_key.hash(), - proof, - }) { - Ok(_) => {} - Err(_) => { - sample!( - SampleRate::Duration(Duration::from_secs(5)), - error!("Failed to send proof, something is wrong in execution.") - ); - } - } - }); - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::mock::MockDbReaderWriter; - use aptos_types::state_store::state_key::inner::StateKeyInner; - use assert_unordered::assert_eq_unordered; - - #[test] - fn test_fetch() { - let fetcher = AsyncProofFetcher::new(Arc::new(MockDbReaderWriter)); - let mut expected_key_hashes = vec![]; - for i in 0..10 { - let state_key: StateKey = StateKey::raw(format!("test_key_{}", i).as_bytes()); - expected_key_hashes.push(state_key.hash()); - let result = fetcher - .fetch_state_value_with_version_and_schedule_proof_read(&state_key, 0, 0, None) - .expect("Should not fail."); - let expected_value = StateValue::from(match state_key.inner() { - StateKeyInner::Raw(key) => key.to_owned(), - _ => unreachable!(), - }); - assert_eq!(result, Some((0, expected_value))); - } - - let proofs = fetcher.get_proof_cache(); - assert_eq!(proofs.len(), 10); - assert_eq_unordered!(proofs.into_keys().collect::>(), expected_key_hashes); - } -} diff --git a/storage/storage-interface/src/state_store/state_view/cached_state_view.rs b/storage/storage-interface/src/state_store/state_view/cached_state_view.rs index 271f395e9dd7c..24d8ed6eac484 100644 --- a/storage/storage-interface/src/state_store/state_view/cached_state_view.rs +++ b/storage/storage-interface/src/state_store/state_view/cached_state_view.rs @@ -3,32 +3,37 @@ use crate::{ metrics::TIMER, - state_store::state_view::{async_proof_fetcher::AsyncProofFetcher, db_state_view::DbStateView}, + state_store::{ + state::State, + state_delta::StateDelta, + state_update_refs::{BatchedStateUpdateRefs, StateUpdateRefs}, + state_view::db_state_view::DbStateView, + versioned_state_value::StateCacheEntry, + }, DbReader, }; -use aptos_crypto::{hash::CryptoHash, HashValue}; -use aptos_experimental_runtimes::thread_manager::THREAD_MANAGER; -use aptos_scratchpad::{FrozenSparseMerkleTree, SparseMerkleTree, StateStoreStatus}; +use anyhow::Result; +use aptos_metrics_core::TimerHelper; use aptos_types::{ - proof::SparseMerkleProofExt, state_store::{ - errors::StateViewError, state_key::StateKey, state_storage_usage::StateStorageUsage, - state_value::StateValue, StateViewId, TStateView, + state_key::StateKey, state_storage_usage::StateStorageUsage, state_value::StateValue, + StateViewId, StateViewResult, TStateView, }, transaction::Version, - write_set::WriteSet, }; use core::fmt; use dashmap::DashMap; use once_cell::sync::Lazy; use parking_lot::RwLock; -use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator}; +use rayon::prelude::*; use std::{ - collections::{HashMap, HashSet}, + collections::HashMap, fmt::{Debug, Formatter}, sync::Arc, }; +pub type StateCacheShard = DashMap; + static IO_POOL: Lazy = Lazy::new(|| { rayon::ThreadPoolBuilder::new() .num_threads(32) @@ -37,108 +42,51 @@ static IO_POOL: Lazy = Lazy::new(|| { .unwrap() }); -type Result = std::result::Result; -type StateCacheShard = DashMap, Option)>; - -// Sharded by StateKey.get_shard_id(). The version in the value indicates there is an entry on that -// version for the given StateKey, and the version is the maximum one which <= the base version. It -// will be None if the value is None, or we found the value on the speculative tree (in that case -// we don't know the maximum version). -#[derive(Debug, Default)] +#[derive(Debug)] pub struct ShardedStateCache { - shards: [StateCacheShard; 16], + next_version: Version, + pub shards: [StateCacheShard; 16], } impl ShardedStateCache { - pub fn combine(&mut self, rhs: Self) { - use rayon::prelude::*; - THREAD_MANAGER.get_exe_cpu_pool().install(|| { - self.shards - .par_iter_mut() - .zip_eq(rhs.shards.into_par_iter()) - .for_each(|(l, r)| { - for (k, (ver, val)) in r.into_iter() { - l.entry(k).or_insert((ver, val)); - } - }) - }); + pub fn new_empty(version: Option) -> Self { + Self { + next_version: version.map_or(0, |v| v + 1), + shards: Default::default(), + } } - pub fn shard(&self, shard_id: u8) -> &StateCacheShard { + fn shard(&self, shard_id: u8) -> &StateCacheShard { &self.shards[shard_id as usize] } - pub fn flatten(self) -> DashMap> { - // TODO(grao): Rethink the strategy for state sync, and optimize this. - self.shards - .into_iter() - .flatten() - .map(|(key, (_ver_opt, val_opt))| (key, val_opt)) - .collect() + pub fn get_cloned(&self, state_key: &StateKey) -> Option { + self.shard(state_key.get_shard_id()) + .get(state_key) + .map(|r| r.clone()) } - pub fn par_iter(&self) -> impl IndexedParallelIterator { - self.shards.par_iter() + pub fn next_version(&self) -> Version { + self.next_version } } /// `CachedStateView` is like a snapshot of the global state comprised of state view at two /// levels, persistent storage and memory. +/// TODO(aldenhu): This is actually MemorizingStateUpdateView? pub struct CachedStateView { /// For logging and debugging purpose, identifies what this view is for. id: StateViewId, - next_version: Version, + /// The persisted state is readable from the persist storage, at the version of + /// `self.speculative.base_version()` + reader: Arc, + + /// The in-memory state on top of known persisted state + speculative: StateDelta, - /// A readable snapshot in the persistent storage. - snapshot: Option<(Version, HashValue)>, - - /// The in-memory state on top of the snapshot. - speculative_state: FrozenSparseMerkleTree, - - /// The cache of verified account states from `reader` and `speculative_state_view`, - /// represented by a hashmap with an account address as key and a pair of an ordered - /// account state map and an an optional account state proof as value. When the VM queries an - /// `access_path`, this cache will first check whether `reader_cache` is hit. If hit, it - /// will return the corresponding value of that `access_path`; otherwise, the account state - /// will be loaded into the cache from scratchpad or persistent storage in order as a - /// deserialized ordered map and then be returned. If the VM queries this account again, - /// the cached data can be read directly without bothering storage layer. The proofs in - /// cache are needed by ScratchPad after VM execution to construct an in-memory sparse Merkle - /// tree. - /// ```text - /// +----------------------------+ - /// | In-memory SparseMerkleTree <------+ - /// +-------------^--------------+ | - /// | | - /// write sets | - /// | cached account state map - /// +-------+-------+ proof - /// | V M | | - /// +-------^-------+ | - /// | | - /// value of `account_address/path` | - /// | | - /// +---------------------------+---------------------+-------+ - /// | +-------------------------+---------------------+-----+ | - /// | | state_cache, state_key_to_proof_cache | | - /// | +---------------^---------------------------^---------+ | - /// | | | | - /// | state store values only state blob proof | - /// | | | | - /// | | | | - /// | +---------------+--------------+ +----------+---------+ | - /// | | speculative_state | | reader | | - /// | +------------------------------+ +--------------------+ | - /// +---------------------------------------------------------+ - /// ``` - /// Cache of state key to state value, which is used in case of fine grained storage object. - /// Eventually this should replace the `account_to_state_cache` as we deprecate account state blob - /// completely and migrate to fine grained storage. A value of None in this cache reflects that - /// the corresponding key has been deleted. This is a temporary hack until we support deletion - /// in JMT node. - sharded_state_cache: ShardedStateCache, - proof_fetcher: Arc, + /// State values (with update versions) read across the lifetime of the state view. + memorized: ShardedStateCache, } impl Debug for CachedStateView { @@ -151,150 +99,118 @@ impl CachedStateView { /// Constructs a [`CachedStateView`] with persistent state view in the DB and the in-memory /// speculative state represented by `speculative_state`. The persistent state view is the /// latest one preceding `next_version` - pub fn new( - id: StateViewId, - reader: Arc, - next_version: Version, - speculative_state: SparseMerkleTree, - proof_fetcher: Arc, - ) -> Result { - // n.b. Freeze the state before getting the state snapshot, otherwise it's possible that - // after we got the snapshot, in-mem trees newer than it gets dropped before being frozen, - // due to a commit happening from another thread. - let base_smt = reader.get_buffered_state_base()?; - let speculative_state = speculative_state.freeze(&base_smt); - let snapshot = reader - .get_state_snapshot_before(next_version) - .map_err(Into::::into)?; - - Ok(Self::new_impl( - id, - next_version, - snapshot, - speculative_state, - proof_fetcher, - )) + pub fn new(id: StateViewId, reader: Arc, state: State) -> StateViewResult { + let persisted_state = reader.get_persisted_state()?; + Ok(Self::new_impl(id, reader, persisted_state, state)) } pub fn new_impl( id: StateViewId, - next_version: Version, - snapshot: Option<(Version, HashValue)>, - speculative_state: FrozenSparseMerkleTree, - proof_fetcher: Arc, + reader: Arc, + persisted_state: State, + state: State, ) -> Self { Self { id, - next_version, - snapshot, - speculative_state, - sharded_state_cache: ShardedStateCache::default(), - proof_fetcher, + reader, + memorized: ShardedStateCache::new_empty(state.version()), + speculative: state.into_delta(persisted_state), } } - pub fn prime_cache_by_write_set<'a, T: IntoIterator + Send>( + pub fn new_dummy(state: &State) -> Self { + struct DummyDbReader; + impl DbReader for DummyDbReader {} + + Self { + id: StateViewId::Miscellaneous, + reader: Arc::new(DummyDbReader), + memorized: ShardedStateCache::new_empty(None), + speculative: state.make_delta(state), + } + } + + pub fn prime_cache(&self, updates: &StateUpdateRefs) -> Result<()> { + let _timer = TIMER.timer_with(&["prime_state_cache"]); + + IO_POOL.install(|| { + if let Some(updates) = &updates.for_last_checkpoint { + self.prime_cache_for_batched_updates(updates)?; + } + if let Some(updates) = &updates.for_latest { + self.prime_cache_for_batched_updates(updates)?; + } + Ok(()) + }) + } + + fn prime_cache_for_batched_updates(&self, updates: &BatchedStateUpdateRefs) -> Result<()> { + updates + .shards + .par_iter() + .try_for_each(|shard| self.prime_cache_for_keys(shard.keys().cloned())) + } + + fn prime_cache_for_keys<'a, T: IntoIterator + Send>( &self, - write_sets: T, + keys: T, ) -> Result<()> { - IO_POOL.scope(|s| { - write_sets - .into_iter() - .flat_map(|write_set| write_set.iter()) - .map(|(key, _)| key) - .collect::>() - .into_iter() - .for_each(|key| { - s.spawn(move |_| { - self.get_state_value_bytes(key).expect("Must succeed."); - }) - }); + rayon::scope(|s| { + keys.into_iter().for_each(|key| { + s.spawn(move |_| { + self.get_state_value(key).expect("Must succeed."); + }) + }); }); Ok(()) } - pub fn into_state_cache(self) -> StateCache { - StateCache { - frozen_base: self.speculative_state, - sharded_state_cache: self.sharded_state_cache, - proofs: self.proof_fetcher.get_proof_cache(), - } + /// Consumes `Self` and returns the state and all the memorized state reads. + pub fn into_memorized_reads(self) -> ShardedStateCache { + let Self { + id: _, + reader: _, + speculative: _, + memorized, + } = self; + + memorized } - fn get_version_and_state_value_internal( - &self, - state_key: &StateKey, - ) -> Result<(Option, Option)> { - // Do most of the work outside the write lock. - let key_hash = state_key.hash(); - match self.speculative_state.get(key_hash) { - StateStoreStatus::ExistsInScratchPad(value) => Ok((None, Some(value))), - StateStoreStatus::DoesNotExist => Ok((None, None)), - // Part of the tree is unknown, need to request proof for later usage (updating the tree) - StateStoreStatus::UnknownSubtreeRoot { - hash: subtree_root_hash, - depth: subtree_root_depth, - } => self.fetch_value_and_maybe_proof_in_snapshot( - state_key, - Some((subtree_root_hash, subtree_root_depth)), - ), - // Tree is known, but we only know the hash of the value, need to request the actual - // StateValue. - StateStoreStatus::UnknownValue => { - self.fetch_value_and_maybe_proof_in_snapshot(state_key, None) - }, - } + fn base_version(&self) -> Option { + self.speculative.base_version() } - fn fetch_value_and_maybe_proof_in_snapshot( - &self, - state_key: &StateKey, - fetch_proof: Option<(HashValue, usize)>, - ) -> Result<(Option, Option)> { - let version_and_value_opt = match self.snapshot { - None => None, - Some((version, _root_hash)) => match fetch_proof { - None => self.proof_fetcher.fetch_state_value(state_key, version)?, - Some((subtree_root_hash, subtree_depth)) => self - .proof_fetcher - .fetch_state_value_with_version_and_schedule_proof_read( - state_key, - version, - subtree_depth, - Some(subtree_root_hash), - )?, - }, + fn get_uncached(&self, state_key: &StateKey) -> Result { + let ret = if let Some(update) = self.speculative.get_state_update(state_key) { + // found in speculative state, can be either a new value or a deletion + update.to_state_value_with_version() + } else if let Some(base_version) = self.base_version() { + StateCacheEntry::from_tuple_opt( + self.reader + .get_state_value_with_version_by_version(state_key, base_version)?, + ) + } else { + StateCacheEntry::NonExistent }; - Ok(match version_and_value_opt { - None => (None, None), - Some((version, value)) => (Some(version), Some(value)), - }) + + Ok(ret) } pub fn next_version(&self) -> Version { - self.next_version + self.speculative.next_version() } -} -#[derive(Debug)] -pub struct StateCache { - pub frozen_base: FrozenSparseMerkleTree, - pub sharded_state_cache: ShardedStateCache, - pub proofs: HashMap, -} + pub fn current_state(&self) -> &State { + &self.speculative.current + } -impl StateCache { - pub fn new_empty(smt: SparseMerkleTree) -> Self { - let frozen_base = smt.freeze(&smt); - Self { - frozen_base, - sharded_state_cache: ShardedStateCache::default(), - proofs: HashMap::new(), - } + pub fn persisted_state(&self) -> &State { + &self.speculative.base } - pub fn new_dummy() -> Self { - Self::new_empty(SparseMerkleTree::new_empty()) + pub fn memorized_reads(&self) -> &ShardedStateCache { + &self.memorized } } @@ -305,32 +221,27 @@ impl TStateView for CachedStateView { self.id } - fn get_state_value(&self, state_key: &StateKey) -> Result> { + fn get_state_value(&self, state_key: &StateKey) -> StateViewResult> { let _timer = TIMER.with_label_values(&["get_state_value"]).start_timer(); // First check if the cache has the state value. - if let Some(version_and_value_opt) = self - .sharded_state_cache - .shard(state_key.get_shard_id()) - .get(state_key) - { - // This can return None, which means the value has been deleted from the DB. - let value_opt = &version_and_value_opt.1; - return Ok(value_opt.clone()); + if let Some(value_with_version_opt) = self.memorized.get_cloned(state_key) { + return Ok(value_with_version_opt.into_state_value_opt()); } - let version_and_state_value_option = - self.get_version_and_state_value_internal(state_key)?; + + // TODO(aldenhu): reduce duplicated gets + let value_with_version_opt = self.get_uncached(state_key)?; + // Update the cache if still empty - let new_version_and_value = self - .sharded_state_cache + let new_value_with_version_opt = self + .memorized .shard(state_key.get_shard_id()) .entry(state_key.clone()) - .or_insert(version_and_state_value_option); - let value_opt = &new_version_and_value.1; - Ok(value_opt.clone()) + .or_insert(value_with_version_opt); + Ok(new_value_with_version_opt.to_state_value_opt()) } - fn get_usage(&self) -> Result { - Ok(self.speculative_state.usage()) + fn get_usage(&self) -> StateViewResult { + Ok(self.speculative.current.usage()) } } @@ -355,7 +266,7 @@ impl TStateView for CachedDbStateView { self.db_state_view.id() } - fn get_state_value(&self, state_key: &StateKey) -> Result> { + fn get_state_value(&self, state_key: &StateKey) -> StateViewResult> { // First check if the cache has the state value. if let Some(val_opt) = self.state_cache.read().get(state_key) { // This can return None, which means the value has been deleted from the DB. @@ -370,7 +281,7 @@ impl TStateView for CachedDbStateView { Ok(new_value.clone()) } - fn get_usage(&self) -> Result { + fn get_usage(&self) -> StateViewResult { self.db_state_view.get_usage() } } diff --git a/storage/storage-interface/src/state_store/state_view/db_state_view.rs b/storage/storage-interface/src/state_store/state_view/db_state_view.rs index 5756a00db15e4..23bb67feae953 100644 --- a/storage/storage-interface/src/state_store/state_view/db_state_view.rs +++ b/storage/storage-interface/src/state_store/state_view/db_state_view.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::DbReader; -use aptos_crypto::{hash::CryptoHash, HashValue}; +use aptos_crypto::HashValue; use aptos_types::{ ledger_info::LedgerInfo, state_store::{ @@ -26,13 +26,14 @@ impl DbStateView { fn get(&self, key: &StateKey) -> StateViewResult> { if let Some(version) = self.version { if let Some(root_hash) = self.maybe_verify_against_state_root_hash { + // TODO(aldenhu): sample-verify proof inside DB // DB doesn't support returning proofs for buffered state, so only optionally // verify proof. // TODO: support returning state proof for buffered state. if let Ok((value, proof)) = self.db.get_state_value_with_proof_by_version(key, version) { - proof.verify(root_hash, CryptoHash::hash(key), value.as_ref())?; + proof.verify(root_hash, *key.crypto_hash_ref(), value.as_ref())?; return Ok(value); } } diff --git a/storage/storage-interface/src/state_store/state_view/mod.rs b/storage/storage-interface/src/state_store/state_view/mod.rs index 8600b7101ed50..aee8fa5e7a39b 100644 --- a/storage/storage-interface/src/state_store/state_view/mod.rs +++ b/storage/storage-interface/src/state_store/state_view/mod.rs @@ -2,6 +2,5 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -pub mod async_proof_fetcher; pub mod cached_state_view; pub mod db_state_view; diff --git a/storage/storage-interface/src/state_store/state_with_summary.rs b/storage/storage-interface/src/state_store/state_with_summary.rs new file mode 100644 index 0000000000000..d2bfdf686aca8 --- /dev/null +++ b/storage/storage-interface/src/state_store/state_with_summary.rs @@ -0,0 +1,119 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use crate::state_store::{ + state::{LedgerState, State}, + state_summary::{LedgerStateSummary, StateSummary}, +}; +use aptos_crypto::HashValue; +use aptos_scratchpad::SparseMerkleTree; +use aptos_types::{state_store::state_storage_usage::StateStorageUsage, transaction::Version}; +use derive_more::{Deref, DerefMut}; + +#[derive(Clone, Debug, Deref)] +pub struct StateWithSummary { + #[deref] + state: State, + summary: StateSummary, +} + +impl StateWithSummary { + pub fn new(state: State, summary: StateSummary) -> Self { + assert_eq!(state.next_version(), summary.next_version()); + Self { state, summary } + } + + pub fn new_empty() -> Self { + Self::new(State::new_empty(), StateSummary::new_empty()) + } + + pub fn new_at_version( + version: Option, + global_state_root_hash: HashValue, + usage: StateStorageUsage, + ) -> Self { + Self::new( + State::new_at_version(version, usage), + StateSummary::new_at_version(version, SparseMerkleTree::new(global_state_root_hash)), + ) + } + + pub fn state(&self) -> &State { + &self.state + } + + pub fn summary(&self) -> &StateSummary { + &self.summary + } + + pub fn is_descendant_of(&self, other: &Self) -> bool { + self.state.is_descendant_of(&other.state) && self.summary.is_descendant_of(&other.summary) + } +} + +#[derive(Clone, Debug, Deref, DerefMut)] +pub struct LedgerStateWithSummary { + #[deref] + #[deref_mut] + latest: StateWithSummary, + last_checkpoint: StateWithSummary, +} + +impl LedgerStateWithSummary { + pub fn from_latest_and_last_checkpoint( + latest: StateWithSummary, + last_checkpoint: StateWithSummary, + ) -> Self { + assert!(latest.is_descendant_of(&last_checkpoint)); + Self { + latest, + last_checkpoint, + } + } + + pub fn new_at_checkpoint(checkpoint: StateWithSummary) -> Self { + Self::from_latest_and_last_checkpoint(checkpoint.clone(), checkpoint) + } + + pub fn new_dummy() -> Self { + let empty = StateWithSummary::new_empty(); + Self::from_latest_and_last_checkpoint(empty.clone(), empty) + } + + pub fn from_state_and_summary(state: LedgerState, summary: LedgerStateSummary) -> Self { + Self::from_latest_and_last_checkpoint( + StateWithSummary::new(state.latest().clone(), summary.latest().clone()), + StateWithSummary::new( + state.last_checkpoint().clone(), + summary.last_checkpoint().clone(), + ), + ) + } + + pub fn last_checkpoint(&self) -> &StateWithSummary { + &self.last_checkpoint + } + + pub fn ledger_state(&self) -> LedgerState { + LedgerState::new( + self.latest.state().clone(), + self.last_checkpoint.state().clone(), + ) + } + + pub fn ledger_state_summary(&self) -> LedgerStateSummary { + LedgerStateSummary::new( + self.last_checkpoint.summary().clone(), + self.latest.summary().clone(), + ) + } + + pub fn to_state_and_summary(&self) -> (LedgerState, LedgerStateSummary) { + (self.ledger_state(), self.ledger_state_summary()) + } + + pub fn is_descendant_of(&self, rhs: &Self) -> bool { + self.latest.is_descendant_of(&rhs.latest) + && self.last_checkpoint.is_descendant_of(&rhs.last_checkpoint) + } +} diff --git a/storage/storage-interface/src/state_store/versioned_state_value.rs b/storage/storage-interface/src/state_store/versioned_state_value.rs new file mode 100644 index 0000000000000..3ac27980d84eb --- /dev/null +++ b/storage/storage-interface/src/state_store/versioned_state_value.rs @@ -0,0 +1,106 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use aptos_types::{state_store::state_value::StateValue, transaction::Version}; + +#[derive(Clone, Debug)] +pub struct StateUpdate { + /// The version where the key got updated (incl. deletion). + pub version: Version, + /// `None` indicates deletion. + pub value: Option, +} + +impl StateUpdate { + pub fn to_state_value_with_version(&self) -> StateCacheEntry { + use StateCacheEntry::*; + + match &self.value { + None => NonExistent, + Some(value) => Value { + version: self.version, + value: value.clone(), + }, + } + } +} + +#[derive(Clone, Debug)] +pub struct StateUpdateRef<'kv> { + /// The version where the key got updated (incl. deletion). + pub version: Version, + /// `None` indicates deletion. + pub value: Option<&'kv StateValue>, +} + +impl<'kv> StateUpdateRef<'kv> { + pub fn cloned(&self) -> StateUpdate { + StateUpdate { + version: self.version, + value: self.value.cloned(), + } + } +} + +#[derive(Clone, Debug)] +pub enum StateCacheEntry { + /// Not indicating if the value ever existed and deleted. + NonExistent, + /// A creation or modification. + Value { version: Version, value: StateValue }, +} + +impl StateCacheEntry { + // TODO(aldenhu): update DbReader interface to return this type directly. + pub fn from_tuple_opt(tuple_opt: Option<(Version, StateValue)>) -> Self { + match tuple_opt { + None => Self::NonExistent, + Some((version, value)) => Self::Value { version, value }, + } + } + + pub fn from_state_write_ref(version: Version, value_opt: Option<&StateValue>) -> Self { + match value_opt { + None => Self::NonExistent, + Some(value) => Self::Value { + version, + value: value.clone(), + }, + } + } + + pub fn from_state_update_ref(state_update_ref: &StateUpdateRef) -> Self { + match state_update_ref.value { + None => Self::NonExistent, + Some(value) => Self::Value { + version: state_update_ref.version, + value: value.clone(), + }, + } + } + + pub fn as_state_value_opt(&self) -> Option<&StateValue> { + match self { + Self::NonExistent => None, + Self::Value { value, .. } => Some(value), + } + } + + pub fn to_state_value_opt(&self) -> Option { + self.state_value_ref_opt().cloned() + } + + pub fn state_value_ref_opt(&self) -> Option<&StateValue> { + match self { + Self::NonExistent => None, + Self::Value { value, .. } => Some(value), + } + } + + pub fn into_state_value_opt(self) -> Option { + match self { + Self::NonExistent => None, + Self::Value { value, .. } => Some(value), + } + } +} diff --git a/testsuite/forge-cli/src/suites/land_blocking.rs b/testsuite/forge-cli/src/suites/land_blocking.rs index 5b2a2eafbe456..9cd6e219d9d99 100644 --- a/testsuite/forge-cli/src/suites/land_blocking.rs +++ b/testsuite/forge-cli/src/suites/land_blocking.rs @@ -2,7 +2,7 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use super::ungrouped::mixed_emit_job; +use super::ungrouped::mixed_compatible_emit_job; use crate::{suites::realistic_environment::realistic_env_max_load_test, TestCommand}; use aptos_forge::{success_criteria::SuccessCriteria, ForgeConfig}; use aptos_testcases::{ @@ -48,5 +48,5 @@ pub(crate) fn framework_upgrade() -> ForgeConfig { helm_values["chain"]["epoch_duration_secs"] = FrameworkUpgrade::EPOCH_DURATION_SECS.into(); })) - .with_emit_job(mixed_emit_job()) + .with_emit_job(mixed_compatible_emit_job()) } diff --git a/testsuite/forge-cli/src/suites/realistic_environment.rs b/testsuite/forge-cli/src/suites/realistic_environment.rs index dbb6a7351a9fd..2f767bec89960 100644 --- a/testsuite/forge-cli/src/suites/realistic_environment.rs +++ b/testsuite/forge-cli/src/suites/realistic_environment.rs @@ -179,7 +179,7 @@ pub(crate) fn realistic_env_fairness_workload_sweep() -> ForgeConfig { ]), criteria: Vec::new(), background_traffic: background_traffic_for_sweep_with_latency( - &[(2.0, 3.0, 8.0), (0.1, 25.0, 30.0), (0.1, 30.0, 40.0)], + &[(2.0, 3.0, 8.0), (0.1, 25.0, 30.0), (0.1, 30.0, 45.0)], false, ), }) @@ -217,8 +217,10 @@ pub(crate) fn realistic_env_graceful_workload_sweep() -> ForgeConfig { (0.1, 2.2, 3.0), (0.1, 3.5, 5.0), (0.1, 4.0, 6.0), - (0.1, 2.5, 4.0), - (0.1, 3.5, 5.0), + // TODO - p50 and p90 is set to high, until it is calibrated/understood. + (0.1, 3.0, 5.0), + // TODO - p50 and p90 is set to high, until it is calibrated/understood. + (0.1, 5.0, 10.0), // TODO - p50 and p90 is set to high, until it is calibrated/understood. (0.1, 3.0, 10.0), ], @@ -485,7 +487,7 @@ pub(crate) fn realistic_network_tuned_for_throughput_test() -> ForgeConfig { ); } else { forge_config = forge_config.with_success_criteria( - SuccessCriteria::new(12000) + SuccessCriteria::new(11000) .add_no_restarts() /* This test runs at high load, so we need more catchup time */ .add_wait_for_catchup_s(120), diff --git a/testsuite/forge-cli/src/suites/ungrouped.rs b/testsuite/forge-cli/src/suites/ungrouped.rs index 2830e63712dec..8dcc2528bdd79 100644 --- a/testsuite/forge-cli/src/suites/ungrouped.rs +++ b/testsuite/forge-cli/src/suites/ungrouped.rs @@ -543,6 +543,80 @@ pub fn mixed_emit_job() -> EmitJobRequest { ]) } +// framework_usecases can have new features, so might fail publishing. +pub fn mixed_compatible_emit_job() -> EmitJobRequest { + EmitJobRequest::default() + .mode(EmitJobMode::MaxLoad { + mempool_backlog: 10000, + }) + .transaction_mix(vec![ + // To test both variants, make module publish with such frequency, so that there are + // similar number of sequential and parallel blocks. + // For other transactions, make more expensive transactions somewhat rarer. + ( + TransactionTypeArg::AccountGeneration.materialize_default(), + 10000, + ), + ( + TransactionTypeArg::CoinTransfer.materialize_default(), + 10000, + ), + (TransactionTypeArg::PublishPackage.materialize_default(), 3), + ( + TransactionTypeArg::Batch100Transfer.materialize_default(), + 100, + ), + ( + TransactionTypeArg::VectorPicture30k.materialize_default(), + 100, + ), + ( + TransactionTypeArg::SmartTablePicture30KWith200Change.materialize( + 1, + true, + WorkflowProgress::when_done_default(), + ), + 100, + ), + ( + TransactionTypeArg::TokenV2AmbassadorMint.materialize_default(), + 10000, + ), + // ( + // TransactionTypeArg::ModifyGlobalResource.materialize_default(), + // 1000, + // ), + // ( + // TransactionTypeArg::ModifyGlobalResourceAggV2.materialize_default(), + // 1000, + // ), + // ( + // TransactionTypeArg::ModifyGlobalFlagAggV2.materialize_default(), + // 1000, + // ), + // ( + // TransactionTypeArg::ModifyGlobalBoundedAggV2.materialize_default(), + // 1000, + // ), + // ( + // TransactionTypeArg::ResourceGroupsGlobalWriteTag1KB.materialize_default(), + // 1000, + // ), + // ( + // TransactionTypeArg::ResourceGroupsGlobalWriteAndReadTag1KB.materialize_default(), + // 1000, + // ), + // ( + // TransactionTypeArg::TokenV1NFTMintAndTransferSequential.materialize_default(), + // 1000, + // ), + // ( + // TransactionTypeArg::TokenV1FTMintAndTransfer.materialize_default(), + // 10000, + // ), + ]) +} + fn fullnode_reboot_stress_test() -> ForgeConfig { ForgeConfig::default() .with_initial_validator_count(NonZeroUsize::new(7).unwrap()) diff --git a/testsuite/forge/src/config.rs b/testsuite/forge/src/config.rs index 61584befb8752..940589e7fb3b1 100644 --- a/testsuite/forge/src/config.rs +++ b/testsuite/forge/src/config.rs @@ -170,7 +170,6 @@ impl ForgeConfig { let existing_db_tag = self.existing_db_tag.clone(); let validator_resource_override = self.validator_resource_override; let fullnode_resource_override = self.fullnode_resource_override; - let suite_name = self.get_suite_name(); // Override specific helm values. See reference: terraform/helm/aptos-node/values.yaml Some(Arc::new(move |helm_values: &mut serde_yaml::Value| { @@ -239,17 +238,6 @@ impl ForgeConfig { ["enable_storage_sharding"] = true.into(); helm_values["validator"]["config"]["indexer_db_config"]["enable_event"] = true.into(); helm_values["fullnode"]["config"]["indexer_db_config"]["enable_event"] = true.into(); - - // This is a temporary hack to disable new pipeline for compat tests. - if !suite_name - .as_ref() - .is_some_and(|name| name.eq_ignore_ascii_case("compat")) - { - // enable new pipeline - helm_values["validator"]["config"]["consensus"]["enable_pipeline"] = true.into(); - helm_values["fullnode"]["config"]["consensus_observer"]["enable_pipeline"] = - true.into(); - } })) } diff --git a/testsuite/generate-format/tests/staged/api.yaml b/testsuite/generate-format/tests/staged/api.yaml index 72e38f150ea12..cef28c8ec8e5c 100644 --- a/testsuite/generate-format/tests/staged/api.yaml +++ b/testsuite/generate-format/tests/staged/api.yaml @@ -11,6 +11,13 @@ AbortLocation: TYPENAME: ModuleId 1: Script: UNIT +AbstractionAuthData: + ENUM: + 0: + V1: + STRUCT: + - signing_message_digest: BYTES + - authenticator: BYTES AccessPath: STRUCT: - address: @@ -49,6 +56,13 @@ AccountAuthenticator: TYPENAME: MultiKeyAuthenticator 4: NoAccountAuthenticator: UNIT + 5: + Abstraction: + STRUCT: + - function_info: + TYPENAME: FunctionInfo + - auth_data: + TYPENAME: AbstractionAuthData AggregateSignature: STRUCT: - validator_bitmask: @@ -321,6 +335,12 @@ FederatedKeylessPublicKey: TYPENAME: AccountAddress - pk: TYPENAME: KeylessPublicKey +FunctionInfo: + STRUCT: + - module_address: + TYPENAME: AccountAddress + - module_name: STR + - function_name: STR G1Bytes: NEWTYPESTRUCT: TUPLEARRAY: diff --git a/testsuite/generate-format/tests/staged/aptos.yaml b/testsuite/generate-format/tests/staged/aptos.yaml index 5e5c9c0e80697..d3067b891d50c 100644 --- a/testsuite/generate-format/tests/staged/aptos.yaml +++ b/testsuite/generate-format/tests/staged/aptos.yaml @@ -1,4 +1,11 @@ --- +AbstractionAuthData: + ENUM: + 0: + V1: + STRUCT: + - signing_message_digest: BYTES + - authenticator: BYTES AccessPath: STRUCT: - address: @@ -37,6 +44,13 @@ AccountAuthenticator: TYPENAME: MultiKeyAuthenticator 4: NoAccountAuthenticator: UNIT + 5: + Abstraction: + STRUCT: + - function_info: + TYPENAME: FunctionInfo + - auth_data: + TYPENAME: AbstractionAuthData AggregateSignature: STRUCT: - validator_bitmask: @@ -267,6 +281,12 @@ FederatedKeylessPublicKey: TYPENAME: AccountAddress - pk: TYPENAME: KeylessPublicKey +FunctionInfo: + STRUCT: + - module_address: + TYPENAME: AccountAddress + - module_name: STR + - function_name: STR G1Bytes: NEWTYPESTRUCT: TUPLEARRAY: diff --git a/testsuite/generate-format/tests/staged/consensus.yaml b/testsuite/generate-format/tests/staged/consensus.yaml index f9bb0aaf27da6..193d04823025c 100644 --- a/testsuite/generate-format/tests/staged/consensus.yaml +++ b/testsuite/generate-format/tests/staged/consensus.yaml @@ -1,4 +1,11 @@ --- +AbstractionAuthData: + ENUM: + 0: + V1: + STRUCT: + - signing_message_digest: BYTES + - authenticator: BYTES AccessPath: STRUCT: - address: @@ -37,6 +44,13 @@ AccountAuthenticator: TYPENAME: MultiKeyAuthenticator 4: NoAccountAuthenticator: UNIT + 5: + Abstraction: + STRUCT: + - function_info: + TYPENAME: FunctionInfo + - auth_data: + TYPENAME: AbstractionAuthData AggregateSignature: STRUCT: - validator_bitmask: @@ -540,6 +554,12 @@ FederatedKeylessPublicKey: TYPENAME: AccountAddress - pk: TYPENAME: KeylessPublicKey +FunctionInfo: + STRUCT: + - module_address: + TYPENAME: AccountAddress + - module_name: STR + - function_name: STR G1Bytes: NEWTYPESTRUCT: TUPLEARRAY: diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/permissioned_transfer.move b/testsuite/module-publish/src/packages/framework_usecases/sources/permissioned_transfer.move new file mode 100644 index 0000000000000..8b97e4576a081 --- /dev/null +++ b/testsuite/module-publish/src/packages/framework_usecases/sources/permissioned_transfer.move @@ -0,0 +1,24 @@ + +module 0xABCD::permissioned_transfer { + use aptos_framework::aptos_account; + // use aptos_framework::permissioned_signer; + use aptos_framework::primary_fungible_store; + + // public entry fun transfer_permissioned( + // source: &signer, to: address, amount: u64 + // ) { + // let handle = permissioned_signer::create_permissioned_handle(source); + // let permissioned_signer = permissioned_signer::signer_from_permissioned_handle(&handle); + + // primary_fungible_store::grant_apt_permission(source, &permissioned_signer, amount); + // aptos_account::transfer(&permissioned_signer, to, amount); + + // permissioned_signer::destroy_permissioned_handle(handle); + // } + + public entry fun transfer( + source: &signer, to: address, amount: u64 + ) { + aptos_account::transfer(source, to, amount); + } +} diff --git a/testsuite/single_node_performance.py b/testsuite/single_node_performance.py index 456e65d3ca8d0..8a024a117fa03 100755 --- a/testsuite/single_node_performance.py +++ b/testsuite/single_node_performance.py @@ -33,6 +33,8 @@ class Flow(Flag): RESOURCE_GROUPS = auto() # Test different executor types EXECUTORS = auto() + # For when testing locally, quick inclusion of specific cases + ADHOC = auto() # Tests that are run on LAND_BLOCKING and continuously on main @@ -217,7 +219,7 @@ class RunGroupConfig: RunGroupConfig(expected_tps=8000, key=RunGroupKey("resource-groups-global-write-and-read-tag1-kb", module_working_set_size=DEFAULT_MODULE_WORKING_SET_SIZE), included_in=Flow.RESOURCE_GROUPS, waived=True), RunGroupConfig(key=RunGroupKey("resource-groups-sender-write-tag1-kb"), included_in=Flow.CONTINUOUS | Flow.RESOURCE_GROUPS), RunGroupConfig(expected_tps=8000, key=RunGroupKey("resource-groups-sender-write-tag1-kb", module_working_set_size=DEFAULT_MODULE_WORKING_SET_SIZE), included_in=Flow.RESOURCE_GROUPS, waived=True), - RunGroupConfig(key=RunGroupKey("resource-groups-sender-multi-change1-kb"), included_in=LAND_BLOCKING_AND_C | Flow.RESOURCE_GROUPS), + RunGroupConfig(key=RunGroupKey("resource-groups-sender-multi-change1-kb"), included_in=LAND_BLOCKING_AND_C | Flow.RESOURCE_GROUPS | Flow.ADHOC), RunGroupConfig(expected_tps=8000, key=RunGroupKey("resource-groups-sender-multi-change1-kb", module_working_set_size=DEFAULT_MODULE_WORKING_SET_SIZE), included_in=Flow.RESOURCE_GROUPS, waived=True), RunGroupConfig(key=RunGroupKey("token-v1ft-mint-and-transfer"), included_in=Flow.CONTINUOUS), @@ -657,7 +659,7 @@ def print_table( execute_command(f"cargo build {BUILD_FLAG} --package aptos-executor-benchmark") print(f"Warmup - creating DB with {NUM_ACCOUNTS} accounts") - create_db_command = f"RUST_BACKTRACE=1 {BUILD_FOLDER}/aptos-executor-benchmark --block-executor-type aptos-vm-with-block-stm --block-size {MAX_BLOCK_SIZE} --execution-threads {NUMBER_OF_EXECUTION_THREADS} {DB_CONFIG_FLAGS} {DB_PRUNER_FLAGS} create-db {FEATURE_FLAGS} --data-dir {tmpdirname}/db --num-accounts {NUM_ACCOUNTS}" + create_db_command = f"PUSH_METRICS_NAMESPACE=benchmark-create-db RUST_BACKTRACE=1 {BUILD_FOLDER}/aptos-executor-benchmark --block-executor-type aptos-vm-with-block-stm --block-size {MAX_BLOCK_SIZE} --execution-threads {NUMBER_OF_EXECUTION_THREADS} {DB_CONFIG_FLAGS} {DB_PRUNER_FLAGS} create-db {FEATURE_FLAGS} --data-dir {tmpdirname}/db --num-accounts {NUM_ACCOUNTS}" output = execute_command(create_db_command) results = [] diff --git a/testsuite/single_node_performance_values.tsv b/testsuite/single_node_performance_values.tsv index 2b51c2a36d97f..0604b33518c3b 100644 --- a/testsuite/single_node_performance_values.tsv +++ b/testsuite/single_node_performance_values.tsv @@ -1,50 +1,50 @@ -no-op 1 VM 34 0.830 1.028 38708.6 -no-op 1000 VM 34 0.848 1.034 36862.7 -apt-fa-transfer 1 VM 34 0.887 1.029 27051.6 -apt-fa-transfer 1 NativeVM 34 0.861 1.084 32411.9 -account-generation 1 VM 35 0.868 1.031 20493.5 -account-generation 1 NativeVM 35 0.851 1.074 28612.4 -account-resource32-b 1 VM 35 0.833 1.028 34327.5 -modify-global-resource 1 VM 35 0.896 1.014 2295.2 -modify-global-resource 100 VM 35 0.871 1.030 33526.5 -publish-package 1 VM 35 0.858 1.018 1666.6 -mix_publish_transfer 1 VM 35 0.857 1.039 21446.3 -batch100-transfer 1 VM 36 0.855 1.035 633.4 -batch100-transfer 1 NativeVM 36 0.848 1.136 1397.0 -vector-picture30k 1 VM 36 0.940 1.035 109.6 -vector-picture30k 100 VM 36 0.751 1.071 1872.7 -smart-table-picture30-k-with200-change 1 VM 36 0.924 1.059 16.2 -smart-table-picture30-k-with200-change 100 VM 36 0.914 1.079 207.6 -modify-global-resource-agg-v2 1 VM 36 0.893 1.022 34731.8 -modify-global-flag-agg-v2 1 VM 36 0.944 1.022 4307.7 -modify-global-bounded-agg-v2 1 VM 36 0.940 1.087 7869.2 -modify-global-milestone-agg-v2 1 VM 36 0.873 1.019 25276.9 -resource-groups-global-write-tag1-kb 1 VM 36 0.893 1.035 9338.6 -resource-groups-global-write-and-read-tag1-kb 1 VM 36 0.914 1.018 5668.8 -resource-groups-sender-write-tag1-kb 1 VM 36 0.840 1.101 20531.0 -resource-groups-sender-multi-change1-kb 1 VM 36 0.917 1.087 17029.7 -token-v1ft-mint-and-transfer 1 VM 36 0.928 1.018 1167.3 -token-v1ft-mint-and-transfer 100 VM 36 0.878 1.018 18222.3 -token-v1nft-mint-and-transfer-sequential 1 VM 36 0.946 1.014 751.5 -token-v1nft-mint-and-transfer-sequential 100 VM 36 0.903 1.012 12957.5 -coin-init-and-mint 1 VM 36 0.907 1.023 27051.6 -coin-init-and-mint 100 VM 36 0.888 1.018 22432.9 -fungible-asset-mint 1 VM 36 0.883 1.040 22878.7 -fungible-asset-mint 100 VM 36 0.888 1.029 19900.0 -no-op5-signers 1 VM 36 0.859 1.022 38925.3 -token-v2-ambassador-mint 1 VM 36 0.923 1.026 15528.4 -token-v2-ambassador-mint 100 VM 36 0.957 1.026 15498.8 -liquidity-pool-swap 1 VM 36 0.942 1.016 767.7 -liquidity-pool-swap 100 VM 36 0.943 1.020 10761.9 -liquidity-pool-swap-stable 1 VM 36 0.954 1.016 730.4 -liquidity-pool-swap-stable 100 VM 36 0.942 1.023 10321.9 -deserialize-u256 1 VM 36 0.952 1.021 37283.8 -no-op-fee-payer 1 VM 36 0.967 1.023 2103.7 -no-op-fee-payer 100 VM 36 0.944 1.016 32540.5 -simple-script 1 VM 36 0.943 1.027 38063.3 -vector-trim-append-len3000-size1 1 VM 36 0.928 1.067 548.0 -vector-remove-insert-len3000-size1 1 VM 36 0.920 1.033 554.4 -no_commit_apt-fa-transfer 1 VM 36 0.971 1.021 29411.8 -no_commit_apt-fa-transfer 1 NativeVM 36 0.957 1.015 45350.3 -no_commit_apt-fa-transfer 1 AptosVMSpeculative 36 0.961 1.009 1831.5 -no_commit_apt-fa-transfer 1 NativeSpeculative 36 0.886 1.031 110171.2 +no-op 1 VM 12 0.939 1.023 41212.4 +no-op 1000 VM 12 0.949 1.012 39434.0 +apt-fa-transfer 1 VM 12 0.907 1.039 28301.2 +apt-fa-transfer 1 NativeVM 12 0.920 1.066 34462.0 +account-generation 1 VM 12 0.897 1.013 22432.9 +account-generation 1 NativeVM 12 0.888 1.095 30075.3 +account-resource32-b 1 VM 12 0.943 1.036 36029.2 +modify-global-resource 1 VM 12 0.973 1.009 2343.5 +modify-global-resource 100 VM 12 0.973 1.021 35070.6 +publish-package 1 VM 12 0.961 1.016 1200 +mix_publish_transfer 1 VM 12 0.961 1.017 22960.6 +batch100-transfer 1 VM 12 0.931 1.020 731.7 +batch100-transfer 1 NativeVM 12 0.932 1.113 1387.1 +vector-picture30k 1 VM 12 0.993 1.032 106.2 +vector-picture30k 100 VM 12 0.896 1.125 1743.3 +smart-table-picture30-k-with200-change 1 VM 12 0.943 1.025 16.3 +smart-table-picture30-k-with200-change 100 VM 12 0.978 1.042 200.3 +modify-global-resource-agg-v2 1 VM 12 0.946 1.028 37283.8 +modify-global-flag-agg-v2 1 VM 12 0.975 1.008 4375.3 +modify-global-bounded-agg-v2 1 VM 12 0.949 1.069 7779.0 +modify-global-milestone-agg-v2 1 VM 12 0.974 1.026 26287.6 +resource-groups-global-write-tag1-kb 1 VM 12 0.938 1.043 8869.9 +resource-groups-global-write-and-read-tag1-kb 1 VM 12 0.968 1.014 5689.1 +resource-groups-sender-write-tag1-kb 1 VM 12 0.963 1.112 17569.3 +resource-groups-sender-multi-change1-kb 1 VM 12 0.916 1.100 14870.3 +token-v1ft-mint-and-transfer 1 VM 12 0.968 1.025 1171.7 +token-v1ft-mint-and-transfer 100 VM 12 0.985 1.011 19174.6 +token-v1nft-mint-and-transfer-sequential 1 VM 12 0.970 1.012 774.6 +token-v1nft-mint-and-transfer-sequential 100 VM 12 0.978 1.015 13796.3 +coin-init-and-mint 1 VM 12 0.961 1.020 28045.4 +coin-init-and-mint 100 VM 12 0.970 1.013 23583.0 +fungible-asset-mint 1 VM 12 0.959 1.032 23751.6 +fungible-asset-mint 100 VM 12 0.940 1.015 20984.9 +no-op5-signers 1 VM 12 0.966 1.021 41212.4 +token-v2-ambassador-mint 1 VM 12 0.955 1.020 16078.7 +token-v2-ambassador-mint 100 VM 12 0.955 1.032 15984.6 +liquidity-pool-swap 1 VM 12 0.942 1.005 812.7 +liquidity-pool-swap 100 VM 12 0.950 1.012 11854.7 +liquidity-pool-swap-stable 1 VM 12 0.948 1.011 780.1 +liquidity-pool-swap-stable 100 VM 12 0.936 1.018 11459.8 +deserialize-u256 1 VM 12 0.927 1.023 38997.7 +no-op-fee-payer 1 VM 12 0.876 1.018 2112.0 +no-op-fee-payer 100 VM 12 0.960 1.017 33327.8 +simple-script 1 VM 12 0.952 1.020 40242.3 +vector-trim-append-len3000-size1 1 VM 12 0.942 1.039 564.0 +vector-remove-insert-len3000-size1 1 VM 12 0.961 1.041 531.1 +no_commit_apt-fa-transfer 1 VM 12 0.942 1.010 30646.3 +no_commit_apt-fa-transfer 1 NativeVM 12 0.943 1.021 49310.8 +no_commit_apt-fa-transfer 1 AptosVMSpeculative 12 0.982 1.005 1801.4 +no_commit_apt-fa-transfer 1 NativeSpeculative 12 0.987 1.017 95514.8 diff --git a/testsuite/smoke-test/Cargo.toml b/testsuite/smoke-test/Cargo.toml index 07fdf4b1af195..e08175b1fdb60 100644 --- a/testsuite/smoke-test/Cargo.toml +++ b/testsuite/smoke-test/Cargo.toml @@ -54,6 +54,7 @@ diesel = { workspace = true, features = [ digest = { workspace = true } hex = { workspace = true } hyper = { workspace = true } +move-binary-format = { workspace = true } move-core-types = { workspace = true } reqwest = { workspace = true } serde = { workspace = true } diff --git a/testsuite/smoke-test/src/keyless.rs b/testsuite/smoke-test/src/keyless.rs index 612ef3a556cf9..22c1457a47af9 100644 --- a/testsuite/smoke-test/src/keyless.rs +++ b/testsuite/smoke-test/src/keyless.rs @@ -31,7 +31,7 @@ use aptos_types::{ }, AnyKeylessPublicKey, Configuration, EphemeralCertificate, Groth16ProofAndStatement, Groth16VerificationKey, KeylessPublicKey, KeylessSignature, TransactionAndProof, - DEVNET_VERIFICATION_KEY, KEYLESS_ACCOUNT_MODULE_NAME, + KEYLESS_ACCOUNT_MODULE_NAME, VERIFICATION_KEY_FOR_TESTING, }, on_chain_config::{FeatureFlag, Features}, transaction::{ @@ -891,6 +891,25 @@ pub(crate) async fn spawn_network_and_execute_gov_proposals( .await .expect("Epoch 2 taking too long to come!"); + let vk_for_testing = Groth16VerificationKey::from(VERIFICATION_KEY_FOR_TESTING.clone()); + let script = get_rotate_vk_governance_script(&vk_for_testing); + + let gas_options = GasOptions { + gas_unit_price: Some(100), + max_gas: Some(2000000), + expiration_secs: 60, + }; + let txn_summary = cli + .run_script_with_gas_options(root_idx, &script, Some(gas_options.clone())) + .await + .unwrap(); + debug!("txn_summary={:?}", txn_summary); + + let mut info = swarm.aptos_public_info(); + + // Increment sequence number since we installed the VK + info.root_account().increment_sequence_number(); + let vk = print_account_resource::( &client, AccountAddress::ONE, @@ -900,10 +919,7 @@ pub(crate) async fn spawn_network_and_execute_gov_proposals( ) .await; - assert_eq!( - vk, - Groth16VerificationKey::from(DEVNET_VERIFICATION_KEY.clone()) - ); + assert_eq!(vk, vk_for_testing); let old_config = print_account_resource::( &client, @@ -962,11 +978,6 @@ fun main(core_resources: &signer) {{ hex::encode(training_wheels_pk.to_bytes()) ); - let gas_options = GasOptions { - gas_unit_price: Some(100), - max_gas: Some(2000000), - expiration_secs: 60, - }; let txn_summary = cli .run_script_with_gas_options(root_idx, &script, Some(gas_options)) .await @@ -998,8 +1009,6 @@ fun main(core_resources: &signer) {{ assert_ne!(old_config, new_config); assert_eq!(new_config.max_exp_horizon_secs, max_exp_horizon_secs); - let mut info = swarm.aptos_public_info(); - // Increment sequence number since we patched a JWK info.root_account().increment_sequence_number(); @@ -1014,12 +1023,7 @@ async fn get_latest_jwkset(rest_client: &Client) -> PatchedJWKs { response.into_inner() } -async fn rotate_vk_by_governance<'a>( - cli: &mut CliTestFramework, - info: &mut AptosPublicInfo, - vk: &Groth16VerificationKey, - root_idx: usize, -) { +fn get_rotate_vk_governance_script(vk: &Groth16VerificationKey) -> String { let script = format!( r#" script {{ @@ -1045,6 +1049,17 @@ script {{ ); debug!("Move script for changing VK follows below:\n{:?}", script); + script +} + +async fn rotate_vk_by_governance<'a>( + cli: &mut CliTestFramework, + info: &mut AptosPublicInfo, + vk: &Groth16VerificationKey, + root_idx: usize, +) { + let script = get_rotate_vk_governance_script(vk); + print_account_resource::( info.client(), AccountAddress::ONE, diff --git a/testsuite/smoke-test/src/upgrade.rs b/testsuite/smoke-test/src/upgrade.rs index 5e0ce9fa0bc59..5cca2bc44c5c1 100644 --- a/testsuite/smoke-test/src/upgrade.rs +++ b/testsuite/smoke-test/src/upgrade.rs @@ -20,6 +20,7 @@ use aptos_release_builder::{ }; use aptos_temppath::TempPath; use aptos_types::on_chain_config::{FeatureFlag as AptosFeatureFlag, OnChainConsensusConfig}; +use move_binary_format::file_format_common::VERSION_DEFAULT_LANG_V2; use std::{fs, path::PathBuf, process::Command, sync::Arc}; // Ignored. This is redundant with the forge compat test but this test is easier to run locally and @@ -113,7 +114,7 @@ async fn test_upgrade_flow() { name: "framework".to_string(), metadata: ProposalMetadata::default(), update_sequence: vec![ReleaseEntry::Framework(FrameworkReleaseConfig { - bytecode_version: 6, // TODO: remove explicit bytecode version from sources + bytecode_version: VERSION_DEFAULT_LANG_V2, // TODO: remove explicit bytecode version from sources git_hash: None, })], }, diff --git a/third_party/copy.bara.sky b/third_party/copy.bara.sky index 574f5a9c49548..0589561a9be71 100644 --- a/third_party/copy.bara.sky +++ b/third_party/copy.bara.sky @@ -1,4 +1,4 @@ -moveUrl = "https://github.com/move-language/move.git" +moveUrl = "https://github.com/move-language/move-on-aptos.git" aptosUrl = "https://github.com/aptos-labs/aptos-core.git" # Workflow to pull from Move to Aptos. This creates a draft PR at the fixed branch `from_move` @@ -7,7 +7,7 @@ core.workflow( name = "pull_move", origin = git.github_origin( url = moveUrl, - ref = "aptos-main", + ref = "main", ), destination = git.destination( url = "NOT_SET", # use --git-destination-url to set this @@ -33,7 +33,7 @@ core.workflow( ), destination = git.destination( url = "NOT_SET", # use --git-destination-url to set this - fetch = "aptos-main", + fetch = "main", push = "to_move", integrates = [], ), @@ -55,7 +55,7 @@ core.workflow( ), destination = git.github_destination( url = moveUrl, - push = "aptos-main", + push = "main", ), mode = "ITERATIVE", origin_files = glob(["third_party/move/**"]), diff --git a/third_party/move/evm/hardhat-examples/.gitignore b/third_party/move/evm/hardhat-examples/.gitignore deleted file mode 100644 index 36077f28843de..0000000000000 --- a/third_party/move/evm/hardhat-examples/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -node_modules -.env -coverage -coverage.json -typechain - -#Hardhat files -cache -artifacts diff --git a/third_party/move/evm/hardhat-examples/README.md b/third_party/move/evm/hardhat-examples/README.md deleted file mode 100644 index 99cb758c27b59..0000000000000 --- a/third_party/move/evm/hardhat-examples/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# 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/third_party/move/evm/hardhat-examples/contracts/ABIStruct/Move.toml b/third_party/move/evm/hardhat-examples/contracts/ABIStruct/Move.toml deleted file mode 100644 index 3dd2c9a0556d9..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ABIStruct/Move.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "ABIStruct" -version = "0.0.0" - -[addresses] -std = "0x1" -Evm = "0x2" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/ABIStruct/sources/ABIStruct.move b/third_party/move/evm/hardhat-examples/contracts/ABIStruct/sources/ABIStruct.move deleted file mode 100644 index f33cbe459d97a..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ABIStruct/sources/ABIStruct.move +++ /dev/null @@ -1,77 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/Callee.sol b/third_party/move/evm/hardhat-examples/contracts/Callee.sol deleted file mode 100644 index 998c54f82b037..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Callee.sol +++ /dev/null @@ -1,22 +0,0 @@ -//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/third_party/move/evm/hardhat-examples/contracts/Caller/Move.toml b/third_party/move/evm/hardhat-examples/contracts/Caller/Move.toml deleted file mode 100644 index 00a74aab94510..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Caller/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "Caller" -version = "0.0.0" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/Caller/sources/Caller.move b/third_party/move/evm/hardhat-examples/contracts/Caller/sources/Caller.move deleted file mode 100644 index aa31f25cc1298..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Caller/sources/Caller.move +++ /dev/null @@ -1,50 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/ERC1155Mock/Move.toml b/third_party/move/evm/hardhat-examples/contracts/ERC1155Mock/Move.toml deleted file mode 100644 index e0d87065e5e0b..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC1155Mock/Move.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "ERC1155Mock" -version = "0.0.0" - -[addresses] -std = "0x1" -Evm = "0x2" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } -MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/ERC1155Mock/sources/ERC1155Mock.move b/third_party/move/evm/hardhat-examples/contracts/ERC1155Mock/sources/ERC1155Mock.move deleted file mode 100644 index 6fde3ba2278d0..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC1155Mock/sources/ERC1155Mock.move +++ /dev/null @@ -1,389 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/ERC1155Mock_Sol.sol b/third_party/move/evm/hardhat-examples/contracts/ERC1155Mock_Sol.sol deleted file mode 100644 index 300a460e0dcef..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC1155Mock_Sol.sol +++ /dev/null @@ -1,51 +0,0 @@ -// 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/third_party/move/evm/hardhat-examples/contracts/ERC1155ReceiverMock.sol b/third_party/move/evm/hardhat-examples/contracts/ERC1155ReceiverMock.sol deleted file mode 100644 index 18e68e58f2137..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC1155ReceiverMock.sol +++ /dev/null @@ -1,53 +0,0 @@ -// 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/third_party/move/evm/hardhat-examples/contracts/ERC1155Tradable/Move.toml b/third_party/move/evm/hardhat-examples/contracts/ERC1155Tradable/Move.toml deleted file mode 100644 index ee54facc63446..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC1155Tradable/Move.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "ERC1155Tradable" -version = "0.0.0" - -[addresses] -std = "0x1" -Evm = "0x2" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } -MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/ERC1155Tradable/sources/ERC1155Tradable.move b/third_party/move/evm/hardhat-examples/contracts/ERC1155Tradable/sources/ERC1155Tradable.move deleted file mode 100644 index 3988cc418cd26..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC1155Tradable/sources/ERC1155Tradable.move +++ /dev/null @@ -1,466 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/ERC20DecimalsMock/Move.toml b/third_party/move/evm/hardhat-examples/contracts/ERC20DecimalsMock/Move.toml deleted file mode 100644 index 2140b03a26b6f..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC20DecimalsMock/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "ERC20DecimalsMock" -version = "0.0.0" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/ERC20DecimalsMock/sources/ERC20DecimalsMock.move b/third_party/move/evm/hardhat-examples/contracts/ERC20DecimalsMock/sources/ERC20DecimalsMock.move deleted file mode 100644 index b6f357136118e..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC20DecimalsMock/sources/ERC20DecimalsMock.move +++ /dev/null @@ -1,203 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/ERC20DecimalsMock_Sol.sol b/third_party/move/evm/hardhat-examples/contracts/ERC20DecimalsMock_Sol.sol deleted file mode 100644 index c98c405080a6b..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC20DecimalsMock_Sol.sol +++ /dev/null @@ -1,29 +0,0 @@ -//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/third_party/move/evm/hardhat-examples/contracts/ERC20Mock/Move.toml b/third_party/move/evm/hardhat-examples/contracts/ERC20Mock/Move.toml deleted file mode 100644 index c52b490464925..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC20Mock/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "ERC20Mock" -version = "0.0.0" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/ERC20Mock/sources/ERC20Mock.move b/third_party/move/evm/hardhat-examples/contracts/ERC20Mock/sources/ERC20Mock.move deleted file mode 100644 index 1fdeb475c9274..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC20Mock/sources/ERC20Mock.move +++ /dev/null @@ -1,223 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/ERC20Mock_Sol.sol b/third_party/move/evm/hardhat-examples/contracts/ERC20Mock_Sol.sol deleted file mode 100644 index 56f7c7d159389..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC20Mock_Sol.sol +++ /dev/null @@ -1,40 +0,0 @@ -//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/third_party/move/evm/hardhat-examples/contracts/ERC721Mock/Move.toml b/third_party/move/evm/hardhat-examples/contracts/ERC721Mock/Move.toml deleted file mode 100644 index 58d6786a1186f..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC721Mock/Move.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "ERC721Mock" -version = "0.0.0" - -[addresses] -std = "0x1" -Evm = "0x2" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } -MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/ERC721Mock/sources/ERC721Mock.move b/third_party/move/evm/hardhat-examples/contracts/ERC721Mock/sources/ERC721Mock.move deleted file mode 100644 index 4b92e421b7463..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC721Mock/sources/ERC721Mock.move +++ /dev/null @@ -1,366 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/ERC721Mock_Sol.sol b/third_party/move/evm/hardhat-examples/contracts/ERC721Mock_Sol.sol deleted file mode 100644 index e4c7f03cb4164..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC721Mock_Sol.sol +++ /dev/null @@ -1,41 +0,0 @@ -// 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/third_party/move/evm/hardhat-examples/contracts/ERC721ReceiverMock.sol b/third_party/move/evm/hardhat-examples/contracts/ERC721ReceiverMock.sol deleted file mode 100644 index e1885b045e2d6..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC721ReceiverMock.sol +++ /dev/null @@ -1,48 +0,0 @@ -// 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/third_party/move/evm/hardhat-examples/contracts/ERC721Tradable/Move.toml b/third_party/move/evm/hardhat-examples/contracts/ERC721Tradable/Move.toml deleted file mode 100644 index 0c8b6d3befb5f..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC721Tradable/Move.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "ERC721Tradable" -version = "0.0.0" - -[addresses] -std = "0x1" -Evm = "0x2" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } -MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/ERC721Tradable/sources/ERC721Tradable.move b/third_party/move/evm/hardhat-examples/contracts/ERC721Tradable/sources/ERC721Tradable.move deleted file mode 100644 index 8f942552c1ab7..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC721Tradable/sources/ERC721Tradable.move +++ /dev/null @@ -1,368 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/ERC721Tradable_Sol.sol b/third_party/move/evm/hardhat-examples/contracts/ERC721Tradable_Sol.sol deleted file mode 100644 index f522b0673433e..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ERC721Tradable_Sol.sol +++ /dev/null @@ -1,52 +0,0 @@ -// 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/third_party/move/evm/hardhat-examples/contracts/Event.sol b/third_party/move/evm/hardhat-examples/contracts/Event.sol deleted file mode 100644 index 837b6108c85fc..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Event.sol +++ /dev/null @@ -1,52 +0,0 @@ -//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/third_party/move/evm/hardhat-examples/contracts/Event/Move.toml b/third_party/move/evm/hardhat-examples/contracts/Event/Move.toml deleted file mode 100644 index c342d3ae79ece..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Event/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "Event" -version = "0.0.0" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/Event/sources/Event.move b/third_party/move/evm/hardhat-examples/contracts/Event/sources/Event.move deleted file mode 100644 index 3f7bfc9dc8b4e..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Event/sources/Event.move +++ /dev/null @@ -1,85 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/ExternalCall/Move.toml b/third_party/move/evm/hardhat-examples/contracts/ExternalCall/Move.toml deleted file mode 100644 index 53f95e038e5c5..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ExternalCall/Move.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "ExternalCall" -version = "0.0.0" - -[addresses] -std = "0x1" -Evm = "0x2" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } -MoveStdlib = { local = "../../../../move-stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/ExternalCall/sources/ExternalCall.move b/third_party/move/evm/hardhat-examples/contracts/ExternalCall/sources/ExternalCall.move deleted file mode 100644 index cb433ca94d93c..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/ExternalCall/sources/ExternalCall.move +++ /dev/null @@ -1,118 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/FortyTwo.sol b/third_party/move/evm/hardhat-examples/contracts/FortyTwo.sol deleted file mode 100644 index fe82d58043b00..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/FortyTwo.sol +++ /dev/null @@ -1,20 +0,0 @@ -//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/third_party/move/evm/hardhat-examples/contracts/FortyTwo/Move.toml b/third_party/move/evm/hardhat-examples/contracts/FortyTwo/Move.toml deleted file mode 100644 index 6ceee8f8c5b26..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/FortyTwo/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "FortyTwo" -version = "0.0.0" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/FortyTwo/sources/FortyTwo.move b/third_party/move/evm/hardhat-examples/contracts/FortyTwo/sources/FortyTwo.move deleted file mode 100644 index 8bf7e639b8f9c..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/FortyTwo/sources/FortyTwo.move +++ /dev/null @@ -1,25 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/Greeter.sol b/third_party/move/evm/hardhat-examples/contracts/Greeter.sol deleted file mode 100644 index 30d7d7f08a63e..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Greeter.sol +++ /dev/null @@ -1,22 +0,0 @@ -//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/third_party/move/evm/hardhat-examples/contracts/Greeter/Move.toml b/third_party/move/evm/hardhat-examples/contracts/Greeter/Move.toml deleted file mode 100644 index 08403d0cbd779..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Greeter/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "Greeter" -version = "0.0.0" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/Greeter/sources/Greeter.move b/third_party/move/evm/hardhat-examples/contracts/Greeter/sources/Greeter.move deleted file mode 100644 index 99c5a11f340ab..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Greeter/sources/Greeter.move +++ /dev/null @@ -1,29 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/Native.sol b/third_party/move/evm/hardhat-examples/contracts/Native.sol deleted file mode 100644 index 4c8365bc5f254..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Native.sol +++ /dev/null @@ -1,20 +0,0 @@ -//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/third_party/move/evm/hardhat-examples/contracts/Native/Move.toml b/third_party/move/evm/hardhat-examples/contracts/Native/Move.toml deleted file mode 100644 index b75025cf48ec9..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Native/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "Native" -version = "0.0.0" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/Native/sources/Native.move b/third_party/move/evm/hardhat-examples/contracts/Native/sources/Native.move deleted file mode 100644 index c2117dd3cea9f..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Native/sources/Native.move +++ /dev/null @@ -1,19 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/Revert.sol b/third_party/move/evm/hardhat-examples/contracts/Revert.sol deleted file mode 100644 index 11e5f8ea47bb2..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Revert.sol +++ /dev/null @@ -1,15 +0,0 @@ -//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/third_party/move/evm/hardhat-examples/contracts/Revert/Move.toml b/third_party/move/evm/hardhat-examples/contracts/Revert/Move.toml deleted file mode 100644 index b71d5e0baedeb..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Revert/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "Revert" -version = "0.0.0" - -[dependencies] -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/Revert/sources/Revert.move b/third_party/move/evm/hardhat-examples/contracts/Revert/sources/Revert.move deleted file mode 100644 index d58015b4a48fc..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Revert/sources/Revert.move +++ /dev/null @@ -1,17 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/contracts/StructABI_Sol.sol b/third_party/move/evm/hardhat-examples/contracts/StructABI_Sol.sol deleted file mode 100644 index 1391ee769e4c5..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/StructABI_Sol.sol +++ /dev/null @@ -1,32 +0,0 @@ -//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/third_party/move/evm/hardhat-examples/contracts/Token/Move.toml b/third_party/move/evm/hardhat-examples/contracts/Token/Move.toml deleted file mode 100644 index 8d4fd46543b0e..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Token/Move.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "Token" -version = "0.0.0" - -[dependencies] -MoveStdlib = { local = "../../../../move-stdlib" } -EvmStdlib = { local = "../../../stdlib" } diff --git a/third_party/move/evm/hardhat-examples/contracts/Token/sources/Token.move b/third_party/move/evm/hardhat-examples/contracts/Token/sources/Token.move deleted file mode 100644 index 2b772e34cead9..0000000000000 --- a/third_party/move/evm/hardhat-examples/contracts/Token/sources/Token.move +++ /dev/null @@ -1,75 +0,0 @@ -#[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/third_party/move/evm/hardhat-examples/hardhat.config.js b/third_party/move/evm/hardhat-examples/hardhat.config.js deleted file mode 100644 index f1a8bd579c1ec..0000000000000 --- a/third_party/move/evm/hardhat-examples/hardhat.config.js +++ /dev/null @@ -1,52 +0,0 @@ -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/third_party/move/evm/hardhat-examples/package-lock.json b/third_party/move/evm/hardhat-examples/package-lock.json deleted file mode 100644 index c10b7f6cd7097..0000000000000 --- a/third_party/move/evm/hardhat-examples/package-lock.json +++ /dev/null @@ -1,24228 +0,0 @@ -{ - "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/third_party/move/evm/hardhat-examples/package.json b/third_party/move/evm/hardhat-examples/package.json deleted file mode 100644 index c3a4462e40a4a..0000000000000 --- a/third_party/move/evm/hardhat-examples/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "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/third_party/move/evm/hardhat-examples/scripts/deploy_ERC1155.js b/third_party/move/evm/hardhat-examples/scripts/deploy_ERC1155.js deleted file mode 100644 index 987a3c53c44d1..0000000000000 --- a/third_party/move/evm/hardhat-examples/scripts/deploy_ERC1155.js +++ /dev/null @@ -1,23 +0,0 @@ -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/third_party/move/evm/hardhat-examples/scripts/deploy_ERC20.js b/third_party/move/evm/hardhat-examples/scripts/deploy_ERC20.js deleted file mode 100644 index 4bafa8ea693cc..0000000000000 --- a/third_party/move/evm/hardhat-examples/scripts/deploy_ERC20.js +++ /dev/null @@ -1,21 +0,0 @@ -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/third_party/move/evm/hardhat-examples/scripts/deploy_ERC721.js b/third_party/move/evm/hardhat-examples/scripts/deploy_ERC721.js deleted file mode 100644 index 2ee98f3431f20..0000000000000 --- a/third_party/move/evm/hardhat-examples/scripts/deploy_ERC721.js +++ /dev/null @@ -1,26 +0,0 @@ -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/third_party/move/evm/hardhat-examples/scripts/sample-script.js b/third_party/move/evm/hardhat-examples/scripts/sample-script.js deleted file mode 100644 index 90cd8197e0585..0000000000000 --- a/third_party/move/evm/hardhat-examples/scripts/sample-script.js +++ /dev/null @@ -1,32 +0,0 @@ -// We require the Hardhat Runtime Environment explicitly here. This is optional -// but useful for running the script in a standalone fashion through `node