diff --git a/Cargo.lock b/Cargo.lock index 3d33e1ddd1..3ba41188ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,7 +39,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" dependencies = [ "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -59,9 +59,9 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -203,7 +203,7 @@ dependencies = [ "hex", "jsonrpc-core-client", "rpassword", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-crypto", "starcoin-logger", @@ -243,6 +243,15 @@ dependencies = [ "governor", ] +[[package]] +name = "arbitrary" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d47fbf90d5149a107494b15a7dc8d69b351be2db3bb9691740e88ec17fd880" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "arc-swap" version = "1.5.1" @@ -270,6 +279,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "ascii" version = "1.0.0" @@ -416,9 +431,9 @@ version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -548,11 +563,11 @@ checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" [[package]] name = "bcs" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510fd83e3eaf7263b06182f3550b4c0af2af42cb36ab8024969ff5ea7fcb2833" +checksum = "8b06b4c1f053002b70e7084ac944c77d58d5d92b2110dbc5e852735e00ad3ccc" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", "thiserror", ] @@ -562,15 +577,9 @@ version = "1.12.9" dependencies = [ "anyhow", "bcs", - "serde 1.0.140", + "serde 1.0.151", ] -[[package]] -name = "bech32" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" - [[package]] name = "bech32" version = "0.9.0" @@ -618,6 +627,26 @@ dependencies = [ "starcoin-vm-types", ] +[[package]] +name = "better_any" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b359aebd937c17c725e19efcb661200883f04c49c53e7132224dac26da39d4a0" +dependencies = [ + "better_typeid_derive", +] + +[[package]] +name = "better_typeid_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3deeecb812ca5300b7d3f66f730cc2ebd3511c3d36c691dd79c165d5b19a26e3" +dependencies = [ + "proc-macro2 1.0.49", + "quote 1.0.20", + "syn 1.0.107", +] + [[package]] name = "bimap" version = "0.6.2" @@ -630,7 +659,7 @@ version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -648,7 +677,7 @@ dependencies = [ "lazycell", "log 0.4.17", "peeking_take_while", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", "regex", "rustc-hash", @@ -693,7 +722,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" dependencies = [ "either", - "radium", + "radium 0.3.0", +] + +[[package]] +name = "bitvec" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +dependencies = [ + "funty", + "radium 0.6.2", + "tap", + "wyz", ] [[package]] @@ -799,7 +840,7 @@ dependencies = [ "lazy_static 1.4.0", "memchr", "regex-automata", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -814,6 +855,12 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + [[package]] name = "byte-tools" version = "0.3.1" @@ -823,7 +870,7 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytecode-interpreter-crypto" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "curve25519-dalek-fiat", @@ -1088,9 +1135,9 @@ checksum = "9ba52acd3b0a5c33aeada5cdaa3267cdc7c594a98731d4268cdc1532f4264cb4" dependencies = [ "heck 0.4.0", "proc-macro-error", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -1150,7 +1197,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52899426b69706219a1aaee2e95868fd01a0bd8006bb163f069578a0af5b5bb2" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", "unicode-segmentation", ] @@ -1161,7 +1208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3362992a0d9f1dd7c3d0e89e0ab2bb540b7a95fea8cd798090e758fda2899b5e" dependencies = [ "codespan-reporting", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -1170,7 +1217,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", "termcolor", "unicode-width", ] @@ -1186,6 +1233,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes 1.2.1", + "memchr", +] + [[package]] name = "concurrent-queue" version = "1.2.4" @@ -1204,7 +1261,7 @@ dependencies = [ "lazy_static 1.4.0", "nom 5.1.2", "rust-ini", - "serde 1.0.140", + "serde 1.0.151", "serde-hjson", "serde_json", "toml", @@ -1240,7 +1297,7 @@ dependencies = [ "hex", "rlp", "rlp-derive", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-crypto", "starcoin-executor", @@ -1326,7 +1383,7 @@ dependencies = [ "plotters", "rayon", "regex", - "serde 1.0.140", + "serde 1.0.151", "serde_cbor", "serde_derive", "serde_json", @@ -1506,7 +1563,7 @@ dependencies = [ "csv-core", "itoa 0.4.8", "ryu", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -1525,7 +1582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" dependencies = [ "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -1662,10 +1719,10 @@ checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", "strsim 0.9.3", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -1676,10 +1733,10 @@ checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", "strsim 0.10.0", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -1701,7 +1758,7 @@ checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" dependencies = [ "darling_core 0.10.2", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -1712,7 +1769,7 @@ checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core 0.13.4", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -1789,7 +1846,7 @@ dependencies = [ "move-binary-format", "move-bytecode-verifier", "pprof", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-account-api", "starcoin-accumulator", @@ -1825,9 +1882,20 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", + "quote 1.0.20", + "syn 1.0.107", +] + +[[package]] +name = "derive_arbitrary" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a16495aeb28047bb1185fca837baf755e7d71ed3aeed7f8504654ffa927208" +dependencies = [ + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -1862,10 +1930,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", "rustc_version 0.4.0", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -1899,7 +1967,7 @@ dependencies = [ "rand 0.8.5", "rand_core 0.6.3", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde-name 0.1.2", "serde_bytes", "sha2 0.9.9", @@ -1914,9 +1982,9 @@ name = "diem-crypto-derive" version = "0.0.3" source = "git+https://github.com/starcoinorg/starcoin-crypto?rev=d871dfb4216f034ee334a575926c101574d9d6dc#d871dfb4216f034ee334a575926c101574d9d6dc" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -2034,7 +2102,7 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", "signature", ] @@ -2047,7 +2115,7 @@ dependencies = [ "curve25519-dalek", "ed25519", "rand 0.7.3", - "serde 1.0.140", + "serde 1.0.151", "sha2 0.9.9", "zeroize", ] @@ -2061,7 +2129,7 @@ dependencies = [ "curve25519-dalek-fiat", "ed25519", "rand 0.8.5", - "serde 1.0.140", + "serde 1.0.151", "serde_bytes", "sha2 0.9.9", "zeroize", @@ -2085,7 +2153,7 @@ dependencies = [ "percent-encoding 2.1.0", "reqwest 0.10.10", "rustc_version 0.2.3", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "serde_with", "url 2.2.2", @@ -2120,9 +2188,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4" dependencies = [ "heck 0.4.0", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -2195,7 +2263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71a6567e6fd35589fea0c63b94b4cf2e55573e413901bdbe60ab15cf0e25e5df" dependencies = [ "crunchy", - "fixed-hash", + "fixed-hash 0.6.1", "impl-rlp", "impl-serde", "tiny-keccak", @@ -2208,10 +2276,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "473aecff686bd8e7b9db0165cbbb53562376b39bf35b427f0c60446a9e1634b0" dependencies = [ "ethbloom", - "fixed-hash", + "fixed-hash 0.6.1", "impl-rlp", "impl-serde", - "primitive-types", + "primitive-types 0.7.3", "uint 0.8.5", ] @@ -2294,6 +2362,18 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder 1.4.3", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + [[package]] name = "fixedbitset" version = "0.2.0" @@ -2356,7 +2436,7 @@ dependencies = [ "proptest-derive", "rand 0.8.5", "rand_core 0.6.3", - "serde 1.0.140", + "serde 1.0.151", "serde_bytes", "starcoin-crypto", "starcoin-logger", @@ -2401,6 +2481,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + [[package]] name = "futures" version = "0.1.31" @@ -2492,9 +2578,9 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -2597,7 +2683,7 @@ dependencies = [ "hex", "jsonrpc-core-client", "rpassword", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-crypto", "starcoin-rpc-api", @@ -2683,9 +2769,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -2841,7 +2927,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -3160,7 +3246,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" dependencies = [ - "parity-scale-codec", + "parity-scale-codec 1.3.7", +] + +[[package]] +name = "impl-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" +dependencies = [ + "parity-scale-codec 2.3.1", ] [[package]] @@ -3178,7 +3273,18 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2 1.0.49", + "quote 1.0.20", + "syn 1.0.107", ] [[package]] @@ -3200,9 +3306,9 @@ checksum = "0a0c890c85da4bab7bce4204c707396bbd3c6c8a681716a51c8814cfc2b682df" dependencies = [ "anyhow", "proc-macro-hack", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -3304,7 +3410,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" dependencies = [ "socket2 0.3.19", - "widestring", + "widestring 0.4.3", "winapi 0.3.9", "winreg 0.6.2", ] @@ -3355,7 +3461,7 @@ dependencies = [ "jsonpath-plus", "once_cell", "regex", - "serde 1.0.140", + "serde 1.0.151", "serde_json", ] @@ -3377,7 +3483,7 @@ dependencies = [ "error-chain 0.11.0", "pest 1.0.6", "pest_derive 1.0.8", - "serde 1.0.140", + "serde 1.0.151", "serde_json", ] @@ -3407,7 +3513,7 @@ dependencies = [ "jsonrpc-server-utils", "log 0.4.17", "parity-tokio-ipc", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "tokio 1.20.1", "url 1.7.2", @@ -3424,7 +3530,7 @@ dependencies = [ "futures-executor", "futures-util", "log 0.4.17", - "serde 1.0.140", + "serde 1.0.151", "serde_derive", "serde_json", ] @@ -3446,9 +3552,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2" dependencies = [ "proc-macro-crate 0.1.5", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -3494,7 +3600,7 @@ dependencies = [ "log 0.4.17", "parking_lot 0.11.2", "rand 0.7.3", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -3832,7 +3938,7 @@ dependencies = [ "sha2 0.10.2", "smallvec 1.10.0", "thiserror", - "uint 0.9.3", + "uint 0.9.5", "unsigned-varint 0.7.1", "void", ] @@ -4052,7 +4158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33b4d0acd47739fe0b570728d8d11bbb535050d84c0cf05d6477a4891fceae10" dependencies = [ "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -4157,7 +4263,7 @@ dependencies = [ "libsecp256k1-gen-ecmult", "libsecp256k1-gen-genmult", "rand 0.8.5", - "serde 1.0.140", + "serde 1.0.151", "sha2 0.9.9", "typenum", ] @@ -4269,7 +4375,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if 1.0.0", - "serde 1.0.140", + "serde 1.0.151", "value-bag", ] @@ -4296,7 +4402,7 @@ dependencies = [ "log 0.4.17", "log-mdc", "parking_lot 0.12.1", - "serde 1.0.140", + "serde 1.0.151", "serde-value", "serde_json", "serde_yaml", @@ -4391,7 +4497,7 @@ dependencies = [ "csv", "hex", "merkletree", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "sha3 0.9.1", "starcoin-crypto", @@ -4409,7 +4515,7 @@ dependencies = [ "memmap2", "positioned-io", "rayon", - "serde 1.0.140", + "serde 1.0.151", "tempfile", "typenum", ] @@ -4540,47 +4646,45 @@ checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" [[package]] name = "move-abigen" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bcs", "heck 0.3.3", "log 0.4.17", + "move-binary-format", "move-bytecode-verifier", "move-command-line-common", "move-core-types", "move-model", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-binary-format" version = "0.0.3" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", - "mirai-annotations", + "arbitrary", "move-core-types", "once_cell", "proptest", "proptest-derive", "ref-cast", - "serde 1.0.140", + "serde 1.0.151", "variant_count", ] [[package]] name = "move-borrow-graph" version = "0.0.1" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" -dependencies = [ - "mirai-annotations", -] +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" [[package]] name = "move-bytecode-source-map" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bcs", @@ -4589,13 +4693,13 @@ dependencies = [ "move-core-types", "move-ir-types", "move-symbol-pool", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-bytecode-utils" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "move-binary-format", @@ -4607,10 +4711,9 @@ dependencies = [ [[package]] name = "move-bytecode-verifier" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", - "mirai-annotations", "move-binary-format", "move-borrow-graph", "move-core-types", @@ -4620,7 +4723,7 @@ dependencies = [ [[package]] name = "move-bytecode-viewer" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "clap 3.2.15", @@ -4637,7 +4740,7 @@ dependencies = [ [[package]] name = "move-cli" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bcs", @@ -4656,6 +4759,7 @@ dependencies = [ "move-core-types", "move-coverage 0.1.0", "move-disassembler", + "move-docgen", "move-errmapgen", "move-ir-types", "move-package", @@ -4665,25 +4769,33 @@ dependencies = [ "move-symbol-pool", "move-unit-test", "move-vm-runtime", + "move-vm-test-utils", "move-vm-types", "once_cell", "read-write-set", "read-write-set-dynamic", - "serde 1.0.140", + "reqwest 0.11.11", + "serde 1.0.151", + "serde_json", "serde_yaml", "tempfile", + "toml_edit", "walkdir", ] [[package]] name = "move-command-line-common" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "difference", + "dirs-next", "hex", - "serde 1.0.140", + "move-core-types", + "num-bigint", + "once_cell", + "serde 1.0.151", "sha2 0.9.9", "walkdir", ] @@ -4691,7 +4803,7 @@ dependencies = [ [[package]] name = "move-compiler" version = "0.0.1" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bcs", @@ -4712,34 +4824,39 @@ dependencies = [ "once_cell", "petgraph 0.5.1", "regex", + "sha3 0.9.1", "tempfile", "walkdir", ] [[package]] name = "move-core-types" -version = "0.0.3" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +version = "0.0.4" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", + "arbitrary", "bcs", - "bech32 0.8.1", + "bech32", + "ethnum", "hex", - "mirai-annotations", + "num", "once_cell", + "primitive-types 0.10.1", "proptest", "proptest-derive", "rand 0.8.5", "ref-cast", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_bytes", + "uint 0.9.5", ] [[package]] name = "move-coverage" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bcs", @@ -4753,7 +4870,7 @@ dependencies = [ "move-ir-types", "once_cell", "petgraph 0.5.1", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -4770,13 +4887,13 @@ dependencies = [ "move-command-line-common", "move-coverage 0.1.0", "petgraph 0.5.1", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-disassembler" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "clap 3.2.15", @@ -4794,7 +4911,7 @@ dependencies = [ [[package]] name = "move-docgen" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "codespan 0.11.1", @@ -4806,13 +4923,13 @@ dependencies = [ "num", "once_cell", "regex", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-errmapgen" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bcs", @@ -4820,13 +4937,13 @@ dependencies = [ "move-command-line-common", "move-core-types", "move-model", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-ir-compiler" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bcs", @@ -4845,7 +4962,7 @@ dependencies = [ [[package]] name = "move-ir-to-bytecode" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "codespan-reporting", @@ -4864,7 +4981,7 @@ dependencies = [ [[package]] name = "move-ir-to-bytecode-syntax" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "hex", @@ -4877,7 +4994,7 @@ dependencies = [ [[package]] name = "move-ir-types" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "hex", @@ -4885,13 +5002,13 @@ dependencies = [ "move-core-types", "move-symbol-pool", "once_cell", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-model" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "codespan 0.11.1", @@ -4911,19 +5028,20 @@ dependencies = [ "num", "once_cell", "regex", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-package" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bcs", "clap 3.2.15", "colored", "dirs-next", + "itertools", "move-abigen", "move-binary-format", "move-bytecode-source-map", @@ -4939,12 +5057,14 @@ dependencies = [ "petgraph 0.5.1", "ptree", "regex", - "serde 1.0.140", + "reqwest 0.11.11", + "serde 1.0.151", "serde_yaml", "sha2 0.9.9", "tempfile", "toml", "walkdir", + "whoami", ] [[package]] @@ -4974,6 +5094,7 @@ dependencies = [ "move-package", "move-unit-test", "move-vm-runtime", + "move-vm-test-utils", "once_cell", "starcoin-account-provider", "starcoin-cmd", @@ -4997,7 +5118,7 @@ dependencies = [ [[package]] name = "move-prover" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "async-trait", @@ -5024,7 +5145,7 @@ dependencies = [ "once_cell", "pretty", "rand 0.8.5", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "simplelog", "tokio 1.20.1", @@ -5034,7 +5155,7 @@ dependencies = [ [[package]] name = "move-prover-boogie-backend" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "async-trait", @@ -5053,7 +5174,7 @@ dependencies = [ "pretty", "rand 0.8.5", "regex", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "tera", "tokio 1.20.1", @@ -5062,7 +5183,7 @@ dependencies = [ [[package]] name = "move-prover-test-utils" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "move-command-line-common", @@ -5073,32 +5194,33 @@ dependencies = [ [[package]] name = "move-read-write-set-types" version = "0.0.3" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "move-binary-format", "move-core-types", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-resource-viewer" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bcs", "hex", "move-binary-format", + "move-bytecode-utils", "move-core-types", "once_cell", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-stackless-bytecode" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "codespan 0.11.1", "codespan-reporting", @@ -5110,6 +5232,7 @@ dependencies = [ "move-borrow-graph", "move-bytecode-verifier", "move-command-line-common", + "move-compiler", "move-core-types", "move-ir-to-bytecode", "move-model", @@ -5118,13 +5241,13 @@ dependencies = [ "once_cell", "paste", "petgraph 0.5.1", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-stackless-bytecode-interpreter" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "bytecode-interpreter-crypto", @@ -5135,16 +5258,17 @@ dependencies = [ "move-core-types", "move-model", "move-stackless-bytecode", - "move-vm-runtime", "num", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "move-stdlib" -version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +version = "0.1.1" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ + "anyhow", + "hex", "log 0.4.17", "move-binary-format", "move-command-line-common", @@ -5164,16 +5288,33 @@ dependencies = [ [[package]] name = "move-symbol-pool" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "once_cell", - "serde 1.0.140", + "serde 1.0.151", +] + +[[package]] +name = "move-table-extension" +version = "0.1.0" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" +dependencies = [ + "anyhow", + "bcs", + "better_any", + "move-binary-format", + "move-core-types", + "move-vm-runtime", + "move-vm-types", + "once_cell", + "sha3 0.9.1", + "smallvec 1.10.0", ] [[package]] name = "move-transactional-test-runner" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "clap 3.2.15", @@ -5183,6 +5324,7 @@ dependencies = [ "move-binary-format", "move-bytecode-source-map", "move-bytecode-utils", + "move-bytecode-verifier", "move-cli", "move-command-line-common", "move-compiler", @@ -5207,23 +5349,30 @@ dependencies = [ [[package]] name = "move-unit-test" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", + "better_any", "clap 3.2.15", + "codespan-reporting", "colored", + "itertools", "move-binary-format", "move-bytecode-utils", "move-command-line-common", "move-compiler", "move-core-types", + "move-ir-types", "move-model", "move-resource-viewer", "move-stackless-bytecode-interpreter", "move-stdlib", + "move-symbol-pool", + "move-table-extension", "move-vm-runtime", "move-vm-test-utils", "move-vm-types", + "once_cell", "rayon", "regex", ] @@ -5231,10 +5380,10 @@ dependencies = [ [[package]] name = "move-vm-runtime" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ + "better_any", "fail", - "mirai-annotations", "move-binary-format", "move-bytecode-verifier", "move-core-types", @@ -5248,25 +5397,26 @@ dependencies = [ [[package]] name = "move-vm-test-utils" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "move-binary-format", "move-core-types", - "move-vm-runtime", + "move-vm-types", + "once_cell", + "serde 1.0.151", ] [[package]] name = "move-vm-types" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "bcs", - "mirai-annotations", "move-binary-format", "move-core-types", "once_cell", - "serde 1.0.140", + "serde 1.0.151", "smallvec 1.10.0", ] @@ -5282,7 +5432,7 @@ dependencies = [ "data-encoding", "multihash", "percent-encoding 2.1.0", - "serde 1.0.140", + "serde 1.0.151", "static_assertions", "unsigned-varint 0.7.1", "url 2.2.2", @@ -5309,9 +5459,9 @@ checksum = "424f6e86263cd5294cbd7f1e95746b95aca0e0d66bff31e5a40d6baa87b4aa99" dependencies = [ "proc-macro-crate 1.1.3", "proc-macro-error", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", "synstructure", ] @@ -5337,15 +5487,15 @@ dependencies = [ [[package]] name = "named-lock" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ab176d4bcfbcb53b8c7c5a25cb2c01674cda33db27064a85a16814c88c1f2d" +checksum = "40a3eb6b7c682b65d1f631ec3176829d72ab450b3aacdd3f719bf220822e59ac" dependencies = [ "libc", "once_cell", - "parking_lot 0.10.2", + "parking_lot 0.12.1", "thiserror", - "widestring", + "widestring 0.5.1", "winapi 0.3.9", ] @@ -5468,7 +5618,7 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.8.5", "schemars", - "serde 1.0.140", + "serde 1.0.151", "starcoin-crypto", "starcoin-logger", "starcoin-metrics", @@ -5507,7 +5657,7 @@ dependencies = [ "prometheus", "rand 0.8.5", "sc-peerset", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "smallvec 1.10.0", "starcoin-config", @@ -5534,7 +5684,7 @@ dependencies = [ "rand 0.8.5", "sc-peerset", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_json", ] @@ -5549,7 +5699,7 @@ dependencies = [ "network-rpc-derive", "network-types", "num_enum", - "serde 1.0.140", + "serde 1.0.151", "starcoin-types", "stest", ] @@ -5559,9 +5709,9 @@ name = "network-rpc-derive" version = "1.12.9" dependencies = [ "anyhow", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -5571,7 +5721,7 @@ dependencies = [ "anyhow", "network-p2p-types", "schemars", - "serde 1.0.140", + "serde 1.0.151", "starcoin-crypto", "starcoin-types", ] @@ -5703,9 +5853,9 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -5795,9 +5945,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" dependencies = [ "proc-macro-crate 1.1.3", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -5866,9 +6016,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a15c83b586f00268c619c1cb3340ec1a6f59dd9ba1d9833a273a68e6d5cd8ffc" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -5880,9 +6030,9 @@ dependencies = [ "jsonrpc-derive", "openrpc-schema", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -5891,7 +6041,7 @@ version = "0.1.0" source = "git+https://github.com/starcoinorg/openrpc-rs?rev=077761500ff6fabe2f20da1bdf429575931e3048#077761500ff6fabe2f20da1bdf429575931e3048" dependencies = [ "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_json", ] @@ -5901,7 +6051,7 @@ version = "0.1.0" source = "git+https://github.com/starcoinorg/openrpc-rs?rev=42e9fdc00036a24c560c2827e84cf4e078edbd0d#42e9fdc00036a24c560c2827e84cf4e078edbd0d" dependencies = [ "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_json", ] @@ -5926,9 +6076,9 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -5992,9 +6142,9 @@ checksum = "03f2cb802b5bdfdf52f1ffa0b54ce105e4d346e91990dd571f86c91321ad49e2" dependencies = [ "Inflector", "proc-macro-error", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -6013,9 +6163,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" dependencies = [ "arrayvec 0.5.2", - "bitvec", - "byte-slice-cast", - "serde 1.0.140", + "bitvec 0.17.4", + "byte-slice-cast 0.3.5", + "serde 1.0.151", +] + +[[package]] +name = "parity-scale-codec" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" +dependencies = [ + "arrayvec 0.7.2", + "bitvec 0.20.4", + "byte-slice-cast 1.2.2", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde 1.0.151", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.49", + "quote 1.0.20", + "syn 1.0.107", ] [[package]] @@ -6073,16 +6249,6 @@ dependencies = [ "rustc_version 0.2.3", ] -[[package]] -name = "parking_lot" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" -dependencies = [ - "lock_api 0.3.4", - "parking_lot_core 0.7.2", -] - [[package]] name = "parking_lot" version = "0.11.2" @@ -6119,20 +6285,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "parking_lot_core" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "smallvec 1.10.0", - "winapi 0.3.9", -] - [[package]] name = "parking_lot_core" version = "0.8.5" @@ -6266,9 +6418,9 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" dependencies = [ "pest 2.1.3", "pest_meta", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -6365,9 +6517,9 @@ version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "851c8d0ce9bebe43790dedfc86614c23494ac9f423dd618d3a61fc693eafe61e" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -6376,9 +6528,9 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -6561,13 +6713,25 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" dependencies = [ - "fixed-hash", - "impl-codec", + "fixed-hash 0.6.1", + "impl-codec 0.4.2", "impl-rlp", "impl-serde", "uint 0.8.5", ] +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash 0.7.0", + "impl-codec 0.5.1", + "impl-serde", + "uint 0.9.5", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -6594,9 +6758,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", "version_check 0.9.4", ] @@ -6606,7 +6770,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", "version_check 0.9.4", ] @@ -6628,9 +6792,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.42" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] @@ -6721,9 +6885,9 @@ checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -6768,7 +6932,7 @@ dependencies = [ "config", "directories", "petgraph 0.6.2", - "serde 1.0.140", + "serde 1.0.151", "serde-value", "tint", ] @@ -6842,7 +7006,7 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", ] [[package]] @@ -6851,6 +7015,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + [[package]] name = "radix_trie" version = "0.2.1" @@ -7101,7 +7271,7 @@ dependencies = [ [[package]] name = "read-write-set" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "move-binary-format", @@ -7116,7 +7286,7 @@ dependencies = [ [[package]] name = "read-write-set-dynamic" version = "0.1.0" -source = "git+https://github.com/starcoinorg/move?rev=2b85bf33378a4469e40b10e7bed815bdbefc5d03#2b85bf33378a4469e40b10e7bed815bdbefc5d03" +source = "git+https://github.com/starcoinorg/move?rev=a781b641dd345c3e8f3e83ed080597f6c23a157c#a781b641dd345c3e8f3e83ed080597f6c23a157c" dependencies = [ "anyhow", "move-binary-format", @@ -7177,9 +7347,9 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f26c4704460286103bff62ea1fb78d137febc86aaf76952e6c5a2249af01f54" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -7239,7 +7409,7 @@ dependencies = [ "native-tls", "percent-encoding 2.1.0", "pin-project-lite 0.2.9", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "serde_urlencoded", "tokio 0.2.25", @@ -7275,7 +7445,7 @@ dependencies = [ "native-tls", "percent-encoding 2.1.0", "pin-project-lite 0.2.9", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "serde_urlencoded", "tokio 1.20.1", @@ -7308,7 +7478,7 @@ dependencies = [ "csv", "hex", "pprof", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-crypto", "starcoin-resource-viewer", @@ -7369,9 +7539,9 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -7438,10 +7608,10 @@ version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94e763e24ba2bf0c72bc6be883f967f794a019fafd1b86ba1daff9c91a7edd30" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", "rust-embed-utils", - "syn 1.0.98", + "syn 1.0.107", "walkdir", ] @@ -7598,7 +7768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb35a55ab810b5c0fe31606fe9b47d1354e4dc519bec0a102655f78ea2b38057" dependencies = [ "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -7673,7 +7843,7 @@ dependencies = [ "dyn-clone", "multiaddr", "schemars_derive", - "serde 1.0.140", + "serde 1.0.151", "serde_json", ] @@ -7682,10 +7852,10 @@ name = "schemars_derive" version = "0.8.8" source = "git+https://github.com/starcoinorg/schemars?rev=6972da92f4360e1779168bb3fe0274c521d324e2#6972da92f4360e1779168bb3fe0274c521d324e2" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", "serde_derive_internals", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -7702,7 +7872,7 @@ dependencies = [ "rust-flatten-json", "rustyline", "rustyline-derive", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "thiserror", ] @@ -7793,9 +7963,9 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" [[package]] name = "serde" -version = "1.0.140" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" +checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" dependencies = [ "serde_derive", ] @@ -7810,7 +7980,7 @@ dependencies = [ "heck 0.3.3", "include_dir", "maplit", - "serde 1.0.140", + "serde 1.0.151", "serde-reflection 0.3.2", "serde_bytes", "serde_yaml", @@ -7824,7 +7994,7 @@ version = "1.12.9" dependencies = [ "bcs-ext", "hex", - "serde 1.0.140", + "serde 1.0.151", "serde_bytes", "serde_json", ] @@ -7847,7 +8017,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12c47087018ec281d1cdab673d36aea22d816b54d498264029c05d5fa1910da6" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", "thiserror", ] @@ -7857,7 +8027,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b5b14ebbcc4e4f2b3642fa99c388649da58d1dc3308c7d109f39f565d1710f0" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", "thiserror", ] @@ -7866,7 +8036,7 @@ name = "serde-reflection" version = "0.3.2" source = "git+https://github.com/starcoinorg/serde-reflection?rev=694048797338ff7385006d968e786b6d9dbdeb8b#694048797338ff7385006d968e786b6d9dbdeb8b" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", "thiserror", ] @@ -7877,7 +8047,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f05a5f801ac62a51a49d378fdb3884480041b99aced450b28990673e8ff99895" dependencies = [ "once_cell", - "serde 1.0.140", + "serde 1.0.151", "thiserror", ] @@ -7888,7 +8058,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" dependencies = [ "ordered-float", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -7897,7 +8067,7 @@ version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -7907,18 +8077,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ "half", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] name = "serde_derive" -version = "1.0.140" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" +checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -7927,9 +8097,9 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -7940,7 +8110,7 @@ checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ "itoa 1.0.2", "ryu", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -7952,7 +8122,7 @@ dependencies = [ "form_urlencoded", "itoa 1.0.2", "ryu", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -7961,7 +8131,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", "serde_with_macros", ] @@ -7972,9 +8142,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ "darling 0.13.4", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -7985,7 +8155,7 @@ checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ "indexmap", "ryu", - "serde 1.0.140", + "serde 1.0.151", "yaml-rust", ] @@ -8330,7 +8500,7 @@ dependencies = [ "move-binary-format", "ordinal", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_bytes", "serde_json", "starcoin-abi-resolver", @@ -8360,7 +8530,7 @@ dependencies = [ "anyhow", "hex", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_bytes", "serde_json", "starcoin-vm-types", @@ -8378,7 +8548,7 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.8.5", "rand_core 0.6.3", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-account-api", "starcoin-config", @@ -8402,7 +8572,7 @@ dependencies = [ "rand 0.8.5", "rand_core 0.6.3", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_bytes", "serde_json", "starcoin-crypto", @@ -8462,7 +8632,7 @@ dependencies = [ "rand 0.8.5", "rand_core 0.6.3", "schemars", - "serde 1.0.140", + "serde 1.0.151", "starcoin-crypto", "starcoin-logger", ] @@ -8545,7 +8715,7 @@ dependencies = [ "network-api", "rand 0.8.5", "rand_core 0.6.3", - "serde 1.0.140", + "serde 1.0.151", "starcoin-accumulator", "starcoin-crypto", "starcoin-service-registry", @@ -8608,7 +8778,7 @@ dependencies = [ "futures 0.3.21", "rand 0.8.5", "rand_core 0.6.3", - "serde 1.0.140", + "serde 1.0.151", "starcoin-chain", "starcoin-chain-api", "starcoin-config", @@ -8645,7 +8815,7 @@ dependencies = [ "network-types", "rand 0.8.5", "scmd", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-abi-decoder", "starcoin-abi-resolver", @@ -8704,10 +8874,12 @@ dependencies = [ "rand 0.8.5", "rand_core 0.6.3", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-account-api", "starcoin-crypto", + "starcoin-gas", + "starcoin-gas-algebra-ext", "starcoin-logger", "starcoin-metrics", "starcoin-system", @@ -8761,7 +8933,7 @@ dependencies = [ "once_cell", "rand 0.8.5", "rand_core 0.6.3", - "serde 1.0.140", + "serde 1.0.151", "serde-name 0.2.1", "serde_bytes", "starcoin-crypto-macro", @@ -8772,9 +8944,9 @@ name = "starcoin-crypto-macro" version = "1.10.0-rc.2" source = "git+https://github.com/starcoinorg/starcoin-crypto?rev=d871dfb4216f034ee334a575926c101574d9d6dc#d871dfb4216f034ee334a575926c101574d9d6dc" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -8783,11 +8955,12 @@ version = "1.12.9" dependencies = [ "anyhow", "bcs-ext", - "serde 1.0.140", - "serde-reflection 0.3.6", + "serde 1.0.151", + "serde-reflection 0.3.2", "serde_yaml", "starcoin-crypto", "starcoin-types", + "starcoin-vm-types", ] [[package]] @@ -8835,7 +9008,7 @@ dependencies = [ "log 0.4.17", "move-transactional-test-runner", "once_cell", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-abi-resolver", "starcoin-abi-types", @@ -8894,7 +9067,7 @@ dependencies = [ "hex", "once_cell", "rust-embed", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-account-api", "starcoin-config", @@ -8913,7 +9086,7 @@ dependencies = [ [[package]] name = "starcoin-framework" version = "11.0.0" -source = "git+https://github.com/starcoinorg/starcoin-framework?rev=cf1deda180af40a8b3e26c0c7b548c4c290cd7e7#cf1deda180af40a8b3e26c0c7b548c4c290cd7e7" +source = "git+https://github.com/starcoinorg/starcoin-framework?rev=a7eff4fa3e08cecfed09edf3dbf9d216832d7414#a7eff4fa3e08cecfed09edf3dbf9d216832d7414" dependencies = [ "anyhow", "include_dir", @@ -8923,6 +9096,35 @@ dependencies = [ "walkdir", ] +[[package]] +name = "starcoin-gas" +version = "1.12.9" +dependencies = [ + "clap 3.2.15", + "move-binary-format", + "move-core-types", + "move-stdlib", + "move-table-extension", + "move-vm-types", + "starcoin-gas-algebra-ext", + "starcoin-logger", + "starcoin-natives", +] + +[[package]] +name = "starcoin-gas-algebra-ext" +version = "1.12.9" +dependencies = [ + "move-binary-format", + "move-core-types", + "move-stdlib", + "move-table-extension", + "move-vm-test-utils", + "move-vm-types", + "serde 1.0.151", + "starcoin-natives", +] + [[package]] name = "starcoin-generator" version = "1.12.9" @@ -8933,7 +9135,7 @@ dependencies = [ "futures-timer", "hex", "scmd", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-account", "starcoin-account-api", @@ -8956,7 +9158,7 @@ dependencies = [ "clap 3.2.15", "include_dir", "once_cell", - "serde 1.0.140", + "serde 1.0.151", "starcoin-accumulator", "starcoin-chain", "starcoin-config", @@ -8986,7 +9188,7 @@ dependencies = [ "futures-retry", "futures-util", "jsonrpc-core-client", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-crypto", "starcoin-logger", @@ -9008,7 +9210,7 @@ dependencies = [ "once_cell", "parking_lot 0.12.1", "schemars", - "serde 1.0.140", + "serde 1.0.151", "slog", "slog-async", "slog-term", @@ -9039,7 +9241,7 @@ dependencies = [ "hex", "once_cell", "parking_lot 0.12.1", - "serde 1.0.140", + "serde 1.0.151", "starcoin-account-api", "starcoin-account-service", "starcoin-accumulator", @@ -9096,7 +9298,7 @@ dependencies = [ "rand 0.8.5", "rand_core 0.6.3", "rust-argon2", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-config", "starcoin-consensus", @@ -9174,7 +9376,7 @@ dependencies = [ "once_cell", "pretty", "rand 0.8.5", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "shell-words", "simplelog", @@ -9206,7 +9408,6 @@ dependencies = [ "smallvec 1.10.0", "starcoin-crypto", "starcoin-uint", - "starcoin-vm-types", "tiny-keccak", "walkdir", ] @@ -9236,7 +9437,7 @@ dependencies = [ "parking_lot 0.12.1", "prometheus", "rand 0.8.5", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-config", "starcoin-crypto", @@ -9272,7 +9473,7 @@ dependencies = [ "network-rpc-derive", "once_cell", "prometheus", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-account-api", "starcoin-accumulator", @@ -9312,13 +9513,14 @@ dependencies = [ "network-rpc-derive", "network-types", "once_cell", - "serde 1.0.140", + "serde 1.0.151", "starcoin-accumulator", "starcoin-crypto", "starcoin-logger", "starcoin-state-api", "starcoin-state-tree", "starcoin-types", + "starcoin-vm-types", ] [[package]] @@ -9384,7 +9586,7 @@ dependencies = [ "async-trait", "backtrace", "futures 0.3.21", - "serde 1.0.140", + "serde 1.0.151", "starcoin-config", "starcoin-consensus", "starcoin-crypto", @@ -9463,7 +9665,7 @@ dependencies = [ "hex", "move-binary-format", "move-core-types", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-vm-types", ] @@ -9490,7 +9692,7 @@ dependencies = [ "openrpc-rs", "openrpc-schema", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde-helpers", "serde_json", "starcoin-abi-decoder", @@ -9536,7 +9738,7 @@ dependencies = [ "network-types", "parity-tokio-ipc", "parking_lot 0.12.1", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-abi-types", "starcoin-account-api", @@ -9606,7 +9808,7 @@ dependencies = [ "network-rpc-core", "network-types", "parking_lot 0.12.1", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-abi-decoder", "starcoin-abi-resolver", @@ -9666,7 +9868,7 @@ dependencies = [ "log 0.4.17", "once_cell", "schemars", - "serde 1.0.140", + "serde 1.0.151", "stest", "thiserror", "tokio 1.20.1", @@ -9680,7 +9882,8 @@ dependencies = [ "async-trait", "bcs-ext", "forkable-jellyfish-merkle", - "serde 1.0.140", + "once_cell", + "serde 1.0.151", "starcoin-crypto", "starcoin-service-registry", "starcoin-state-tree", @@ -9704,6 +9907,7 @@ dependencies = [ "starcoin-statedb", "starcoin-storage", "starcoin-types", + "starcoin-vm-types", "stest", "test-helper", "tokio 1.20.1", @@ -9715,7 +9919,7 @@ version = "1.12.9" dependencies = [ "anyhow", "forkable-jellyfish-merkle", - "serde 1.0.140", + "serde 1.0.151", "starcoin-crypto", ] @@ -9727,7 +9931,7 @@ dependencies = [ "bcs-ext", "forkable-jellyfish-merkle", "parking_lot 0.12.1", - "serde 1.0.140", + "serde 1.0.151", "starcoin-config", "starcoin-crypto", "starcoin-logger", @@ -9746,7 +9950,7 @@ dependencies = [ "forkable-jellyfish-merkle", "lru", "parking_lot 0.12.1", - "serde 1.0.140", + "serde 1.0.151", "starcoin-crypto", "starcoin-logger", "starcoin-state-api", @@ -9775,7 +9979,7 @@ dependencies = [ "proptest-derive", "rand 0.8.5", "rocksdb", - "serde 1.0.140", + "serde 1.0.151", "starcoin-accumulator", "starcoin-config", "starcoin-crypto", @@ -9784,6 +9988,7 @@ dependencies = [ "starcoin-state-store-api", "starcoin-types", "starcoin-uint", + "starcoin-vm-types", "stest", "thiserror", ] @@ -9802,7 +10007,7 @@ dependencies = [ "jsonrpc-pubsub", "jsonrpc-tcp-server", "openrpc-rs", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-config", "starcoin-crypto", @@ -9882,7 +10087,7 @@ dependencies = [ "async-trait", "network-api", "schemars", - "serde 1.0.140", + "serde 1.0.151", "starcoin-accumulator", "starcoin-crypto", "starcoin-logger", @@ -9904,7 +10109,7 @@ name = "starcoin-time-service" version = "1.12.9" dependencies = [ "log 0.4.17", - "serde 1.0.140", + "serde 1.0.151", ] [[package]] @@ -9947,9 +10152,10 @@ dependencies = [ "move-compiler", "move-core-types", "move-resource-viewer", + "move-table-extension", "move-transactional-test-runner", "once_cell", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-abi-decoder", "starcoin-accumulator", @@ -10012,7 +10218,7 @@ dependencies = [ "proptest-derive", "rand 0.8.5", "rand_core 0.6.3", - "serde 1.0.140", + "serde 1.0.151", "serde_derive", "starcoin-config", "starcoin-crypto", @@ -10046,7 +10252,7 @@ dependencies = [ "async-trait", "futures-channel", "schemars", - "serde 1.0.140", + "serde 1.0.151", "starcoin-crypto", "starcoin-types", ] @@ -10081,7 +10287,7 @@ dependencies = [ "rand 0.8.5", "rand_core 0.6.3", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-accumulator", "starcoin-crypto", @@ -10096,11 +10302,11 @@ version = "1.12.9" dependencies = [ "bcs-ext", "hex", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-crypto", "starcoin-types", - "uint 0.9.3", + "uint 0.9.5", ] [[package]] @@ -10111,12 +10317,17 @@ dependencies = [ "bcs-ext", "move-core-types", "move-stdlib", + "move-table-extension", "move-vm-runtime", "num_enum", "once_cell", "rand 0.8.5", "rand_core 0.6.3", + "serde 1.0.151", + "starcoin-config", "starcoin-crypto", + "starcoin-gas", + "starcoin-gas-algebra-ext", "starcoin-logger", "starcoin-metrics", "starcoin-natives", @@ -10132,7 +10343,7 @@ version = "1.12.9" dependencies = [ "anyhow", "bcs-ext", - "bech32 0.9.0", + "bech32", "chrono", "forkable-jellyfish-merkle", "hex", @@ -10142,6 +10353,7 @@ dependencies = [ "move-bytecode-verifier", "move-core-types", "move-ir-types", + "move-table-extension", "move-vm-types", "num_enum", "once_cell", @@ -10149,11 +10361,12 @@ dependencies = [ "proptest-derive", "rand 0.8.5", "schemars", - "serde 1.0.140", + "serde 1.0.151", "serde_bytes", "serde_json", "starcoin-accumulator", "starcoin-crypto", + "starcoin-gas-algebra-ext", "starcoin-time-service", ] @@ -10179,7 +10392,7 @@ dependencies = [ "move-compiler", "move-prover", "once_cell", - "serde 1.0.140", + "serde 1.0.151", "sha2 0.10.2", "simplelog", "starcoin-crypto", @@ -10214,7 +10427,7 @@ dependencies = [ "darling 0.10.2", "quote 1.0.20", "stest", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -10243,7 +10456,7 @@ dependencies = [ "pin-project 0.4.30", "pin-utils", "schemars", - "serde 1.0.140", + "serde 1.0.151", "starcoin-logger", "stest", "thiserror", @@ -10315,9 +10528,9 @@ checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck 0.3.3", "proc-macro-error", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -10373,11 +10586,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.98" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", "unicode-ident", ] @@ -10397,9 +10610,9 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", "unicode-xid 0.2.3", ] @@ -10459,6 +10672,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.3.0" @@ -10489,7 +10708,7 @@ dependencies = [ "pest_derive 2.1.0", "rand 0.8.5", "regex", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "slug", "unic-segment", @@ -10562,7 +10781,7 @@ dependencies = [ "network-p2p-types", "network-rpc-core", "rand 0.8.5", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "starcoin-account-api", "starcoin-account-service", @@ -10614,7 +10833,7 @@ dependencies = [ "jsonpath", "regex", "scmd", - "serde 1.0.140", + "serde 1.0.151", "serde_bytes", "serde_json", "starcoin-account-api", @@ -10680,22 +10899,22 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -10801,7 +11020,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", "serde_json", ] @@ -10907,9 +11126,9 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -11056,7 +11275,19 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ - "serde 1.0.140", + "serde 1.0.151", +] + +[[package]] +name = "toml_edit" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5376256e44f2443f8896ac012507c19a012df0fe8758b55246ae51a2279db51f" +dependencies = [ + "combine", + "indexmap", + "itertools", + "serde 1.0.151", ] [[package]] @@ -11093,9 +11324,9 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -11262,9 +11493,9 @@ dependencies = [ [[package]] name = "uint" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ "byteorder 1.4.3", "crunchy", @@ -11510,7 +11741,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124" dependencies = [ "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", ] [[package]] @@ -11543,7 +11774,7 @@ version = "1.12.9" dependencies = [ "anyhow", "schemars", - "serde 1.0.140", + "serde 1.0.151", "starcoin-move-explain", "starcoin-vm-types", ] @@ -11615,7 +11846,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ "cfg-if 1.0.0", - "serde 1.0.140", + "serde 1.0.151", "serde_json", "wasm-bindgen-macro", ] @@ -11629,9 +11860,9 @@ dependencies = [ "bumpalo", "log 0.4.17", "once_cell", - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", "wasm-bindgen-shared", ] @@ -11663,9 +11894,9 @@ version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11781,12 +12012,29 @@ dependencies = [ "libc", ] +[[package]] +name = "whoami" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6631b6a2fd59b1841b622e8f1a7ad241ef0a46f2d580464ce8140ac94cbd571" +dependencies = [ + "bumpalo", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "widestring" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + [[package]] name = "winapi" version = "0.2.8" @@ -11953,6 +12201,12 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + [[package]] name = "x25519-dalek" version = "1.2.0" @@ -12013,8 +12267,8 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" dependencies = [ - "proc-macro2 1.0.42", + "proc-macro2 1.0.49", "quote 1.0.20", - "syn 1.0.98", + "syn 1.0.107", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index ad3fe542fe..17e23d90af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,7 +77,9 @@ members = [ "vm/transaction-builder-generator", "vm/move-coverage", "vm/resource-viewer", + "vm/starcoin-gas", "vm/dev", + "vm/gas-algebra-ext", "vm/move-explain", "vm/move-package-manager", "vm/vm-status-translator", @@ -178,7 +180,9 @@ default-members = [ "vm/transaction-builder-generator", "vm/move-coverage", "vm/resource-viewer", + "vm/starcoin-gas", "vm/dev", + "vm/gas-algebra-ext", "vm/move-explain", "vm/move-package-manager", "vm/vm-status-translator", @@ -215,7 +219,7 @@ debug-assertions = false codegen-units = 1 [workspace.package] -authors = ["Starcoin Core Dev ", ] +authors = ["Starcoin Core Dev "] edition = "2021" homepage = "https://starcoin.org" license = "Apache-2.0" @@ -246,18 +250,18 @@ bitflags = "1.3.2" bs58 = "0.3.1" byteorder = "1.3.4" bytes = "1" -chrono = { version = "0.4.19", default-features = false, features = ["clock", ] } -clap = { version = "3", features = ["derive", ] } +chrono = { version = "0.4.19", default-features = false, features = ["clock"] } +clap = { version = "3", features = ["derive"] } cli-table = "0.3.2" coarsetime = "0.1.22" -codespan = { version = "0.8.0", features = ["serialization", ] } +codespan = { version = "0.8.0", features = ["serialization"] } codespan-reporting = "0.11" colored = "2.0.0" criterion = "0.3" crossbeam-channel = "0.5.6" cryptonight-rs = { path = "consensus/cryptonight-rs" } csv = "~1" -ctrlc = { version = "3.2.2", features = ["termination", ] } +ctrlc = { version = "3.2.2", features = ["termination"] } cucumber = { package = "cucumber_rust", version = "^0.6.0" } darling = "0.10.2" dashmap = "~5" @@ -280,12 +284,12 @@ futures-retry = "0.6" futures-timer = "3.0" futures-util = "~0.3" git-version = "0.3.5" -governor = { version = "0.4.2", features = ["dashmap", ] } +governor = { version = "0.4.2", features = ["dashmap"] } heck = "0.3.3" hex = "0.4" hmac = "0.12.1" -hyper = { version = "0.14.12", features = ["full", ] } -include_dir = { version = "0.6.2", features = ["search", ] } +hyper = { version = "0.14.12", features = ["full"] } +include_dir = { version = "0.6.2", features = ["search"] } indicatif = "0.16.2" ip_network = "0.3.4" io-lifetimes = "0.7.2" @@ -296,8 +300,10 @@ jsonrpc-client-transports = "18" jsonrpc-core = "18" jsonrpc-core-client = "18" jsonrpc-derive = "18" -openrpc-derive = {git = "https://github.com/starcoinorg/openrpc-rs",rev = "42e9fdc00036a24c560c2827e84cf4e078edbd0d",features=["jsonrpc"]} -openrpc-schema = {git = "https://github.com/starcoinorg/openrpc-rs",rev = "42e9fdc00036a24c560c2827e84cf4e078edbd0d"} +openrpc-derive = { git = "https://github.com/starcoinorg/openrpc-rs", rev = "42e9fdc00036a24c560c2827e84cf4e078edbd0d", features = [ + "jsonrpc", +] } +openrpc-schema = { git = "https://github.com/starcoinorg/openrpc-rs", rev = "42e9fdc00036a24c560c2827e84cf4e078edbd0d" } jsonrpc-http-server = "18" jsonrpc-ipc-server = "18" @@ -314,33 +320,36 @@ libsecp256k1 = "0.7.1" linked-hash-map = "0.5.6" linked_hash_set = "0.1.3" log = { version = "0.4.16" } -log4rs = { version = "1.0.0", features = ["background_rotation", "gzip", ] } +log4rs = { version = "1.0.0", features = ["background_rotation", "gzip"] } lru = "0.7.8" merkletree = { git = "https://github.com/filecoin-project/merkletree", rev = "3b1d98c43b341aed935152c5c1535c17d1b21d20" } mirai-annotations = "1.10.1" -move-binary-format = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-bytecode-source-map = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-bytecode-verifier = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-cli = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-command-line-common = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-compiler = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-core-types = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-coverage = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-disassembler = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-docgen = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-errmapgen = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-ir-compiler = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-ir-types = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-model = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-package = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-prover = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-prover-test-utils = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-resource-viewer = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-stdlib = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-transactional-test-runner = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-unit-test = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-vm-runtime = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } -move-vm-types = { git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03" } +move-binary-format = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-bytecode-source-map = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-bytecode-verifier = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-cli = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-command-line-common = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-compiler = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-core-types = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-coverage = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-disassembler = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-docgen = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-errmapgen = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-ir-compiler = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-ir-types = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-model = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-package = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-prover = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-prover-test-utils = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-resource-viewer = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-stdlib = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-transactional-test-runner = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-unit-test = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-vm-runtime = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-vm-types = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-table-extension = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } +move-vm-test-utils = { git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } + names = { version = "0.14.0", default-features = false } network-api = { path = "network/api", package = "network-api" } network-p2p = { path = "network-p2p" } @@ -375,7 +384,7 @@ regex = "1.6.0" ripemd160 = "0.9.1" rlp = "0.4" rlp-derive = "0.1" -rocksdb = { default-features = false, features = ["lz4", ], version = "0.18" } +rocksdb = { default-features = false, features = ["lz4"], version = "0.18" } rpassword = "~5" rust-argon2 = "0.8" rust-embed = "6.3.0" @@ -425,7 +434,7 @@ starcoin-crypto = { git = "https://github.com/starcoinorg/starcoin-crypto", rev starcoin-decrypt = { path = "commons/decrypt" } starcoin-dev = { path = "vm/dev" } starcoin-executor = { path = "executor" } -starcoin-framework = { git = "https://github.com/starcoinorg/starcoin-framework", rev = "cf1deda180af40a8b3e26c0c7b548c4c290cd7e7" } +starcoin-framework = { git = "https://github.com/starcoinorg/starcoin-framework", rev = "a7eff4fa3e08cecfed09edf3dbf9d216832d7414" } starcoin-genesis = { path = "genesis" } starcoin-logger = { path = "commons/logger" } starcoin-metrics = { path = "commons/metrics" } @@ -434,6 +443,8 @@ starcoin-miner-client = { path = "cmd/miner_client" } starcoin-miner-client-api = { path = "cmd/miner_client/api" } starcoin-move-compiler = { path = "vm/compiler" } starcoin-move-explain = { path = "vm/move-explain" } +starcoin-gas-algebra-ext = { path = "vm/gas-algebra-ext" } +starcoin-gas = { path = "vm/starcoin-gas" } starcoin-natives = { path = "vm/natives" } starcoin-network = { path = "network" } starcoin-network-rpc = { path = "network-rpc" } @@ -471,24 +482,34 @@ stdlib = { path = "vm/stdlib" } stest = { path = "commons/stest" } stest-macro = { path = "commons/stest/stest-macro" } stream-task = { path = "commons/stream-task" } -syn = { version = "1.0", features = ["full", "extra-traits", "visit", "fold", ] } +syn = { version = "1.0.107", features = [ + "full", + "extra-traits", + "visit", + "fold", +] } sysinfo = "0.25.1" tempfile = "3.2.0" test-helper = { path = "test-helper" } textwrap = "0.14.0" thiserror = "1.0" timeout-join-handler = { path = "commons/timeout-join-handler" } -tiny-keccak = { version = "2", features = ["keccak", ] } +tiny-keccak = { version = "2", features = ["keccak"] } tiny_http = "0.8.2" -tokio = { version = "^1", features = ["full", ] } -tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking", ] } +tokio = { version = "^1", features = ["full"] } +tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } toml = "0.5.9" trace-time = "0.1" tracing = "0.1.34" transaction-pool = "2.0.3" uint = "0.9.3" -unsigned-varint = { version = "0.6.0", features = ["futures", "asynchronous_codec", ] } -vm = { package = "move-binary-format", git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03", features = ["fuzzing", ] } +unsigned-varint = { version = "0.6.0", features = [ + "futures", + "asynchronous_codec", +] } +vm = { package = "move-binary-format", git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c", features = [ + "fuzzing", +] } vm-status-translator = { path = "vm/vm-status-translator" } void = "1.0.2" walkdir = "2.3.1" diff --git a/README.md b/README.md index 2ce6733461..bdaef10c6b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ Starcoin - a smart contract blockchain network that scales by layering +net proxima using move with table extension feature. If you want to use it, you should compile dev branch. + [Report a Bug](https://github.com/starcoinorg/starcoin/issues/new?assignees=&labels=bug&template=01_BUG_REPORT.md&title=bug%3A+") · [Request a Feature](https://github.com/starcoinorg/starcoin/issues/new?assignees=&labels=enhancement&template=02_FEATURE_REQUEST.md&title=feat%3A+") diff --git a/abi/decoder/Cargo.toml b/abi/decoder/Cargo.toml index 28b81519d6..f5b6e85b74 100644 --- a/abi/decoder/Cargo.toml +++ b/abi/decoder/Cargo.toml @@ -6,7 +6,7 @@ hex = { workspace = true } move-binary-format = { workspace = true } ordinal = { workspace = true } schemars = { workspace = true } -serde = { features = [ "derive", "rc",], workspace = true } +serde = { features = ["derive", "rc"], workspace = true } serde_bytes = { workspace = true } serde_json = { workspace = true } starcoin-abi-resolver = { workspace = true } diff --git a/abi/decoder/src/lib.rs b/abi/decoder/src/lib.rs index d399cf97a3..12430a4b3f 100644 --- a/abi/decoder/src/lib.rs +++ b/abi/decoder/src/lib.rs @@ -82,8 +82,12 @@ fn value_to_json(origin: AnnotatedMoveValue) -> serde_json::Value { use serde_json::Value; match origin { AnnotatedMoveValue::U8(v) => Value::Number(v.into()), + AnnotatedMoveValue::U16(v) => Value::Number(v.into()), + AnnotatedMoveValue::U32(v) => Value::Number(v.into()), AnnotatedMoveValue::U64(v) => Value::Number(v.into()), AnnotatedMoveValue::U128(v) => Value::Number(v.into()), + // XXX FIXME YSG + AnnotatedMoveValue::U256(v) => Value::String(v.to_string()), AnnotatedMoveValue::Bool(v) => Value::Bool(v), AnnotatedMoveValue::Address(v) => Value::String(v.to_string()), AnnotatedMoveValue::Vector(v) => Value::Array(v.into_iter().map(value_to_json).collect()), diff --git a/abi/resolver/src/lib.rs b/abi/resolver/src/lib.rs index 82fd4299c1..c30f717321 100644 --- a/abi/resolver/src/lib.rs +++ b/abi/resolver/src/lib.rs @@ -12,7 +12,7 @@ use starcoin_resource_viewer::module_cache::ModuleCache; use starcoin_resource_viewer::resolver::Resolver; use starcoin_vm_types::access::ModuleAccess; use starcoin_vm_types::file_format::{ - CompiledModule, CompiledScript, FunctionDefinitionIndex, StructDefinitionIndex, Visibility, + CompiledModule, CompiledScript, FunctionDefinitionIndex, StructDefinitionIndex, }; use starcoin_vm_types::identifier::{IdentStr, Identifier}; use starcoin_vm_types::language_storage::{ModuleId, StructTag, TypeTag}; @@ -63,7 +63,7 @@ impl<'a> ABIResolver<'a> { let functions = m .exposed_functions .iter() - .filter(|(_, func)| func.visibility == Visibility::Script) // only script functions + // .filter(|(_, func)| func.visibility == Visibility::Script) // only script functions .map(|(name, func)| self.function_to_abi(&module_id, name.as_ident_str(), func)) .collect::>>()?; Ok(ModuleABI::new(m.module_id(), structs, functions)) @@ -108,8 +108,11 @@ impl<'a> ABIResolver<'a> { Ok(match type_tag { TypeTag::Bool => TypeInstantiation::Bool, TypeTag::U8 => TypeInstantiation::U8, + TypeTag::U16 => TypeInstantiation::U16, + TypeTag::U32 => TypeInstantiation::U32, TypeTag::U64 => TypeInstantiation::U64, TypeTag::U128 => TypeInstantiation::U128, + TypeTag::U256 => TypeInstantiation::U256, TypeTag::Address => TypeInstantiation::Address, TypeTag::Signer => TypeInstantiation::Signer, @@ -134,8 +137,11 @@ impl<'a> ABIResolver<'a> { Ok(match ty { Type::Bool => TypeInstantiation::Bool, Type::U8 => TypeInstantiation::U8, + Type::U16 => TypeInstantiation::U16, + Type::U32 => TypeInstantiation::U32, Type::U64 => TypeInstantiation::U64, Type::U128 => TypeInstantiation::U128, + Type::U256 => TypeInstantiation::U256, Type::Address => TypeInstantiation::Address, Type::Signer => TypeInstantiation::Signer, Type::Struct { @@ -351,7 +357,7 @@ fn find_struct_def_in_module( mod tests { use crate::ABIResolver; use anyhow::Result; - use starcoin_vm_types::access_path::{AccessPath, DataPath}; + use starcoin_vm_types::access_path::DataPath; use starcoin_vm_types::account_address::AccountAddress; use starcoin_vm_types::account_config::genesis_address; use starcoin_vm_types::file_format::CompiledModule; @@ -359,6 +365,7 @@ mod tests { use starcoin_vm_types::language_storage::ModuleId; use starcoin_vm_types::normalized::Module; use starcoin_vm_types::parser::parse_struct_tag; + use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::state_view::StateView; use std::collections::BTreeMap; @@ -373,16 +380,23 @@ mod tests { } } impl StateView for InMemoryStateView { - fn get(&self, access_path: &AccessPath) -> Result>> { - let module_id = match &access_path.path { - DataPath::Code(name) => ModuleId::new(access_path.address, name.clone()), - _ => anyhow::bail!("no data"), - }; - Ok(self.modules.get(&module_id).map(|m| { - let mut data = vec![]; - m.serialize(&mut data).unwrap(); - data - })) + fn get_state_value(&self, state_key: &StateKey) -> Result>> { + match state_key { + StateKey::AccessPath(access_path) => { + let module_id = match &access_path.path { + DataPath::Code(name) => ModuleId::new(access_path.address, name.clone()), + _ => anyhow::bail!("no data"), + }; + Ok(self.modules.get(&module_id).map(|m| { + let mut data = vec![]; + m.serialize(&mut data).unwrap(); + data + })) + } + StateKey::TableItem(_table_item) => { + anyhow::bail!("no need table_item") + } + } } fn is_genesis(&self) -> bool { diff --git a/abi/types/src/lib.rs b/abi/types/src/lib.rs index b6758fdf8e..d46858242c 100644 --- a/abi/types/src/lib.rs +++ b/abi/types/src/lib.rs @@ -571,8 +571,11 @@ impl FieldABI { pub enum TypeInstantiation { Bool, U8, + U16, + U32, U64, U128, + U256, Address, Signer, Vector(Box), @@ -591,9 +594,11 @@ impl TypeInstantiation { Ok(match self { Self::Bool => MoveTypeLayout::Bool, Self::U8 => MoveTypeLayout::U8, - + Self::U16 => MoveTypeLayout::U16, + Self::U32 => MoveTypeLayout::U32, Self::U64 => MoveTypeLayout::U64, Self::U128 => MoveTypeLayout::U128, + Self::U256 => MoveTypeLayout::U256, Self::Address => MoveTypeLayout::Address, Self::Signer => MoveTypeLayout::Signer, @@ -607,14 +612,16 @@ impl TypeInstantiation { Ok(match self { Self::Bool => TypeTag::Bool, Self::U8 => TypeTag::U8, - + Self::U16 => TypeTag::U16, + Self::U32 => TypeTag::U32, Self::U64 => TypeTag::U64, Self::U128 => TypeTag::U128, + Self::U256 => TypeTag::U256, Self::Address => TypeTag::Address, Self::Signer => TypeTag::Signer, Self::Vector(t) => TypeTag::Vector(Box::new(t.type_tag()?)), - Self::Struct(s) => TypeTag::Struct(s.struct_tag()?), + Self::Struct(s) => TypeTag::Struct(Box::new(s.struct_tag()?)), Self::TypeParameter(_) => anyhow::bail!("get type tag failed -- {:?}", self), Self::Reference(_, _) => anyhow::bail!("get type tag failed -- {:?}", self), }) @@ -650,8 +657,12 @@ impl<'d> serde::de::DeserializeSeed<'d> for &TypeInstantiation { match &self { T::Bool => bool::deserialize(deserializer).map(V::Bool), T::U8 => u8::deserialize(deserializer).map(Into::into), + T::U16 => u16::deserialize(deserializer).map(Into::into), + T::U32 => u32::deserialize(deserializer).map(Into::into), T::U64 => u64::deserialize(deserializer).map(Into::into), T::U128 => u128::deserialize(deserializer).map(Into::into), + // XXX FIXME YSG + T::U256 => Err(D::Error::custom("type U256 not process variant")), T::Address => { AccountAddress::deserialize(deserializer).map(|addr| V::String(addr.to_string())) } diff --git a/account/provider/Cargo.toml b/account/provider/Cargo.toml index e508c53bc5..6b91ac56a9 100644 --- a/account/provider/Cargo.toml +++ b/account/provider/Cargo.toml @@ -1,7 +1,7 @@ [dependencies] anyhow = { workspace = true } starcoin-account = { workspace = true } -starcoin-account-api = { features = [ "mock",], workspace = true } +starcoin-account-api = { features = ["mock"], workspace = true } starcoin-config = { workspace = true } starcoin-crypto = { workspace = true } starcoin-rpc-client = { workspace = true } diff --git a/account/service/Cargo.toml b/account/service/Cargo.toml index 069c01af3a..21293b8c30 100644 --- a/account/service/Cargo.toml +++ b/account/service/Cargo.toml @@ -4,7 +4,7 @@ async-trait = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } futures = { workspace = true } starcoin-account = { workspace = true } -starcoin-account-api = { features = [ "mock",], workspace = true } +starcoin-account-api = { features = ["mock"], workspace = true } starcoin-chain-notify = { workspace = true } starcoin-config = { workspace = true } starcoin-crypto = { workspace = true } diff --git a/benchmarks/Cargo.toml b/benchmarks/Cargo.toml index 0d8d1662b5..6b63ae48d6 100644 --- a/benchmarks/Cargo.toml +++ b/benchmarks/Cargo.toml @@ -61,4 +61,4 @@ repository = { workspace = true } rust-version = { workspace = true } [target."cfg(target_os=\"linux\")".dependencies] -pprof = { version = "0.10", features = ["flamegraph", "criterion", ] } +pprof = { version = "0.10", features = ["flamegraph", "criterion"] } diff --git a/block-relayer/Cargo.toml b/block-relayer/Cargo.toml index b77f2fddce..e68a3b2c0c 100644 --- a/block-relayer/Cargo.toml +++ b/block-relayer/Cargo.toml @@ -23,7 +23,7 @@ starcoin-config = { workspace = true } [dev-dependencies] hex = { workspace = true } stest = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [package] authors = { workspace = true } diff --git a/chain/Cargo.toml b/chain/Cargo.toml index e42123f58b..99d75b884c 100644 --- a/chain/Cargo.toml +++ b/chain/Cargo.toml @@ -1,7 +1,7 @@ [dependencies] anyhow = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } starcoin-crypto = { package = "starcoin-crypto", workspace = true } starcoin-logger = { package = "starcoin-logger", workspace = true } proptest = { default-features = false, optional = true, workspace = true } @@ -32,15 +32,17 @@ starcoin-chain-mock = { workspace = true } starcoin-genesis = { workspace = true } starcoin-resource-viewer = { workspace = true } starcoin-transaction-builder = { workspace = true } -starcoin-types = { package = "starcoin-types", features = [ "fuzzing",], workspace = true } +starcoin-types = { package = "starcoin-types", features = [ + "fuzzing", +], workspace = true } stdlib = { workspace = true } stest = { workspace = true } test-helper = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [features] default = [] -fuzzing = [ "proptest", "proptest-derive", "starcoin-types/fuzzing",] +fuzzing = ["proptest", "proptest-derive", "starcoin-types/fuzzing"] [package] authors = { workspace = true } diff --git a/chain/api/Cargo.toml b/chain/api/Cargo.toml index 1d630f968a..349dc67f78 100644 --- a/chain/api/Cargo.toml +++ b/chain/api/Cargo.toml @@ -16,6 +16,7 @@ starcoin-types = { workspace = true } starcoin-vm-types = { workspace = true } thiserror = { workspace = true } + [dev-dependencies] [features] diff --git a/chain/mock/Cargo.toml b/chain/mock/Cargo.toml index ee80276774..2f6f86b16d 100644 --- a/chain/mock/Cargo.toml +++ b/chain/mock/Cargo.toml @@ -30,7 +30,7 @@ proptest-derive = { workspace = true } [features] default = [] -fuzzing = [ "proptest", "proptest-derive", "starcoin-types/fuzzing",] +fuzzing = ["proptest", "proptest-derive", "starcoin-types/fuzzing"] [package] authors = { workspace = true } diff --git a/chain/tests/test_block_chain.rs b/chain/tests/test_block_chain.rs index b1ee51321e..7b1d41411b 100644 --- a/chain/tests/test_block_chain.rs +++ b/chain/tests/test_block_chain.rs @@ -28,12 +28,12 @@ fn test_chain_filter_events() { let times = 10; mock_chain.produce_and_apply_times(times).unwrap(); - let event_type_tag = TypeTag::Struct(StructTag { + let event_type_tag = TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::from_str("Block").unwrap(), name: Identifier::from_str("NewBlockEvent").unwrap(), type_params: vec![], - }); + })); // Origin block event index is 4, after https://github.com/starcoinorg/starcoin-framework/pull/42 , Genesis account create more event_handles, so the block event index is 7. // So we should use type_tags to filter event, do not dependent on event key. diff --git a/cmd/airdrop/Cargo.toml b/cmd/airdrop/Cargo.toml index 2543cea505..d9ea109a4f 100644 --- a/cmd/airdrop/Cargo.toml +++ b/cmd/airdrop/Cargo.toml @@ -2,7 +2,7 @@ anyhow = { workspace = true } async-trait = { workspace = true } bcs-ext = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } csv = { workspace = true } elasticsearch = { workspace = true } futures-retry = { workspace = true } @@ -17,7 +17,7 @@ starcoin-logger = { workspace = true } starcoin-rpc-api = { workspace = true } starcoin-types = { workspace = true } starcoin-vm-types = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [package] authors = { workspace = true } diff --git a/cmd/airdrop/src/main.rs b/cmd/airdrop/src/main.rs index 10519303b8..4f28fb2e5c 100644 --- a/cmd/airdrop/src/main.rs +++ b/cmd/airdrop/src/main.rs @@ -124,7 +124,7 @@ async fn main() -> Result<()> { .token_code .unwrap_or_else(|| G_STC_TOKEN_CODE.clone()) .try_into()?; - let is_stc = stc_type_tag().eq(&TypeTag::Struct(token_type.clone())); + let is_stc = stc_type_tag().eq(&TypeTag::Struct(Box::new(token_type.clone()))); let mut total_amount = 0u128; let airdrop_infos: Vec = { diff --git a/cmd/db-exporter/Cargo.toml b/cmd/db-exporter/Cargo.toml index 6e87537b4b..816136b394 100644 --- a/cmd/db-exporter/Cargo.toml +++ b/cmd/db-exporter/Cargo.toml @@ -6,14 +6,14 @@ path = "src/main.rs" anyhow = { workspace = true } atomic-counter = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } csv = { workspace = true } hex = { workspace = true } indicatif = { workspace = true } starcoin-logger = { package = "starcoin-logger", workspace = true } serde = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } -tokio = { features = [ "full",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } +tokio = { features = ["full"], workspace = true } move-binary-format = { workspace = true } move-bytecode-verifier = { workspace = true } starcoin-account-api = { workspace = true } @@ -43,5 +43,6 @@ homepage = { workspace = true } repository = { workspace = true } rust-version = { workspace = true } + [target."cfg(target_os=\"linux\")".dependencies] -pprof = { version = "0.10", features = [ "flamegraph",] } +pprof = { version = "0.10", features = ["flamegraph"] } diff --git a/cmd/db-exporter/src/lib.rs b/cmd/db-exporter/src/lib.rs index e08288615e..643379cd7e 100644 --- a/cmd/db-exporter/src/lib.rs +++ b/cmd/db-exporter/src/lib.rs @@ -5,10 +5,10 @@ use anyhow::bail; use atomic_counter::AtomicCounter; use indicatif::{ProgressBar, ProgressStyle}; use move_binary_format::errors::Location; +use move_binary_format::errors::VMError; use starcoin_crypto::HashValue; use starcoin_types::block::Block; use starcoin_types::transaction::TransactionPayload; -use starcoin_vm_types::errors::VMError; use starcoin_vm_types::file_format::CompiledModule; use std::fs::File; use std::io::{BufRead, BufReader}; diff --git a/cmd/db-exporter/src/main.rs b/cmd/db-exporter/src/main.rs index 6c15213d3e..f37a9e6801 100644 --- a/cmd/db-exporter/src/main.rs +++ b/cmd/db-exporter/src/main.rs @@ -672,6 +672,7 @@ pub fn apply_block( network: BuiltinNetworkID, verifier: Verifier, ) -> anyhow::Result<()> { + ::starcoin_logger::init(); let net = ChainNetwork::new_builtin(network); let db_storage = DBStorage::new(to_dir.join("starcoindb/db"), RocksdbConfig::default(), None)?; let storage = Arc::new(Storage::new(StorageInstance::new_cache_and_db_instance( @@ -767,12 +768,6 @@ pub fn startup_info_back( let cur_num = chain.status().head().number(); let back_size = back_size.unwrap_or(BACK_SIZE); - let back_size = if back_size < BACK_SIZE { - BACK_SIZE - } else { - back_size - }; - if cur_num <= back_size { println!( "startup_info block number {} <= back_size {}", @@ -1838,12 +1833,13 @@ impl serde::Serialize for MoveValue { } AnnotatedMoveValue::Bytes(v) => hex::encode(v).serialize(serializer), AnnotatedMoveValue::Struct(v) => MoveStruct(v.clone()).serialize(serializer), + _ => todo!("XXX FXIME YSG"), } } } fn parse_struct_tag(input: &str) -> anyhow::Result { match parse_type_tag(input)? { - TypeTag::Struct(s) => Ok(s), + TypeTag::Struct(s) => Ok(*s), _ => { anyhow::bail!("invalid struct tag") } diff --git a/cmd/faucet/Cargo.toml b/cmd/faucet/Cargo.toml index 092ce94e99..6e1c7cae32 100644 --- a/cmd/faucet/Cargo.toml +++ b/cmd/faucet/Cargo.toml @@ -5,14 +5,14 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } ascii = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } futures = { workspace = true } futures-timer = { workspace = true } hex = { default-features = false, workspace = true } once_cell = { workspace = true } rust-embed = { workspace = true } serde = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-account-api = { workspace = true } starcoin-config = { workspace = true } starcoin-crypto = { workspace = true } @@ -23,8 +23,8 @@ starcoin-state-api = { workspace = true } starcoin-transaction-builder = { workspace = true } starcoin-types = { workspace = true } tiny_http = { workspace = true } -tokio = { features = [ "full",], workspace = true } -tokio-executor = { features = [ "blocking",], workspace = true } +tokio = { features = ["full"], workspace = true } +tokio-executor = { features = ["blocking"], workspace = true } [features] default = [] diff --git a/cmd/generator/Cargo.toml b/cmd/generator/Cargo.toml index 7ecdc227a5..6c97001f09 100644 --- a/cmd/generator/Cargo.toml +++ b/cmd/generator/Cargo.toml @@ -4,13 +4,13 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } futures = { workspace = true } futures-timer = { workspace = true } hex = { default-features = false, workspace = true } scmd = { workspace = true } serde = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-account = { workspace = true } starcoin-account-api = { workspace = true } starcoin-chain = { workspace = true } diff --git a/cmd/genesis-nft-miner/Cargo.toml b/cmd/genesis-nft-miner/Cargo.toml index c596f64930..4f3c4ce0b0 100644 --- a/cmd/genesis-nft-miner/Cargo.toml +++ b/cmd/genesis-nft-miner/Cargo.toml @@ -1,7 +1,7 @@ [dependencies] anyhow = { workspace = true } bcs-ext = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } hex = { workspace = true } jsonrpc-core-client = { workspace = true } rpassword = { workspace = true } @@ -11,7 +11,7 @@ starcoin-crypto = { workspace = true } starcoin-rpc-api = { workspace = true } starcoin-types = { workspace = true } starcoin-vm-types = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [package] authors = { workspace = true } diff --git a/cmd/indexer/Cargo.toml b/cmd/indexer/Cargo.toml index 82dafd9785..f7e5a342c8 100644 --- a/cmd/indexer/Cargo.toml +++ b/cmd/indexer/Cargo.toml @@ -5,7 +5,7 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } async-trait = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } elasticsearch = { workspace = true } futures-retry = { workspace = true } futures-util = { workspace = true } @@ -16,7 +16,7 @@ starcoin-crypto = { workspace = true } starcoin-logger = { workspace = true } starcoin-rpc-api = { workspace = true } starcoin-types = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [package] authors = { workspace = true } diff --git a/cmd/merkle-generator/Cargo.toml b/cmd/merkle-generator/Cargo.toml index 6a2776acb4..b5c0c674b5 100644 --- a/cmd/merkle-generator/Cargo.toml +++ b/cmd/merkle-generator/Cargo.toml @@ -1,12 +1,12 @@ [dependencies] anyhow = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } csv = { workspace = true } hex = { workspace = true } merkletree = { workspace = true } serde = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } sha3 = { workspace = true } starcoin-crypto = { workspace = true } starcoin-vm-types = { workspace = true } diff --git a/cmd/miner_client/Cargo.toml b/cmd/miner_client/Cargo.toml index d43ce6b786..8a046eaa5a 100644 --- a/cmd/miner_client/Cargo.toml +++ b/cmd/miner_client/Cargo.toml @@ -11,17 +11,17 @@ starcoin-consensus = { package = "starcoin-consensus", workspace = true } starcoin-crypto = { package = "starcoin-crypto", workspace = true } futures = { workspace = true } futures-channel = { workspace = true } -jsonrpc-core = { features = [ "arbitrary_precision",], workspace = true } +jsonrpc-core = { features = ["arbitrary_precision"], workspace = true } jsonrpc-core-client = { workspace = true } jsonrpc-server-utils = { workspace = true } starcoin-logger = { package = "starcoin-logger", workspace = true } starcoin-config = { workspace = true } starcoin-time-service = { workspace = true } starcoin-types = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } async-trait = { workspace = true } byteorder = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } dyn-clone = { workspace = true } futures-timer = { workspace = true } hex = { default-features = false, workspace = true } @@ -30,8 +30,8 @@ parking_lot = { workspace = true } rand = { workspace = true } rand_core = { default-features = false, workspace = true } rust-argon2 = { workspace = true } -serde = { features = [ "derive",], workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde = { features = ["derive"], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-miner = { workspace = true } starcoin-miner-client-api = { workspace = true } starcoin-rpc-api = { workspace = true } diff --git a/cmd/peer-watcher/Cargo.toml b/cmd/peer-watcher/Cargo.toml index 7739f6a69a..e4b4ce0e48 100644 --- a/cmd/peer-watcher/Cargo.toml +++ b/cmd/peer-watcher/Cargo.toml @@ -5,7 +5,7 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } async-std = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } futures = { workspace = true } network-p2p = { workspace = true } network-p2p-types = { workspace = true } diff --git a/cmd/replay/Cargo.toml b/cmd/replay/Cargo.toml index 8a0f2b36e2..e1e568533d 100644 --- a/cmd/replay/Cargo.toml +++ b/cmd/replay/Cargo.toml @@ -4,7 +4,7 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } sp-utils = { workspace = true } starcoin-chain = { workspace = true } starcoin-config = { workspace = true } diff --git a/cmd/resource-exporter/Cargo.toml b/cmd/resource-exporter/Cargo.toml index 8bd4137c23..73a7ef7d68 100644 --- a/cmd/resource-exporter/Cargo.toml +++ b/cmd/resource-exporter/Cargo.toml @@ -1,11 +1,11 @@ [dependencies] anyhow = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } csv = { workspace = true } hex = { workspace = true } serde = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-crypto = { workspace = true } starcoin-resource-viewer = { workspace = true } starcoin-state-tree = { workspace = true } @@ -26,4 +26,4 @@ repository = { workspace = true } rust-version = { workspace = true } [target."cfg(target_os=\"linux\")".dependencies] -pprof = { version = "0.10", features = [ "flamegraph"] } +pprof = { version = "0.10", features = ["flamegraph"] } diff --git a/cmd/resource-exporter/src/main.rs b/cmd/resource-exporter/src/main.rs index ac477b099c..bdd9abaf41 100644 --- a/cmd/resource-exporter/src/main.rs +++ b/cmd/resource-exporter/src/main.rs @@ -133,8 +133,11 @@ impl serde::Serialize for MoveValue { match &self.0 { AnnotatedMoveValue::Bool(b) => serializer.serialize_bool(*b), AnnotatedMoveValue::U8(v) => serializer.serialize_u8(*v), + AnnotatedMoveValue::U16(v) => serializer.serialize_u16(*v), + AnnotatedMoveValue::U32(v) => serializer.serialize_u32(*v), AnnotatedMoveValue::U64(v) => serializer.serialize_u64(*v), AnnotatedMoveValue::U128(v) => serializer.serialize_u128(*v), + //AnnotatedMoveValue::U256(v) => serializer.serialize(*v), AnnotatedMoveValue::Address(v) => v.serialize(serializer), AnnotatedMoveValue::Vector(v) => { let vs: Vec<_> = v.clone().into_iter().map(MoveValue).collect(); @@ -142,13 +145,14 @@ impl serde::Serialize for MoveValue { } AnnotatedMoveValue::Bytes(v) => hex::encode(v).serialize(serializer), AnnotatedMoveValue::Struct(v) => MoveStruct(v.clone()).serialize(serializer), + _ => todo!("XXX FIXME YSG"), } } } fn parse_struct_tag(input: &str) -> anyhow::Result { match parse_type_tag(input)? { - TypeTag::Struct(s) => Ok(s), + TypeTag::Struct(s) => Ok(*s), _ => { anyhow::bail!("invalid struct tag") } diff --git a/cmd/starcoin/Cargo.toml b/cmd/starcoin/Cargo.toml index 8b107e4101..89dc578f66 100644 --- a/cmd/starcoin/Cargo.toml +++ b/cmd/starcoin/Cargo.toml @@ -5,7 +5,7 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } crossbeam-channel = { workspace = true } forkable-jellyfish-merkle = { workspace = true } futures = { workspace = true } @@ -19,7 +19,7 @@ network-types = { workspace = true } rand = { workspace = true } scmd = { workspace = true } serde = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-abi-decoder = { workspace = true } starcoin-abi-resolver = { workspace = true } starcoin-abi-types = { workspace = true } @@ -50,7 +50,7 @@ starcoin-types = { workspace = true } starcoin-vm-runtime = { workspace = true } starcoin-vm-types = { workspace = true } stdlib = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } vm-status-translator = { workspace = true } [dev-dependencies] diff --git a/cmd/starcoin/src/account/accept_token_cmd.rs b/cmd/starcoin/src/account/accept_token_cmd.rs index 81821a6f44..416976187b 100644 --- a/cmd/starcoin/src/account/accept_token_cmd.rs +++ b/cmd/starcoin/src/account/accept_token_cmd.rs @@ -46,7 +46,9 @@ impl CommandAction for AcceptTokenCommand { TransactionPayload::ScriptFunction(ScriptFunction::new( ModuleId::new(core_code_address(), Identifier::new("Account").unwrap()), Identifier::new("accept_token").unwrap(), - vec![TypeTag::Struct(opt.token_code.clone().try_into().unwrap())], + vec![TypeTag::Struct(Box::new( + opt.token_code.clone().try_into().unwrap(), + ))], vec![], )), ) diff --git a/cmd/starcoin/src/dev/compile_cmd.rs b/cmd/starcoin/src/dev/compile_cmd.rs index 0b3ba4a811..7350e86e82 100644 --- a/cmd/starcoin/src/dev/compile_cmd.rs +++ b/cmd/starcoin/src/dev/compile_cmd.rs @@ -99,8 +99,7 @@ impl CommandAction for CompileCommand { )? } else { let targets = vec![source_file_or_dir.to_string_lossy().to_string()]; - Compiler::new(&targets, &deps) - .set_named_address_values(starcoin_framework_named_addresses()) + Compiler::from_files(targets, deps, starcoin_framework_named_addresses()) .set_flags(Flags::empty().set_sources_shadow_deps(true)) .build()? }; @@ -165,7 +164,7 @@ impl CommandAction for CompileCommand { file_path.set_extension(MOVE_COMPILED_EXTENSION); let mut file = File::create(file_path.as_path()) .map_err(|e| format_err!("create file({:?} error: {:?})", file_path, e))?; - file.write_all(&unit.serialize()) + file.write_all(&unit.serialize(None)) .map_err(|e| format_err!("write file({:?} error: {:?})", file_path, e))?; results.push(file_path.to_string_lossy().to_string()); } diff --git a/cmd/starcoin/src/view.rs b/cmd/starcoin/src/view.rs index fff79c773d..1094c16e0c 100644 --- a/cmd/starcoin/src/view.rs +++ b/cmd/starcoin/src/view.rs @@ -173,7 +173,7 @@ pub enum EventDataView { impl EventDataView { pub fn new(event_type_tag: &TypeTag, event_data: &[u8]) -> anyhow::Result { - if event_type_tag == &TypeTag::Struct(DepositEvent::struct_tag()) { + if event_type_tag == &TypeTag::Struct(Box::new(DepositEvent::struct_tag())) { if let Ok(received_event) = DepositEvent::try_from_bytes(event_data) { Ok(EventDataView::ReceivedPayment { amount: received_event.amount(), @@ -183,7 +183,7 @@ impl EventDataView { } else { Err(format_err!("Unable to parse ReceivedPaymentEvent")) } - } else if event_type_tag == &TypeTag::Struct(WithdrawEvent::struct_tag()) { + } else if event_type_tag == &TypeTag::Struct(Box::new(WithdrawEvent::struct_tag())) { if let Ok(sent_event) = WithdrawEvent::try_from_bytes(event_data) { Ok(EventDataView::SentPayment { amount: sent_event.amount(), @@ -193,7 +193,7 @@ impl EventDataView { } else { Err(format_err!("Unable to parse SentPaymentEvent")) } - } else if event_type_tag == &TypeTag::Struct(MintEvent::struct_tag()) { + } else if event_type_tag == &TypeTag::Struct(Box::new(MintEvent::struct_tag())) { if let Ok(mint_event) = MintEvent::try_from_bytes(event_data) { Ok(EventDataView::Mint { amount: mint_event.amount(), @@ -202,7 +202,7 @@ impl EventDataView { } else { Err(format_err!("Unable to parse MintEvent")) } - } else if event_type_tag == &TypeTag::Struct(ProposalCreatedEvent::struct_tag()) { + } else if event_type_tag == &TypeTag::Struct(Box::new(ProposalCreatedEvent::struct_tag())) { if let Ok(event) = ProposalCreatedEvent::try_from_bytes(event_data) { Ok(EventDataView::ProposalCreated { proposal_id: event.proposal_id, @@ -211,7 +211,7 @@ impl EventDataView { } else { Err(format_err!("Unable to parse ProposalCreatedEvent")) } - } else if event_type_tag == &TypeTag::Struct(VoteChangedEvent::struct_tag()) { + } else if event_type_tag == &TypeTag::Struct(Box::new(VoteChangedEvent::struct_tag())) { if let Ok(event) = VoteChangedEvent::try_from_bytes(event_data) { Ok(EventDataView::VoteChanged { proposal_id: event.proposal_id, @@ -223,7 +223,7 @@ impl EventDataView { } else { Err(format_err!("Unable to parse VoteChangedEvent")) } - } else if event_type_tag == &TypeTag::Struct(AcceptTokenEvent::struct_tag()) { + } else if event_type_tag == &TypeTag::Struct(Box::new(AcceptTokenEvent::struct_tag())) { if let Ok(event) = AcceptTokenEvent::try_from_bytes(event_data) { Ok(EventDataView::AcceptToken { token_code: event.token_code().to_string(), @@ -231,7 +231,7 @@ impl EventDataView { } else { Err(format_err!("Unable to parse VoteChangedEvent")) } - } else if event_type_tag == &TypeTag::Struct(BlockRewardEvent::struct_tag()) { + } else if event_type_tag == &TypeTag::Struct(Box::new(BlockRewardEvent::struct_tag())) { Ok(BlockRewardEvent::try_from_bytes(event_data) .map_err(|_| format_err!("Unable to parse {}", BlockRewardEvent::struct_tag()))? .into()) diff --git a/cmd/tx-factory/Cargo.toml b/cmd/tx-factory/Cargo.toml index 508e319a89..0ddc3f19a5 100644 --- a/cmd/tx-factory/Cargo.toml +++ b/cmd/tx-factory/Cargo.toml @@ -4,8 +4,8 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } -clap = { features = [ "derive",], workspace = true } -ctrlc = { features = [ "termination",], workspace = true } +clap = { features = ["derive"], workspace = true } +ctrlc = { features = ["termination"], workspace = true } futures = { workspace = true } starcoin-account-api = { workspace = true } starcoin-config = { workspace = true } @@ -17,7 +17,7 @@ starcoin-rpc-client = { workspace = true } starcoin-state-api = { workspace = true } starcoin-transaction-builder = { workspace = true } starcoin-types = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [package] authors = { workspace = true } diff --git a/commons/accumulator/Cargo.toml b/commons/accumulator/Cargo.toml index dd11c1702a..3c791e8492 100644 --- a/commons/accumulator/Cargo.toml +++ b/commons/accumulator/Cargo.toml @@ -20,7 +20,7 @@ rand_core = { default-features = false, workspace = true } [features] default = [] -fuzzing = [ "starcoin-crypto/fuzzing",] +fuzzing = ["starcoin-crypto/fuzzing"] [package] authors = { workspace = true } diff --git a/commons/api-limiter/Cargo.toml b/commons/api-limiter/Cargo.toml index 7d68962823..3bdd865c77 100644 --- a/commons/api-limiter/Cargo.toml +++ b/commons/api-limiter/Cargo.toml @@ -1,7 +1,7 @@ [dependencies] anyhow = { workspace = true } dashmap = { workspace = true } -governor = { features = [ "dashmap",], workspace = true } +governor = { features = ["dashmap"], workspace = true } [package] authors = { workspace = true } diff --git a/commons/forkable-jellyfish-merkle/Cargo.toml b/commons/forkable-jellyfish-merkle/Cargo.toml index 5c2c367808..fb02e90bdb 100644 --- a/commons/forkable-jellyfish-merkle/Cargo.toml +++ b/commons/forkable-jellyfish-merkle/Cargo.toml @@ -13,7 +13,7 @@ num-derive = { workspace = true } num-traits = { workspace = true } proptest = { optional = true, workspace = true } proptest-derive = { optional = true, workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } serde_bytes = { workspace = true } starcoin-crypto = { workspace = true } starcoin-logger = { workspace = true } @@ -30,7 +30,7 @@ starcoin-crypto = { workspace = true } [features] default = [] -fuzzing = [ "proptest", "proptest-derive", "starcoin-crypto/fuzzing",] +fuzzing = ["proptest", "proptest-derive", "starcoin-crypto/fuzzing"] [package] authors = { workspace = true } diff --git a/commons/logger/Cargo.toml b/commons/logger/Cargo.toml index 51379153d5..94dcd0f12c 100644 --- a/commons/logger/Cargo.toml +++ b/commons/logger/Cargo.toml @@ -4,11 +4,11 @@ arc-swap = { workspace = true } chrono = { workspace = true } lazy_static = { workspace = true } log = { workspace = true } -log4rs = { features = [ "background_rotation", "gzip",], workspace = true } +log4rs = { features = ["background_rotation", "gzip"], workspace = true } once_cell = { workspace = true } parking_lot = { workspace = true } schemars = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } slog = { workspace = true } slog-async = { workspace = true } slog-term = { workspace = true } diff --git a/commons/metrics/Cargo.toml b/commons/metrics/Cargo.toml index 6305a69f89..8692fcafed 100644 --- a/commons/metrics/Cargo.toml +++ b/commons/metrics/Cargo.toml @@ -1,13 +1,13 @@ [dependencies] anyhow = { workspace = true } prometheus = { default-features = false, workspace = true } -serde_json = { features = ["arbitrary_precision", ], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-logger = { workspace = true } futures = { optional = true, workspace = true } -hyper = { features = ["full", ], optional = true, workspace = true } +hyper = { features = ["full"], optional = true, workspace = true } [features] -server = ["prometheus/push", "hyper", "futures", ] +server = ["prometheus/push", "hyper", "futures"] [package] authors = { workspace = true } @@ -22,5 +22,9 @@ repository = { workspace = true } rust-version = { workspace = true } [target."cfg(any(target_os = \"macos\", target_os=\"linux\"))".dependencies] -psutil = { version = "3.2", default-features = false, features = ["cpu", "memory", "process", ] } +psutil = { version = "3.2", default-features = false, features = [ + "cpu", + "memory", + "process", +] } timeout-join-handler = { workspace = true } diff --git a/commons/proptest-helpers/Cargo.toml b/commons/proptest-helpers/Cargo.toml index be115658cc..48a2a8db84 100644 --- a/commons/proptest-helpers/Cargo.toml +++ b/commons/proptest-helpers/Cargo.toml @@ -8,6 +8,6 @@ version = "1.12.9" [dependencies] crossbeam = "0.7.3" -diem-proptest-helpers = {package = "diem-proptest-helpers", git = "https://github.com/starcoinorg/move", rev = "2b85bf33378a4469e40b10e7bed815bdbefc5d03"} +diem-proptest-helpers = { package = "diem-proptest-helpers", git = "https://github.com/starcoinorg/move", rev = "a781b641dd345c3e8f3e83ed080597f6c23a157c" } proptest = "1.0.0" proptest-derive = "0.3.0" diff --git a/commons/scmd/Cargo.toml b/commons/scmd/Cargo.toml index 2b3f3634c4..3a85d46d96 100644 --- a/commons/scmd/Cargo.toml +++ b/commons/scmd/Cargo.toml @@ -1,14 +1,14 @@ [dependencies] anyhow = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } cli-table = { workspace = true } jpst = { workspace = true } once_cell = { workspace = true } rust-flatten-json = { workspace = true } rustyline = { workspace = true } rustyline-derive = { workspace = true } -serde = { features = [ "derive",], workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde = { features = ["derive"], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } thiserror = { workspace = true } [dev-dependencies] diff --git a/commons/serde-helpers/Cargo.toml b/commons/serde-helpers/Cargo.toml index 6208fed9d7..1f0897a59f 100644 --- a/commons/serde-helpers/Cargo.toml +++ b/commons/serde-helpers/Cargo.toml @@ -1,11 +1,11 @@ [dependencies] hex = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } serde_bytes = { workspace = true } [dev-dependencies] bcs-ext = { package = "bcs-ext", workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } [package] authors = { workspace = true } diff --git a/commons/service-registry/Cargo.toml b/commons/service-registry/Cargo.toml index f8208d8270..5e84d60a5b 100644 --- a/commons/service-registry/Cargo.toml +++ b/commons/service-registry/Cargo.toml @@ -8,7 +8,7 @@ futures-timer = { workspace = true } log = { workspace = true } once_cell = { workspace = true } schemars = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } thiserror = { workspace = true } tokio = { workspace = true } diff --git a/commons/stest/Cargo.toml b/commons/stest/Cargo.toml index fb6e626a93..6e26d52e6e 100644 --- a/commons/stest/Cargo.toml +++ b/commons/stest/Cargo.toml @@ -7,7 +7,7 @@ log = { workspace = true } starcoin-logger = { workspace = true } stest-macro = { workspace = true } timeout-join-handler = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [package] authors = { workspace = true } diff --git a/commons/stream-task/Cargo.toml b/commons/stream-task/Cargo.toml index 725fad89cd..b239a81f91 100644 --- a/commons/stream-task/Cargo.toml +++ b/commons/stream-task/Cargo.toml @@ -9,7 +9,7 @@ parking_lot = { workspace = true } pin-project = { workspace = true } pin-utils = { workspace = true } schemars = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } thiserror = { workspace = true } tokio = { workspace = true } diff --git a/commons/system/Cargo.toml b/commons/system/Cargo.toml index 707451888b..85c9bf406f 100644 --- a/commons/system/Cargo.toml +++ b/commons/system/Cargo.toml @@ -7,5 +7,5 @@ publish = false version = "1.12.9" [dependencies] -anyhow = "1.0.37" +anyhow = { workspace = true } systemstat = "0.1.6" diff --git a/commons/utils/Cargo.toml b/commons/utils/Cargo.toml index 0bee31eb09..4a069815c4 100644 --- a/commons/utils/Cargo.toml +++ b/commons/utils/Cargo.toml @@ -8,7 +8,7 @@ prometheus = { workspace = true } simple-stopwatch = { workspace = true } [features] -default = [ "metered",] +default = ["metered"] metered = [] [package] diff --git a/config/Cargo.toml b/config/Cargo.toml index a4bb355f8d..2db81e864f 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -1,6 +1,6 @@ [dependencies] anyhow = { workspace = true } -clap = { features = [ "derive", "cargo",], workspace = true } +clap = { features = ["derive", "cargo"], workspace = true } dirs-next = { workspace = true } git-version = { workspace = true } hex = { workspace = true } @@ -16,8 +16,8 @@ parking_lot = { workspace = true } rand = { workspace = true } rand_core = { default-features = false, workspace = true } schemars = { workspace = true } -serde = { features = [ "derive",], workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde = { features = ["derive"], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-account-api = { workspace = true } starcoin-crypto = { workspace = true } starcoin-logger = { package = "starcoin-logger", workspace = true } @@ -27,6 +27,8 @@ starcoin-time-service = { workspace = true } starcoin-types = { workspace = true } starcoin-uint = { workspace = true } starcoin-vm-types = { workspace = true } +starcoin-gas-algebra-ext = { workspace = true } +starcoin-gas = { workspace = true } stdlib = { workspace = true } tempfile = { workspace = true } thiserror = { workspace = true } diff --git a/config/example/proxima/genesis_config.json b/config/example/proxima/genesis_config.json index 6af60fc5a2..480eb4dd8e 100644 --- a/config/example/proxima/genesis_config.json +++ b/config/example/proxima/genesis_config.json @@ -2,7 +2,7 @@ "genesis_block_parameter": { "Static": { "parent_hash": "0xb9215327433b65d5f98f4155d39b06d9a74cc40886857ad510d753022b903f05", - "timestamp": 1644560891000, + "timestamp": 1661944080000, "difficulty": "0x64" } }, @@ -267,6 +267,38 @@ { "instruction_gas": 27, "memory_gas": 1 + }, + { + "instruction_gas": 84, + "memory_gas": 1 + }, + { + "instruction_gas": 98, + "memory_gas": 1 + }, + { + "instruction_gas": 1334, + "memory_gas": 1 + }, + { + "instruction_gas": 1902, + "memory_gas": 1 + }, + { + "instruction_gas": 53, + "memory_gas": 1 + }, + { + "instruction_gas": 227, + "memory_gas": 1 + }, + { + "instruction_gas": 572, + "memory_gas": 1 + }, + { + "instruction_gas": 1436, + "memory_gas": 1 } ], "native_table": [ @@ -353,6 +385,98 @@ { "instruction_gas": 64, "memory_gas": 1 + }, + { + "instruction_gas": 64, + "memory_gas": 1 + }, + { + "instruction_gas": 128, + "memory_gas": 1 + }, + { + "instruction_gas": 2, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 + }, + { + "instruction_gas": 10, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 + }, + { + "instruction_gas": 8, + "memory_gas": 1 + }, + { + "instruction_gas": 40, + "memory_gas": 1 + }, + { + "instruction_gas": 20, + "memory_gas": 1 + }, + { + "instruction_gas": 10, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 + }, + { + "instruction_gas": 10, + "memory_gas": 1 + }, + { + "instruction_gas": 8, + "memory_gas": 1 + }, + { + "instruction_gas": 40, + "memory_gas": 1 + }, + { + "instruction_gas": 20, + "memory_gas": 1 + }, + { + "instruction_gas": 73, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 + }, + { + "instruction_gas": 4, + "memory_gas": 1 } ], "gas_constants": { @@ -392,9 +516,7 @@ "0x068b8493d8c533fd08568429274e49639518a8517f6ab03a0f0cc37edcbdfdd0071855fd941dbcefeb9e4da9f417c7b0f39f73226c9310d39881ae13b45017fa67cc9cb01386e9f5e321b078d4d3a2925b520f955cf7dfd9f6891de366c186ce6ec4a3d5a1c6c795126e5ee1222e23f9a28266c07ecce3e2cd19c6e123b465c091bc45a1fa7f778c66c37af15f3e81ff511e69ff0481bcfaab7b4673f469a3d29760cacf5dd0105a541b5f50720b9577a4c3ff7475554afedbf6a884777f9db4c461fe9aca18df90ed31ee967fe49ed47756311eaa2a6042b7aff1422e48643dc7a0004e0ca3e6b8e548c80d76eeb88e84a82f6b863a1346eabadfe4d5d9be86f98fa72c63f1e1a3f193d4ff71e10dbf364200b221e1a7f71cfab55cc7f7ad2a05" ], "genesis_key_pair": null, - "stdlib_version": { - "Version": 10 - }, + "stdlib_version": "Latest", "dao_config": { "voting_delay": 60000, "voting_period": 600000, diff --git a/config/src/genesis_config.rs b/config/src/genesis_config.rs index 6be6f114af..08ad5d1153 100644 --- a/config/src/genesis_config.rs +++ b/config/src/genesis_config.rs @@ -14,18 +14,20 @@ use starcoin_crypto::{ multi_ed25519::{genesis_multi_key_pair, MultiEd25519PublicKey}, HashValue, ValidCryptoMaterialStringExt, }; +use starcoin_gas::StarcoinGasParameters; +use starcoin_gas_algebra_ext::{CostTable, FromOnChainGasSchedule}; use starcoin_time_service::{TimeService, TimeServiceType}; use starcoin_uint::U256; use starcoin_vm_types::account_config::genesis_address; use starcoin_vm_types::event::EventHandle; use starcoin_vm_types::gas_schedule::{ - latest_cost_table, CostTable, G_GAS_CONSTANTS_V1, G_GAS_CONSTANTS_V2, G_GAS_CONSTANTS_V3, - G_LATEST_GAS_SCHEDULE, G_TEST_GAS_CONSTANTS, + latest_cost_table, G_GAS_CONSTANTS_V1, G_GAS_CONSTANTS_V2, G_LATEST_GAS_SCHEDULE, + G_TEST_GAS_CONSTANTS, }; use starcoin_vm_types::genesis_config::{ChainId, ConsensusStrategy, StdlibVersion}; use starcoin_vm_types::on_chain_config::{ instruction_table_v1, native_table_v1, native_table_v2, ConsensusConfig, DaoConfig, - TransactionPublishOption, VMConfig, Version, + GasSchedule, TransactionPublishOption, VMConfig, Version, }; use starcoin_vm_types::on_chain_resource::Epoch; use starcoin_vm_types::token::stc::STCUnit; @@ -586,7 +588,7 @@ pub enum GenesisBlockParameterConfig { } /// GenesisConfig is a config for initialize a chain genesis. -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct GenesisConfig { /// Parameter for init genesis block pub genesis_block_parameter: GenesisBlockParameterConfig, @@ -874,12 +876,12 @@ pub static G_PROXIMA_BOOT_NODES: Lazy> = Lazy::new(|| { }); pub static G_PROXIMA_CONFIG: Lazy = Lazy::new(|| { - let stdlib_version = StdlibVersion::Version(10); + let stdlib_version = StdlibVersion::Latest; let association_public_key = "068b8493d8c533fd08568429274e49639518a8517f6ab03a0f0cc37edcbdfdd0071855fd941dbcefeb9e4da9f417c7b0f39f73226c9310d39881ae13b45017fa67cc9cb01386e9f5e321b078d4d3a2925b520f955cf7dfd9f6891de366c186ce6ec4a3d5a1c6c795126e5ee1222e23f9a28266c07ecce3e2cd19c6e123b465c091bc45a1fa7f778c66c37af15f3e81ff511e69ff0481bcfaab7b4673f469a3d29760cacf5dd0105a541b5f50720b9577a4c3ff7475554afedbf6a884777f9db4c461fe9aca18df90ed31ee967fe49ed47756311eaa2a6042b7aff1422e48643dc7a0004e0ca3e6b8e548c80d76eeb88e84a82f6b863a1346eabadfe4d5d9be86f98fa72c63f1e1a3f193d4ff71e10dbf364200b221e1a7f71cfab55cc7f7ad2a05"; GenesisConfig { genesis_block_parameter: GenesisBlockParameterConfig::Static(GenesisBlockParameter { parent_hash: HashValue::sha3_256_of(b"starcoin_proxima"), - timestamp: 1644560891000, + timestamp: 1661944080000, difficulty: 100.into(), }), version: Version { major: 1 }, @@ -888,11 +890,7 @@ pub static G_PROXIMA_CONFIG: Lazy = Lazy::new(|| { time_mint_amount: G_DEFAULT_TIME_LOCKED_AMOUNT.scaling(), time_mint_period: G_DEFAULT_TIME_LOCKED_PERIOD / 12, vm_config: VMConfig { - gas_schedule: CostTable { - instruction_table: instruction_table_v1(), - native_table: native_table_v2(), - gas_constants: G_GAS_CONSTANTS_V3.clone(), - }, + gas_schedule: G_LATEST_GAS_SCHEDULE.clone(), }, publishing_option: TransactionPublishOption::open(), consensus_config: ConsensusConfig { @@ -1046,3 +1044,179 @@ pub static G_MAIN_CONFIG: Lazy = Lazy::new(|| { transaction_timeout: ONE_DAY, } }); + +pub static G_LATEST_GAS_PARAMS: Lazy = Lazy::new(|| { + let vm_config = VMConfig { + gas_schedule: G_LATEST_GAS_SCHEDULE.clone(), + }; + let gas_schedule = GasSchedule::from(&vm_config); + StarcoinGasParameters::from_on_chain_gas_schedule(&gas_schedule.to_btree_map()).unwrap() +}); + +#[cfg(test)] +mod tests { + use starcoin_gas::StarcoinGasParameters; + use starcoin_gas_algebra_ext::{CostTable, FromOnChainGasSchedule}; + use starcoin_vm_types::gas_schedule::{ + latest_cost_table, G_GAS_CONSTANTS_V1, G_GAS_CONSTANTS_V2, G_LATEST_GAS_SCHEDULE, + G_TEST_GAS_CONSTANTS, + }; + use starcoin_vm_types::on_chain_config::{ + instruction_gas_schedule_v1, instruction_gas_schedule_v2, instruction_table_v1, + native_gas_schedule_v1, native_gas_schedule_v2, native_gas_schedule_v4, native_table_v1, + native_table_v2, txn_gas_schedule_test, txn_gas_schedule_v1, txn_gas_schedule_v2, + txn_gas_schedule_v3, GasSchedule, VMConfig, + }; + + fn config_entries( + instrs: Vec<(String, u64)>, + natives: Vec<(String, u64)>, + constants: Vec<(String, u64)>, + ) -> Vec<(String, u64)> { + let mut entries = instrs; + let mut natives = natives; + let mut constants = constants; + entries.push(("instr.ld_u16".to_string(), 3)); + entries.push(("instr.ld_u32".to_string(), 2)); + entries.push(("instr.ld_u256".to_string(), 3)); + entries.push(("instr.cast_u16".to_string(), 3)); + entries.push(("instr.cast_u32".to_string(), 2)); + entries.push(("instr.cast_u256".to_string(), 3)); + entries.append(&mut natives); + // native_table don't have these + entries.push(("nursery.debug.print.base_cost".to_string(), 1)); + entries.push(("nursery.debug.print_stack_trace.base_cost".to_string(), 1)); + + entries.push(( + "move_stdlib.hash.sha2_256.legacy_min_input_len".to_string(), + 1, + )); + entries.push(( + "move_stdlib.hash.sha3_256.legacy_min_input_len".to_string(), + 1, + )); + entries.push(("move_stdlib.bcs.to_bytes.failure".to_string(), 182)); + entries.push(( + "move_stdlib.bcs.to_bytes.legacy_min_output_size".to_string(), + 1, + )); + entries.append(&mut constants); + entries + } + + #[test] + fn test_dev_config() { + let vm_config = VMConfig { + gas_schedule: latest_cost_table(G_TEST_GAS_CONSTANTS.clone()), + }; + + let entries = config_entries( + instruction_gas_schedule_v2(), + native_gas_schedule_v4(), + txn_gas_schedule_test(), + ); + + let gas_schedule = GasSchedule::from(&vm_config); + assert_eq!(entries, gas_schedule.entries); + let gas_params = + StarcoinGasParameters::from_on_chain_gas_schedule(&gas_schedule.to_btree_map()); + assert_eq!( + gas_params.unwrap().natives.nursery.debug.print.base_cost, + 1.into() + ); + } + + #[test] + fn test_halley_config() { + let vm_config = VMConfig { + gas_schedule: G_LATEST_GAS_SCHEDULE.clone(), + }; + + let entries = config_entries( + instruction_gas_schedule_v2(), + native_gas_schedule_v4(), + txn_gas_schedule_v3(), + ); + + let gas_schedule = GasSchedule::from(&vm_config); + assert_eq!(entries, gas_schedule.entries); + let gas_params = + StarcoinGasParameters::from_on_chain_gas_schedule(&gas_schedule.to_btree_map()); + assert_eq!( + gas_params.unwrap().natives.nursery.debug.print.base_cost, + 1.into() + ); + } + + #[test] + fn test_proxima_config() { + let vm_config = VMConfig { + gas_schedule: G_LATEST_GAS_SCHEDULE.clone(), + }; + + let entries = config_entries( + instruction_gas_schedule_v2(), + native_gas_schedule_v4(), + txn_gas_schedule_v3(), + ); + let gas_schedule = GasSchedule::from(&vm_config); + assert_eq!(entries, gas_schedule.entries); + let gas_params = + StarcoinGasParameters::from_on_chain_gas_schedule(&gas_schedule.to_btree_map()); + assert_eq!( + gas_params.unwrap().natives.nursery.debug.print.base_cost, + 1.into() + ); + } + + #[test] + fn test_barnard_config() { + let vm_config = VMConfig { + gas_schedule: CostTable { + instruction_table: instruction_table_v1(), + native_table: native_table_v1(), + gas_constants: G_GAS_CONSTANTS_V1.clone(), + }, + }; + + let entries = config_entries( + instruction_gas_schedule_v1(), + native_gas_schedule_v1(), + txn_gas_schedule_v1(), + ); + let gas_schedule = GasSchedule::from(&vm_config); + assert_eq!(entries, gas_schedule.entries); + let gas_params = + StarcoinGasParameters::from_on_chain_gas_schedule(&gas_schedule.to_btree_map()); + assert_eq!( + gas_params.unwrap().natives.nursery.debug.print.base_cost, + 1.into() + ); + } + + #[test] + fn test_main_config() { + let vm_config = VMConfig { + gas_schedule: CostTable { + instruction_table: instruction_table_v1(), + native_table: native_table_v2(), + gas_constants: G_GAS_CONSTANTS_V2.clone(), + }, + }; + + let entries = config_entries( + instruction_gas_schedule_v1(), + native_gas_schedule_v2(), + txn_gas_schedule_v2(), + ); + + let gas_schedule = GasSchedule::from(&vm_config); + assert_eq!(entries, gas_schedule.entries); + let gas_params = + StarcoinGasParameters::from_on_chain_gas_schedule(&gas_schedule.to_btree_map()); + assert_eq!( + gas_params.unwrap().natives.nursery.debug.print.base_cost, + 1.into() + ); + } +} diff --git a/config/src/tests.rs b/config/src/tests.rs index 45cef3d652..5f3120774e 100644 --- a/config/src/tests.rs +++ b/config/src/tests.rs @@ -3,7 +3,6 @@ use super::*; use crate::helper::to_toml; -use starcoin_vm_types::gas_schedule::GasAlgebra; #[test] fn test_generate_and_load() -> Result<()> { @@ -165,7 +164,6 @@ fn test_genesis_config_security() { .gas_schedule .gas_constants .min_price_per_gas_unit - .get() > 0 ); // maximum_number_of_gas_units must be less than base_block_gas_limit @@ -175,7 +173,6 @@ fn test_genesis_config_security() { .gas_schedule .gas_constants .maximum_number_of_gas_units - .get() < genesis_config.consensus_config.base_block_gas_limit ); } diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 5ed0f0ce8d..a3dc108bb2 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -27,7 +27,7 @@ stest = { workspace = true } [features] default = [] -fuzzing = [ "proptest", "proptest-derive", "starcoin-types/fuzzing",] +fuzzing = ["proptest", "proptest-derive", "starcoin-types/fuzzing"] [package] authors = { workspace = true } diff --git a/consensus/src/lib.rs b/consensus/src/lib.rs index a1588f90dd..8b870c6d2e 100644 --- a/consensus/src/lib.rs +++ b/consensus/src/lib.rs @@ -44,8 +44,9 @@ pub fn set_header_nonce(header: &[u8], nonce: u32, extra: &BlockHeaderExtra) -> return vec![]; } let mut header = header.to_owned(); - let _ = header[39..].as_mut().write_u32::(nonce); - let _ = header[35..39].as_mut().write_all(extra.as_slice()); + // XXX FIXME YSG, why need change code? + let _ = <[u8] as AsMut<[u8]>>::as_mut(&mut header[39..]).write_u32::(nonce); + let _ = <[u8] as AsMut<[u8]>>::as_mut(&mut header[35..39]).write_all(extra.as_slice()); header } diff --git a/dataformat-generator/Cargo.toml b/dataformat-generator/Cargo.toml index 27605ae5fd..7c5bc404e2 100644 --- a/dataformat-generator/Cargo.toml +++ b/dataformat-generator/Cargo.toml @@ -1,11 +1,12 @@ [build-dependencies] -serde-reflection = "~0.3" -starcoin-crypto = { git = "https://github.com/starcoinorg/starcoin-crypto", rev = "d871dfb4216f034ee334a575926c101574d9d6dc" } -starcoin-types = { path = "../types" } -anyhow = "1.0" -bcs-ext = { package = "bcs-ext", path = "../commons/bcs_ext" } -serde = "1.0.130" -serde_yaml = "0.8" +serde-reflection = { workspace = true } +starcoin-crypto = { package = "starcoin-crypto", workspace = true } +starcoin-types = { package = "starcoin-types", workspace = true } +anyhow = { workspace = true } +bcs-ext = { package = "bcs-ext", workspace = true } +serde = { features = ["derive"], workspace = true } +serde_yaml = { workspace = true } +starcoin-vm-types = { workspace = true } [dependencies] diff --git a/dataformat-generator/build.rs b/dataformat-generator/build.rs index 4cb5ca10bf..75aa1db2d9 100644 --- a/dataformat-generator/build.rs +++ b/dataformat-generator/build.rs @@ -26,6 +26,7 @@ use starcoin_types::transaction::{ TransactionPayload, }; use starcoin_types::write_set::{WriteOp, WriteSet}; +use starcoin_vm_types::state_store::state_key::StateKey; fn main() { generate().unwrap(); @@ -72,6 +73,7 @@ fn generate() -> Result<(), Error> { )?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/etc/starcoin_types.yml b/etc/starcoin_types.yml index 38625ca7a2..ea11e85123 100644 --- a/etc/starcoin_types.yml +++ b/etc/starcoin_types.yml @@ -199,6 +199,16 @@ SignedUserTransaction: SigningMessage: NEWTYPESTRUCT: SEQ: U8 +StateKey: + ENUM: + 0: + AccessPath: + NEWTYPE: + TYPENAME: AccessPath + 1: + TableItem: + NEWTYPE: + TYPENAME: TableItem StructTag: STRUCT: - address: @@ -210,6 +220,14 @@ StructTag: - type_args: SEQ: TYPENAME: TypeTag +TableHandle: + NEWTYPESTRUCT: + TYPENAME: AccountAddress +TableItem: + STRUCT: + - handle: + TYPENAME: TableHandle + - key: BYTES Transaction: ENUM: 0: @@ -241,6 +259,18 @@ TransactionArgument: 5: Bool: NEWTYPE: BOOL + 6: + U16: + NEWTYPE: U16 + 7: + U32: + NEWTYPE: U32 + 8: + U256: + NEWTYPE: + TUPLEARRAY: + CONTENT: U8 + SIZE: 32 TransactionAuthenticator: ENUM: 0: @@ -307,6 +337,12 @@ TypeTag: struct: NEWTYPE: TYPENAME: StructTag + 8: + u16: UNIT + 9: + u32: UNIT + 10: + u256: UNIT WithdrawCapabilityResource: STRUCT: - account_address: @@ -326,5 +362,5 @@ WriteSetMut: - write_set: SEQ: TUPLE: - - TYPENAME: AccessPath + - TYPENAME: StateKey - TYPENAME: WriteOp diff --git a/executor/Cargo.toml b/executor/Cargo.toml index 286f208d24..0b3243e317 100644 --- a/executor/Cargo.toml +++ b/executor/Cargo.toml @@ -33,7 +33,7 @@ move-transactional-test-runner = { workspace = true } [features] default = [] -fuzzing = [ "starcoin-types/fuzzing",] +fuzzing = ["starcoin-types/fuzzing"] [package] authors = { workspace = true } diff --git a/executor/benchmark/Cargo.toml b/executor/benchmark/Cargo.toml index 2cf216214f..34a6030ae6 100644 --- a/executor/benchmark/Cargo.toml +++ b/executor/benchmark/Cargo.toml @@ -1,6 +1,6 @@ [dependencies] anyhow = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } itertools = { default-features = false, workspace = true } rand = { workspace = true } rayon = { workspace = true } diff --git a/executor/src/block_executor.rs b/executor/src/block_executor.rs index 69dc6462b0..6318b6dbe4 100644 --- a/executor/src/block_executor.rs +++ b/executor/src/block_executor.rs @@ -59,7 +59,8 @@ pub fn block_execute( let txn_state_root = chain_state .commit() .map_err(BlockExecutorError::BlockChainStateErr)?; - + #[cfg(testing)] + info!("txn_hash {} gas_used {}", txn_hash, gas_used); executed_data.txn_infos.push(TransactionInfo::new( txn_hash, txn_state_root, diff --git a/executor/tests/error_code_test.rs b/executor/tests/error_code_test.rs index 619661a2bb..a107f1da79 100644 --- a/executor/tests/error_code_test.rs +++ b/executor/tests/error_code_test.rs @@ -181,6 +181,7 @@ fn test_execute_transfer_txn_with_dummy_gas_token_code() -> Result<()> { let txn2 = Transaction::UserTransaction(account1.sign_txn(raw_txn)); let output = execute_and_apply(&chain_state, txn2); //FIXME:: More detailed error code + // XXX FIXME YSG for test assert_eq!( TransactionStatus::Discard(StatusCode::BAD_TRANSACTION_FEE_CURRENCY), *output.status() diff --git a/executor/tests/executor_test.rs b/executor/tests/executor_test.rs index 4a9ec14d26..5cd19f75ec 100644 --- a/executor/tests/executor_test.rs +++ b/executor/tests/executor_test.rs @@ -18,7 +18,6 @@ use starcoin_types::{ account_config, block_metadata::BlockMetadata, transaction::Transaction, transaction::TransactionPayload, transaction::TransactionStatus, }; -use starcoin_vm_types::access_path::AccessPath; use starcoin_vm_types::account_config::genesis_address; use starcoin_vm_types::account_config::AccountResource; use starcoin_vm_types::genesis_config::ChainId; @@ -43,13 +42,14 @@ use starcoin_types::account::Account; use starcoin_types::account_config::G_STC_TOKEN_CODE; use starcoin_vm_runtime::starcoin_vm::StarcoinVM; use starcoin_vm_types::account_config::core_code_address; +use starcoin_vm_types::state_store::state_key::StateKey; use test_helper::txn::create_account_txn_sent_as_association; #[derive(Default)] pub struct NullStateView; impl StateView for NullStateView { - fn get(&self, _access_path: &AccessPath) -> Result>> { + fn get_state_value(&self, _state_key: &StateKey) -> Result>> { Err(anyhow!("No data")) } diff --git a/executor/tests/module_upgrade_test.rs b/executor/tests/module_upgrade_test.rs index b8c636c19c..c9d4e949b6 100644 --- a/executor/tests/module_upgrade_test.rs +++ b/executor/tests/module_upgrade_test.rs @@ -20,6 +20,7 @@ use starcoin_vm_types::genesis_config::{ChainId, StdlibVersion}; use starcoin_vm_types::move_resource::MoveResource; use starcoin_vm_types::on_chain_config::{MoveLanguageVersion, TransactionPublishOption, Version}; use starcoin_vm_types::on_chain_resource::LinearWithdrawCapability; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::token::stc::G_STC_TOKEN_CODE; use starcoin_vm_types::transaction::{Package, TransactionPayload}; use std::convert::TryInto; @@ -45,12 +46,12 @@ fn test_init_script() -> Result<()> { )?; let chain_state = prepare_customized_genesis(&net); - let dao_action_type_tag = TypeTag::Struct(StructTag { + let dao_action_type_tag = TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("UpgradeModuleDaoProposal").unwrap(), name: Identifier::new("UpgradeModule").unwrap(), type_params: vec![], - }); + })); let init_script = ScriptFunction::new( ModuleId::new( @@ -123,12 +124,12 @@ fn test_upgrade_stdlib_with_incremental_package() -> Result<()> { )?; let chain_state = prepare_customized_genesis(&net); - let dao_action_type_tag = TypeTag::Struct(StructTag { + let dao_action_type_tag = TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("UpgradeModuleDaoProposal").unwrap(), name: Identifier::new("UpgradeModule").unwrap(), type_params: vec![], - }); + })); let path = std::path::PathBuf::from("../vm/stdlib/compiled/2/1-2/stdlib.blob") .canonicalize() .unwrap(); @@ -221,8 +222,20 @@ fn test_stdlib_upgrade() -> Result<()> { )?; proposal_id += 1; } + // if upgrade from 11 to later, we need to update language version to 6. + if let StdlibVersion::Version(11) = current_version { + dao_vote_test( + &alice, + &chain_state, + &net, + vote_language_version(&net, 6), + on_chain_config_type_tag(MoveLanguageVersion::type_tag()), + execute_script_on_chain_config(&net, MoveLanguageVersion::type_tag(), proposal_id), + proposal_id, + )?; + proposal_id += 1; + } verify_version_state(current_version, &chain_state)?; - let dao_action_type_tag = new_version.upgrade_module_type_tag(); let package = match load_upgrade_package(current_version, new_version)? { Some(package) => package, @@ -283,6 +296,7 @@ fn test_stdlib_upgrade() -> Result<()> { Ok(()) } + // this is daospace-v12 starcoin-framework // https://github.com/starcoinorg/starcoin-framework/releases/tag/daospace-v12 // in starcoin master we don't use it @@ -320,12 +334,12 @@ fn test_stdlib_upgrade_since_v12() -> Result<()> { }; let package_hash = package.crypto_hash(); - let starcoin_dao_type = TypeTag::Struct(StructTag { + let starcoin_dao_type = TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("StarcoinDAO").unwrap(), name: Identifier::new("StarcoinDAO").unwrap(), type_params: vec![], - }); + })); let vote_script_function = new_version.propose_module_upgrade_function_since_v12( starcoin_dao_type.clone(), "upgrade stdlib", @@ -401,7 +415,7 @@ fn ext_execute_after_upgrade( )?; } StdlibVersion::Version(6) => { - let resource = chain_state.get(&AccessPath::new( + let resource = chain_state.get_state_value(&StateKey::AccessPath(AccessPath::new( genesis_address(), DataPath::Resource(StructTag { address: genesis_address(), @@ -409,7 +423,7 @@ fn ext_execute_after_upgrade( name: Identifier::new("SignerDelegated").unwrap(), type_params: vec![], }), - ))?; + )))?; assert!(resource.is_some()); let genesis_account = chain_state .get_account_resource(genesis_address())? @@ -429,20 +443,22 @@ fn ext_execute_after_upgrade( assert!(version_resource.is_some()); let version = version_resource.unwrap(); assert_eq!(version.major, 2, "expect language version is 2"); - let genesis_nft_info = chain_state.get(&AccessPath::new( - genesis_address(), - DataPath::Resource(StructTag { - address: genesis_address(), - module: Identifier::new("GenesisNFT").unwrap(), - name: Identifier::new("GenesisNFTInfo").unwrap(), - type_params: vec![], - }), - ))?; + let genesis_nft_info = + chain_state.get_state_value(&StateKey::AccessPath(AccessPath::new( + genesis_address(), + DataPath::Resource(StructTag { + address: genesis_address(), + module: Identifier::new("GenesisNFT").unwrap(), + name: Identifier::new("GenesisNFTInfo").unwrap(), + type_params: vec![], + }), + )))?; assert!( genesis_nft_info.is_some(), "expect 0x1::GenesisNFT::GenesisNFTInfo in global storage, but go none." ); } + // this is old daospace-v12 starcoin-framework, // https://github.com/starcoinorg/starcoin-framework/releases/tag/daospace-v12 // master don't use it @@ -720,7 +736,7 @@ fn assert_genesis_resouce_exist( type_params: Vec, ) { let checkpoint = chain_state - .get(&AccessPath::new( + .get_state_value(&StateKey::AccessPath(AccessPath::new( genesis_address(), DataPath::Resource(StructTag { address: genesis_address(), @@ -728,7 +744,7 @@ fn assert_genesis_resouce_exist( name: Identifier::new(name).unwrap(), type_params, }), - )) + ))) .unwrap(); assert!( checkpoint.is_some(), @@ -746,7 +762,7 @@ fn assert_genesis_resouce_not_exist( type_params: Vec, ) { let checkpoint = chain_state - .get(&AccessPath::new( + .get_state_value(&StateKey::AccessPath(AccessPath::new( genesis_address(), DataPath::Resource(StructTag { address: genesis_address(), @@ -754,7 +770,7 @@ fn assert_genesis_resouce_not_exist( name: Identifier::new(name).unwrap(), type_params, }), - )) + ))) .unwrap(); assert!( checkpoint.is_none(), diff --git a/executor/tests/readonly_function_call_test.rs b/executor/tests/readonly_function_call_test.rs index 559fab407e..3e72355ede 100644 --- a/executor/tests/readonly_function_call_test.rs +++ b/executor/tests/readonly_function_call_test.rs @@ -89,12 +89,12 @@ fn test_readonly_function_call() -> Result<()> { None, )?; - let ty = TypeTag::Struct(StructTag { + let ty = TypeTag::Struct(Box::new(StructTag { address: *account1.address(), module: Identifier::new("A").unwrap(), name: Identifier::new("S").unwrap(), type_params: vec![], - }); + })); assert_eq!(result[0].0, ty); #[derive(Serialize, Deserialize)] struct S { diff --git a/executor/tests/script_function_test.rs b/executor/tests/script_function_test.rs index 2583aedfda..3504123fb7 100644 --- a/executor/tests/script_function_test.rs +++ b/executor/tests/script_function_test.rs @@ -178,6 +178,76 @@ fn test_invoke_private_function() -> Result<()> { Ok(()) } +//a test for issue https://github.com/starcoinorg/starcoin/issues/3804 +#[stest::test] +fn test_signer_cap_internal_type_error() -> Result<()> { + let (chain_state, net) = prepare_genesis(); + let alice = Account::new(); + let txn1 = Transaction::UserTransaction(create_account_txn_sent_as_association( + &alice, 0, 50_000_000, 1, &net, + )); + let output1 = execute_and_apply(&chain_state, txn1); + assert_eq!(KeptVMStatus::Executed, output1.status().status().unwrap()); + let module_source = r#" + module {{sender}}::IdentifierNFTTest { + use StarcoinFramework::NFT::{MintCapability, BurnCapability, UpdateCapability}; + use StarcoinFramework::NFT; + + struct Body has store{} + struct Meta has copy, store, drop{} + + struct ShardCap has store, key{ + mint_cap:MintCapability, + burn_cap:BurnCapability, + update_cap:UpdateCapability + } + public(script) fun init(sender: signer){ + let meta_data = NFT::empty_meta(); + NFT::register_v2(&sender, meta_data); + let mint_cap = NFT::remove_mint_capability(&sender); + let update_cap = NFT::remove_update_capability(&sender); + let burn_cap = NFT::remove_burn_capability(&sender); + move_to(&sender,ShardCap{ + mint_cap, + update_cap, + burn_cap + }); + } + } + "#; + let compiled_module = compile_modules_with_address(*alice.address(), module_source) + .pop() + .unwrap(); + let init_script = ScriptFunction::new( + ModuleId::new( + *alice.address(), + Identifier::new("IdentifierNFTTest").unwrap(), + ), + Identifier::new("init").unwrap(), + vec![], + vec![], + ); + let txn = Transaction::UserTransaction(alice.create_signed_txn_impl( + *alice.address(), + TransactionPayload::Package( + Package::new(vec![compiled_module], Some(init_script)).unwrap(), + ), + 0, + 10_000_000, + 1, + 1, + net.chain_id(), + )); + + let output = execute_and_apply(&chain_state, txn); + assert_eq!( + TransactionStatus::Keep(KeptVMStatus::Executed), + output.status().clone() + ); + + Ok(()) +} + #[stest::test] fn test_execute_script() -> Result<()> { let (chain_state, net) = prepare_genesis(); diff --git a/executor/tests/sip_flag_test.rs b/executor/tests/sip_flag_test.rs index 2d718eec89..5a66b17e21 100644 --- a/executor/tests/sip_flag_test.rs +++ b/executor/tests/sip_flag_test.rs @@ -40,7 +40,6 @@ fn test_sip_flags() -> Result<()> { // .unwrap(); // let package = Package::new_with_module(module)?; // let package_hash = package.crypto_hash(); - // let vote_script_function = ScriptFunction::new( // ModuleId::new( // core_code_address(), @@ -78,7 +77,6 @@ fn test_sip_flags() -> Result<()> { // 0, // )?; // association_execute_should_success(&net, &chain_state, TransactionPayload::Package(package))?; - // assert!(chain_state.is_activated(sip_10000)?); Ok(()) } diff --git a/generated/halley/genesis b/generated/halley/genesis new file mode 100644 index 0000000000..35e35c6e84 Binary files /dev/null and b/generated/halley/genesis differ diff --git a/generated/proxima/genesis b/generated/proxima/genesis new file mode 100644 index 0000000000..cb4a0d3786 Binary files /dev/null and b/generated/proxima/genesis differ diff --git a/genesis/Cargo.toml b/genesis/Cargo.toml index eb741a2019..f8981d1f2d 100644 --- a/genesis/Cargo.toml +++ b/genesis/Cargo.toml @@ -1,7 +1,7 @@ [dependencies] anyhow = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } include_dir = { workspace = true } once_cell = { workspace = true } serde = { workspace = true } @@ -16,7 +16,7 @@ starcoin-state-api = { workspace = true } starcoin-statedb = { workspace = true } starcoin-storage = { workspace = true } starcoin-transaction-builder = { workspace = true } -starcoin-types = { features = [ "fuzzing",], workspace = true } +starcoin-types = { features = ["fuzzing"], workspace = true } starcoin-vm-types = { workspace = true } stdlib = { workspace = true } stest = { workspace = true } @@ -24,7 +24,7 @@ thiserror = { workspace = true } [features] default = [] -fuzzing = [ "starcoin-types/fuzzing",] +fuzzing = ["starcoin-types/fuzzing"] [package] authors = { workspace = true } diff --git a/genesis/generated/halley/genesis b/genesis/generated/halley/genesis index 96cd86f540..a71478d010 100644 Binary files a/genesis/generated/halley/genesis and b/genesis/generated/halley/genesis differ diff --git a/genesis/generated/proxima/genesis b/genesis/generated/proxima/genesis index 3c47f4268d..e13d72a40e 100644 Binary files a/genesis/generated/proxima/genesis and b/genesis/generated/proxima/genesis differ diff --git a/miner/Cargo.toml b/miner/Cargo.toml index d2791a72c8..28ea7cc95c 100644 --- a/miner/Cargo.toml +++ b/miner/Cargo.toml @@ -25,7 +25,7 @@ starcoin-storage = { workspace = true } starcoin-txpool = { workspace = true } starcoin-txpool-api = { workspace = true } starcoin-vm-types = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } starcoin-types = { package = "starcoin-types", workspace = true } [dev-dependencies] diff --git a/network-p2p/Cargo.toml b/network-p2p/Cargo.toml index 8c8f4f8b20..72a88e8dad 100644 --- a/network-p2p/Cargo.toml +++ b/network-p2p/Cargo.toml @@ -25,15 +25,18 @@ pin-project = { workspace = true } prometheus = { workspace = true } rand = { workspace = true } sc-peerset = { workspace = true } -serde = { features = [ "derive",], workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde = { features = ["derive"], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } smallvec = { workspace = true } starcoin-crypto = { workspace = true } starcoin-config = { workspace = true } starcoin-metrics = { workspace = true } starcoin-types = { workspace = true } thiserror = { workspace = true } -unsigned-varint = { features = [ "futures", "asynchronous_codec",], workspace = true } +unsigned-varint = { features = [ + "futures", + "asynchronous_codec", +], workspace = true } void = { workspace = true } wasm-timer = { workspace = true } zeroize = { workspace = true } @@ -57,4 +60,3 @@ version = "1.12.9" homepage = { workspace = true } repository = { workspace = true } rust-version = { workspace = true } - diff --git a/network-p2p/peerset/Cargo.toml b/network-p2p/peerset/Cargo.toml index 0e65d7dd7c..0e01a3ae2b 100644 --- a/network-p2p/peerset/Cargo.toml +++ b/network-p2p/peerset/Cargo.toml @@ -2,7 +2,7 @@ futures = { workspace = true } libp2p = { default-features = false, workspace = true } log = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } sp-utils = { workspace = true } wasm-timer = { workspace = true } @@ -23,4 +23,4 @@ publish = { workspace = true } rust-version = { workspace = true } [package.metadata.docs.rs] -targets = [ "x86_64-unknown-linux-gnu",] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/network-p2p/types/Cargo.toml b/network-p2p/types/Cargo.toml index e9131f6238..5a0df8579c 100644 --- a/network-p2p/types/Cargo.toml +++ b/network-p2p/types/Cargo.toml @@ -2,12 +2,14 @@ bitflags = { workspace = true } bytes = { workspace = true } derive_more = { workspace = true } -libp2p = { default-features = false, features = [ "request-response",], workspace = true } +libp2p = { default-features = false, features = [ + "request-response", +], workspace = true } rand = { workspace = true } sc-peerset = { workspace = true } schemars = { workspace = true } -serde = { features = [ "derive",], workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde = { features = ["derive"], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } [features] default = [] diff --git a/network-rpc/Cargo.toml b/network-rpc/Cargo.toml index e3505a35a1..3fe0e7c664 100644 --- a/network-rpc/Cargo.toml +++ b/network-rpc/Cargo.toml @@ -4,9 +4,9 @@ bytes = { workspace = true } futures = { workspace = true } hex = { workspace = true } once_cell = { workspace = true } -serde = { features = ["derive", ], workspace = true } +serde = { features = ["derive"], workspace = true } serde_json = { workspace = true } -tokio = { features = ["full", ], workspace = true } +tokio = { features = ["full"], workspace = true } api-limiter = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } starcoin-crypto = { package = "starcoin-crypto", workspace = true } @@ -40,7 +40,7 @@ starcoin-node = { workspace = true } starcoin-statedb = { package = "starcoin-statedb", workspace = true } starcoin-txpool = { workspace = true } starcoin-txpool-api = { workspace = true } -starcoin-vm-types = { package = "starcoin-vm-types", workspace = true } +starcoin-vm-types = { workspace = true } starcoin-storage = { package = "starcoin-storage", workspace = true } stest = { workspace = true } test-helper = { workspace = true } diff --git a/network-rpc/api/Cargo.toml b/network-rpc/api/Cargo.toml index e8e4eb6065..5df6bbfe30 100644 --- a/network-rpc/api/Cargo.toml +++ b/network-rpc/api/Cargo.toml @@ -6,13 +6,14 @@ futures = { workspace = true } network-rpc-core = { workspace = true } network-rpc-derive = { workspace = true } network-types = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } starcoin-accumulator = { workspace = true } starcoin-crypto = { workspace = true } starcoin-logger = { workspace = true } starcoin-state-api = { workspace = true } starcoin-state-tree = { workspace = true } starcoin-types = { workspace = true } +starcoin-vm-types = { workspace = true } [package] authors = { workspace = true } diff --git a/network-rpc/api/src/lib.rs b/network-rpc/api/src/lib.rs index f053a82aad..d3e2a5a5d5 100644 --- a/network-rpc/api/src/lib.rs +++ b/network-rpc/api/src/lib.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use starcoin_accumulator::node::AccumulatorStoreType; use starcoin_accumulator::AccumulatorNode; use starcoin_crypto::HashValue; -use starcoin_state_api::StateWithProof; +use starcoin_state_api::{StateWithProof, StateWithTableItemProof}; use starcoin_state_tree::StateNode; use starcoin_types::access_path::AccessPath; use starcoin_types::account_address::AccountAddress; @@ -25,6 +25,7 @@ pub use network_rpc_core::RawRpcClient; pub use remote_chain_state::RemoteChainStateReader; pub use starcoin_types::block::BlockBody; +use starcoin_vm_types::state_store::table::TableHandle; pub const MAX_BLOCK_REQUEST_SIZE: u64 = 50; pub const MAX_BLOCK_HEADER_REQUEST_SIZE: u64 = 1000; @@ -278,4 +279,17 @@ pub trait NetworkRpc: Sized + Send + Sync + 'static { peer_id: PeerId, ids: Vec, ) -> BoxFuture>>>; + + fn get_state_with_table_item_proof( + &self, + peer_id: PeerId, + request: GetStateWithTableItemProof, + ) -> BoxFuture>; +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct GetStateWithTableItemProof { + pub state_root: HashValue, + pub handle: TableHandle, + pub key: Vec, } diff --git a/network-rpc/api/src/remote_chain_state.rs b/network-rpc/api/src/remote_chain_state.rs index 1c8799899c..c2433aa0b4 100644 --- a/network-rpc/api/src/remote_chain_state.rs +++ b/network-rpc/api/src/remote_chain_state.rs @@ -1,16 +1,20 @@ // Copyright (c) The Starcoin Core Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{gen_client::NetworkRpcClient, GetAccountState, GetStateWithProof}; +use crate::{ + gen_client::NetworkRpcClient, GetAccountState, GetStateWithProof, GetStateWithTableItemProof, +}; use anyhow::{anyhow, Result}; use network_types::peer_info::PeerId; use starcoin_crypto::HashValue; -use starcoin_state_api::{ChainStateReader, StateView, StateWithProof}; +use starcoin_state_api::{ChainStateReader, StateView, StateWithProof, StateWithTableItemProof}; use starcoin_state_tree::AccountStateSetIterator; use starcoin_types::access_path::AccessPath; use starcoin_types::account_address::AccountAddress; use starcoin_types::account_state::AccountState; use starcoin_types::state_set::{AccountStateSet, ChainStateSet}; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::state_store::table::TableHandle; #[derive(Clone)] pub struct RemoteChainStateReader { @@ -93,12 +97,45 @@ impl ChainStateReader for RemoteChainStateReader { fn dump_iter(&self) -> Result { unimplemented!() } + + fn get_with_table_item_proof( + &self, + handle: &TableHandle, + key: &[u8], + ) -> Result { + let peer_id = self + .peer_id + .clone() + .ok_or_else(|| anyhow!("peer id not set"))?; + let state_root = self + .state_root + .ok_or_else(|| anyhow!("state root not set"))?; + let req = GetStateWithTableItemProof { + state_root, + handle: *handle, + key: key.to_vec(), + }; + let client = self.client.clone(); + let state_table_item_proof: StateWithTableItemProof = + futures::executor::block_on(client.get_state_with_table_item_proof(peer_id, req))?; + state_table_item_proof.verify(handle, key)?; + Ok(state_table_item_proof) + } } impl StateView for RemoteChainStateReader { - fn get(&self, access_path: &AccessPath) -> Result>> { - let state_proof = self.get_with_proof(access_path)?; - Ok(state_proof.state) + fn get_state_value(&self, state_key: &StateKey) -> Result>> { + match state_key { + StateKey::AccessPath(access_path) => { + let state_proof = self.get_with_proof(access_path)?; + Ok(state_proof.state) + } + StateKey::TableItem(table_item) => { + let state_proof = + self.get_with_table_item_proof(&table_item.handle, &table_item.key)?; + Ok(state_proof.key_proof.0) + } + } } fn is_genesis(&self) -> bool { diff --git a/network-rpc/core/Cargo.toml b/network-rpc/core/Cargo.toml index 073c050f42..249bc85dcb 100644 --- a/network-rpc/core/Cargo.toml +++ b/network-rpc/core/Cargo.toml @@ -5,7 +5,7 @@ futures = { workspace = true } log = { workspace = true } network-rpc-derive = { workspace = true } num_enum = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } starcoin-types = { package = "starcoin-types", workspace = true } network-types = { workspace = true } diff --git a/network-rpc/derive/Cargo.toml b/network-rpc/derive/Cargo.toml index 94019cdaa7..d33ef5067d 100644 --- a/network-rpc/derive/Cargo.toml +++ b/network-rpc/derive/Cargo.toml @@ -2,7 +2,7 @@ anyhow = { workspace = true } proc-macro2 = { workspace = true } quote = { workspace = true } -syn = { features = [ "full", "extra-traits", "visit", "fold",], workspace = true } +syn = { features = ["full", "extra-traits", "visit", "fold"], workspace = true } [lib] proc-macro = true diff --git a/network-rpc/src/rpc.rs b/network-rpc/src/rpc.rs index e6e839a9ad..6e01227aad 100644 --- a/network-rpc/src/rpc.rs +++ b/network-rpc/src/rpc.rs @@ -11,12 +11,12 @@ use starcoin_chain_service::{ChainAsyncService, ChainReaderService}; use starcoin_crypto::HashValue; use starcoin_network_rpc_api::{ gen_server, BlockBody, GetAccountState, GetAccumulatorNodeByNodeHash, GetBlockHeadersByNumber, - GetBlockIds, GetStateWithProof, GetTxnsWithHash, GetTxnsWithSize, Ping, RpcRequest, - MAX_BLOCK_HEADER_REQUEST_SIZE, MAX_BLOCK_INFO_REQUEST_SIZE, MAX_BLOCK_REQUEST_SIZE, - MAX_TXN_REQUEST_SIZE, + GetBlockIds, GetStateWithProof, GetStateWithTableItemProof, GetTxnsWithHash, GetTxnsWithSize, + Ping, RpcRequest, MAX_BLOCK_HEADER_REQUEST_SIZE, MAX_BLOCK_INFO_REQUEST_SIZE, + MAX_BLOCK_REQUEST_SIZE, MAX_TXN_REQUEST_SIZE, }; use starcoin_service_registry::ServiceRef; -use starcoin_state_api::{ChainStateAsyncService, StateWithProof}; +use starcoin_state_api::{ChainStateAsyncService, StateWithProof, StateWithTableItemProof}; use starcoin_state_service::ChainStateService; use starcoin_state_tree::StateNode; use starcoin_storage::Store; @@ -237,6 +237,20 @@ impl gen_server::NetworkRpc for NetworkRpcImpl { Box::pin(fut) } + fn get_state_with_table_item_proof( + &self, + _peer_id: PeerId, + req: GetStateWithTableItemProof, + ) -> BoxFuture> { + let state_service = self.state_service.clone(); + let fut = async move { + state_service + .get_with_table_item_proof_by_root(req.handle, req.key, req.state_root) + .await + }; + Box::pin(fut) + } + fn get_account_state( &self, _peer_id: PeerId, diff --git a/network/Cargo.toml b/network/Cargo.toml index a355955512..68612d06fa 100644 --- a/network/Cargo.toml +++ b/network/Cargo.toml @@ -23,8 +23,8 @@ tempfile = { workspace = true } async-std = { workspace = true } async-trait = { workspace = true } derive_more = { workspace = true } -serde = { features = ["derive", ], workspace = true } -serde_json = { features = ["arbitrary_precision", ], workspace = true } +serde = { features = ["derive"], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } stest = { workspace = true } prometheus = { workspace = true } network-api = { workspace = true } @@ -38,7 +38,7 @@ openrpc-rs = { workspace = true } [dev-dependencies] test-helper = { workspace = true } -tokio = { features = ["full", ], workspace = true } +tokio = { features = ["full"], workspace = true } [package] authors = { workspace = true } diff --git a/node/Cargo.toml b/node/Cargo.toml index 88ea10721c..a89313eefa 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -10,7 +10,7 @@ futures = { workspace = true } futures-timer = { workspace = true } network-api = { workspace = true } network-rpc-core = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-account-api = { workspace = true } starcoin-account-service = { workspace = true } starcoin-block-relayer = { workspace = true } @@ -23,7 +23,7 @@ starcoin-dev = { workspace = true } starcoin-executor = { workspace = true } starcoin-genesis = { workspace = true } starcoin-logger = { workspace = true } -starcoin-metrics = { features = [ "server",], workspace = true } +starcoin-metrics = { features = ["server"], workspace = true } starcoin-miner = { workspace = true } starcoin-miner-client = { workspace = true } starcoin-network = { workspace = true } @@ -46,7 +46,7 @@ starcoin-types = { workspace = true } starcoin-vm-runtime = { workspace = true } thiserror = { workspace = true } timeout-join-handler = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [dev-dependencies] stest = { workspace = true } diff --git a/node/api/Cargo.toml b/node/api/Cargo.toml index 0e14fc4c68..e58c6a329e 100644 --- a/node/api/Cargo.toml +++ b/node/api/Cargo.toml @@ -3,7 +3,7 @@ anyhow = { workspace = true } async-trait = { workspace = true } backtrace = { workspace = true } futures = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } starcoin-config = { workspace = true } starcoin-consensus = { workspace = true } starcoin-crypto = { workspace = true } diff --git a/rpc/api/Cargo.toml b/rpc/api/Cargo.toml index 404edfe74a..0b7d139e93 100644 --- a/rpc/api/Cargo.toml +++ b/rpc/api/Cargo.toml @@ -6,11 +6,17 @@ path = "src/generate_schema.rs" anyhow = { workspace = true } async-trait = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } futures = { workspace = true } hex = { workspace = true } -jsonrpc-core = { features = [ "arbitrary_precision",], workspace = true } -jsonrpc-core-client = { features = [ "http", "ipc", "ws", "arbitrary_precision", "tls",], workspace = true } +jsonrpc-core = { features = ["arbitrary_precision"], workspace = true } +jsonrpc-core-client = { features = [ + "http", + "ipc", + "ws", + "arbitrary_precision", + "tls", +], workspace = true } jsonrpc-derive = { workspace = true } jsonrpc-pubsub = { workspace = true } jsonrpc-server-utils = { workspace = true } @@ -21,9 +27,9 @@ openrpc-rs = { workspace = true } openrpc-derive = { workspace = true } openrpc-schema = { workspace = true } schemars = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } serde-helpers = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-abi-decoder = { workspace = true } starcoin-abi-types = { workspace = true } starcoin-account-api = { workspace = true } @@ -51,4 +57,4 @@ publish = { workspace = true } version = "1.12.9" homepage = { workspace = true } repository = { workspace = true } -rust-version = { workspace = true } \ No newline at end of file +rust-version = { workspace = true } diff --git a/rpc/api/generated_rpc_schema/contract_api.json b/rpc/api/generated_rpc_schema/contract_api.json index be1c6e70c4..c8b7c3a166 100644 --- a/rpc/api/generated_rpc_schema/contract_api.json +++ b/rpc/api/generated_rpc_schema/contract_api.json @@ -852,6 +852,7 @@ "explained_status", "gas_used", "status", + "table_item_write_set", "write_set" ], "properties": { @@ -1152,6 +1153,47 @@ } ] }, + "table_item_write_set": { + "type": "array", + "items": { + "type": "object", + "required": [ + "action", + "table_item" + ], + "properties": { + "action": { + "type": "string", + "enum": [ + "Deletion", + "Value" + ] + }, + "table_item": { + "type": "object", + "required": [ + "handle", + "key" + ], + "properties": { + "handle": { + "type": "string", + "format": "AccountAddress" + }, + "key": { + "type": "string" + } + } + }, + "value": { + "type": [ + "string", + "null" + ] + } + } + } + }, "write_set": { "type": "array", "items": { @@ -1280,8 +1322,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -1456,8 +1501,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -1683,8 +1731,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -1925,8 +1976,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -2088,6 +2142,7 @@ "explained_status", "gas_used", "status", + "table_item_write_set", "write_set" ], "properties": { @@ -2388,6 +2443,47 @@ } ] }, + "table_item_write_set": { + "type": "array", + "items": { + "type": "object", + "required": [ + "action", + "table_item" + ], + "properties": { + "action": { + "type": "string", + "enum": [ + "Deletion", + "Value" + ] + }, + "table_item": { + "type": "object", + "required": [ + "handle", + "key" + ], + "properties": { + "handle": { + "type": "string", + "format": "AccountAddress" + }, + "key": { + "type": "string" + } + } + }, + "value": { + "type": [ + "string", + "null" + ] + } + } + } + }, "write_set": { "type": "array", "items": { @@ -2516,8 +2612,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -2692,8 +2791,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -2919,8 +3021,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -3161,8 +3266,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -3348,8 +3456,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -3524,8 +3635,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -3710,8 +3824,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -3930,8 +4047,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -4106,8 +4226,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -4292,8 +4415,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -4508,8 +4634,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -4616,8 +4745,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -4760,8 +4892,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -4925,8 +5060,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -5101,8 +5239,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -5328,8 +5469,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -5529,8 +5673,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] diff --git a/rpc/api/generated_rpc_schema/state.json b/rpc/api/generated_rpc_schema/state.json index 8ee12d4ea8..6b192c78b3 100644 --- a/rpc/api/generated_rpc_schema/state.json +++ b/rpc/api/generated_rpc_schema/state.json @@ -913,6 +913,511 @@ } } }, + { + "name": "state.get_with_table_item_proof", + "params": [ + { + "name": "handle", + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "TableHandle", + "type": "string", + "format": "AccountAddress" + } + }, + { + "name": "key", + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Array_of_uint8", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } + } + ], + "result": { + "name": "StateWithTableItemProofView", + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "StateWithTableItemProofView", + "type": "object", + "required": [ + "key_proof", + "state_proof", + "table_handle_proof" + ], + "properties": { + "key_proof": { + "type": "array", + "items": [ + { + "type": [ + "string", + "null" + ] + }, + { + "type": "object", + "required": [ + "siblings" + ], + "properties": { + "leaf": { + "description": "This proof can be used to authenticate whether a given leaf exists in the tree or not. - If this is `Some(HashValue, HashValue)` - If the first `HashValue` equals requested key, this is an inclusion proof and the second `HashValue` equals the hash of the corresponding account blob. - Otherwise this is a non-inclusion proof. The first `HashValue` is the only key that exists in the subtree and the second `HashValue` equals the hash of the corresponding account blob. - If this is `None`, this is also a non-inclusion proof which indicates the subtree is empty.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "string", + "format": "HashValue" + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "siblings": { + "description": "All siblings in this proof, including the default ones. Siblings are ordered from the bottom level to the root level.", + "type": "array", + "items": { + "type": "string", + "format": "HashValue" + } + } + } + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 3, + "minItems": 3 + }, + "state_proof": { + "type": "array", + "items": [ + { + "type": "object", + "required": [ + "account_proof", + "account_state_proof" + ], + "properties": { + "account_proof": { + "type": "object", + "required": [ + "siblings" + ], + "properties": { + "leaf": { + "description": "This proof can be used to authenticate whether a given leaf exists in the tree or not. - If this is `Some(HashValue, HashValue)` - If the first `HashValue` equals requested key, this is an inclusion proof and the second `HashValue` equals the hash of the corresponding account blob. - Otherwise this is a non-inclusion proof. The first `HashValue` is the only key that exists in the subtree and the second `HashValue` equals the hash of the corresponding account blob. - If this is `None`, this is also a non-inclusion proof which indicates the subtree is empty.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "string", + "format": "HashValue" + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "siblings": { + "description": "All siblings in this proof, including the default ones. Siblings are ordered from the bottom level to the root level.", + "type": "array", + "items": { + "type": "string", + "format": "HashValue" + } + } + } + }, + "account_state": { + "type": [ + "string", + "null" + ] + }, + "account_state_proof": { + "type": "object", + "required": [ + "siblings" + ], + "properties": { + "leaf": { + "description": "This proof can be used to authenticate whether a given leaf exists in the tree or not. - If this is `Some(HashValue, HashValue)` - If the first `HashValue` equals requested key, this is an inclusion proof and the second `HashValue` equals the hash of the corresponding account blob. - Otherwise this is a non-inclusion proof. The first `HashValue` is the only key that exists in the subtree and the second `HashValue` equals the hash of the corresponding account blob. - If this is `None`, this is also a non-inclusion proof which indicates the subtree is empty.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "string", + "format": "HashValue" + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "siblings": { + "description": "All siblings in this proof, including the default ones. Siblings are ordered from the bottom level to the root level.", + "type": "array", + "items": { + "type": "string", + "format": "HashValue" + } + } + } + }, + "state": { + "type": [ + "string", + "null" + ] + } + } + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "table_handle_proof": { + "type": "array", + "items": [ + { + "type": [ + "string", + "null" + ] + }, + { + "type": "object", + "required": [ + "siblings" + ], + "properties": { + "leaf": { + "description": "This proof can be used to authenticate whether a given leaf exists in the tree or not. - If this is `Some(HashValue, HashValue)` - If the first `HashValue` equals requested key, this is an inclusion proof and the second `HashValue` equals the hash of the corresponding account blob. - Otherwise this is a non-inclusion proof. The first `HashValue` is the only key that exists in the subtree and the second `HashValue` equals the hash of the corresponding account blob. - If this is `None`, this is also a non-inclusion proof which indicates the subtree is empty.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "string", + "format": "HashValue" + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "siblings": { + "description": "All siblings in this proof, including the default ones. Siblings are ordered from the bottom level to the root level.", + "type": "array", + "items": { + "type": "string", + "format": "HashValue" + } + } + } + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 3, + "minItems": 3 + } + } + } + } + }, + { + "name": "state.get_with_table_item_proof_by_root", + "params": [ + { + "name": "handle", + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "TableHandle", + "type": "string", + "format": "AccountAddress" + } + }, + { + "name": "key", + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Array_of_uint8", + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } + }, + { + "name": "state_root", + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "HashValue", + "type": "string", + "format": "HashValue" + } + } + ], + "result": { + "name": "StateWithTableItemProofView", + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "StateWithTableItemProofView", + "type": "object", + "required": [ + "key_proof", + "state_proof", + "table_handle_proof" + ], + "properties": { + "key_proof": { + "type": "array", + "items": [ + { + "type": [ + "string", + "null" + ] + }, + { + "type": "object", + "required": [ + "siblings" + ], + "properties": { + "leaf": { + "description": "This proof can be used to authenticate whether a given leaf exists in the tree or not. - If this is `Some(HashValue, HashValue)` - If the first `HashValue` equals requested key, this is an inclusion proof and the second `HashValue` equals the hash of the corresponding account blob. - Otherwise this is a non-inclusion proof. The first `HashValue` is the only key that exists in the subtree and the second `HashValue` equals the hash of the corresponding account blob. - If this is `None`, this is also a non-inclusion proof which indicates the subtree is empty.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "string", + "format": "HashValue" + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "siblings": { + "description": "All siblings in this proof, including the default ones. Siblings are ordered from the bottom level to the root level.", + "type": "array", + "items": { + "type": "string", + "format": "HashValue" + } + } + } + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 3, + "minItems": 3 + }, + "state_proof": { + "type": "array", + "items": [ + { + "type": "object", + "required": [ + "account_proof", + "account_state_proof" + ], + "properties": { + "account_proof": { + "type": "object", + "required": [ + "siblings" + ], + "properties": { + "leaf": { + "description": "This proof can be used to authenticate whether a given leaf exists in the tree or not. - If this is `Some(HashValue, HashValue)` - If the first `HashValue` equals requested key, this is an inclusion proof and the second `HashValue` equals the hash of the corresponding account blob. - Otherwise this is a non-inclusion proof. The first `HashValue` is the only key that exists in the subtree and the second `HashValue` equals the hash of the corresponding account blob. - If this is `None`, this is also a non-inclusion proof which indicates the subtree is empty.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "string", + "format": "HashValue" + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "siblings": { + "description": "All siblings in this proof, including the default ones. Siblings are ordered from the bottom level to the root level.", + "type": "array", + "items": { + "type": "string", + "format": "HashValue" + } + } + } + }, + "account_state": { + "type": [ + "string", + "null" + ] + }, + "account_state_proof": { + "type": "object", + "required": [ + "siblings" + ], + "properties": { + "leaf": { + "description": "This proof can be used to authenticate whether a given leaf exists in the tree or not. - If this is `Some(HashValue, HashValue)` - If the first `HashValue` equals requested key, this is an inclusion proof and the second `HashValue` equals the hash of the corresponding account blob. - Otherwise this is a non-inclusion proof. The first `HashValue` is the only key that exists in the subtree and the second `HashValue` equals the hash of the corresponding account blob. - If this is `None`, this is also a non-inclusion proof which indicates the subtree is empty.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "string", + "format": "HashValue" + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "siblings": { + "description": "All siblings in this proof, including the default ones. Siblings are ordered from the bottom level to the root level.", + "type": "array", + "items": { + "type": "string", + "format": "HashValue" + } + } + } + }, + "state": { + "type": [ + "string", + "null" + ] + } + } + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "table_handle_proof": { + "type": "array", + "items": [ + { + "type": [ + "string", + "null" + ] + }, + { + "type": "object", + "required": [ + "siblings" + ], + "properties": { + "leaf": { + "description": "This proof can be used to authenticate whether a given leaf exists in the tree or not. - If this is `Some(HashValue, HashValue)` - If the first `HashValue` equals requested key, this is an inclusion proof and the second `HashValue` equals the hash of the corresponding account blob. - Otherwise this is a non-inclusion proof. The first `HashValue` is the only key that exists in the subtree and the second `HashValue` equals the hash of the corresponding account blob. - If this is `None`, this is also a non-inclusion proof which indicates the subtree is empty.", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "string", + "format": "HashValue" + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 2, + "minItems": 2 + }, + "siblings": { + "description": "All siblings in this proof, including the default ones. Siblings are ordered from the bottom level to the root level.", + "type": "array", + "items": { + "type": "string", + "format": "HashValue" + } + } + } + }, + { + "type": "string", + "format": "HashValue" + } + ], + "maxItems": 3, + "minItems": 3 + } + } + } + } + }, { "name": "state.get_code", "params": [ @@ -1018,8 +1523,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -1194,8 +1702,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -1421,8 +1932,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] @@ -1627,8 +2141,11 @@ "enum": [ "Bool", "U8", + "U16", + "U32", "U64", "U128", + "U256", "Address", "Signer" ] diff --git a/rpc/api/src/contract_api.rs b/rpc/api/src/contract_api.rs index c8f87337c8..a0f8ec2f31 100644 --- a/rpc/api/src/contract_api.rs +++ b/rpc/api/src/contract_api.rs @@ -42,7 +42,6 @@ pub trait ContractApi { raw_txn: String, sender_public_key: StrView, ) -> FutureResult; - #[rpc(name = "contract.resolve_function")] fn resolve_function(&self, function_id: FunctionIdView) -> FutureResult; #[rpc(name = "contract.resolve_module_function_index")] diff --git a/rpc/api/src/state/mod.rs b/rpc/api/src/state/mod.rs index 1a98c9ea80..0c4b9fc0be 100644 --- a/rpc/api/src/state/mod.rs +++ b/rpc/api/src/state/mod.rs @@ -4,7 +4,7 @@ pub use self::gen_client::Client as StateClient; use crate::types::{ AccountStateSetView, CodeView, ListCodeView, ListResourceView, ResourceView, - StateWithProofView, StrView, StructTagView, + StateWithProofView, StateWithTableItemProofView, StrView, StructTagView, }; use crate::FutureResult; use openrpc_derive::openrpc; @@ -16,6 +16,7 @@ use starcoin_types::language_storage::{ModuleId, StructTag}; use starcoin_types::{ access_path::AccessPath, account_address::AccountAddress, account_state::AccountState, }; +use starcoin_vm_types::state_store::table::TableHandle; #[openrpc] pub trait StateApi { #[rpc(name = "state.get")] @@ -62,6 +63,23 @@ pub trait StateApi { state_root: HashValue, ) -> FutureResult>>; + /// Return the TableItem value and provide a State Proof at `state_root` + #[rpc(name = "state.get_with_table_item_proof")] + fn get_with_table_item_proof( + &self, + handle: TableHandle, + key: Vec, + ) -> FutureResult; + + /// Return the TableItem value and provide a State Proof at `state_root` + #[rpc(name = "state.get_with_table_item_proof_by_root")] + fn get_with_table_item_proof_by_root( + &self, + handle: TableHandle, + key: Vec, + state_root: HashValue, + ) -> FutureResult; + /// get code of module #[rpc(name = "state.get_code")] fn get_code( diff --git a/rpc/api/src/types.rs b/rpc/api/src/types.rs index c4be2c08fd..6a04d0245e 100644 --- a/rpc/api/src/types.rs +++ b/rpc/api/src/types.rs @@ -20,7 +20,7 @@ use starcoin_accumulator::proof::AccumulatorProof; use starcoin_crypto::{CryptoMaterialError, HashValue, ValidCryptoMaterialStringExt}; use starcoin_resource_viewer::{AnnotatedMoveStruct, AnnotatedMoveValue}; use starcoin_service_registry::ServiceRequest; -use starcoin_state_api::{StateProof, StateWithProof}; +use starcoin_state_api::{StateProof, StateWithProof, StateWithTableItemProof}; use starcoin_types::block::{ Block, BlockBody, BlockHeader, BlockHeaderExtra, BlockInfo, BlockNumber, }; @@ -135,8 +135,12 @@ impl From for AnnotatedMoveStructView { #[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)] pub enum AnnotatedMoveValueView { U8(u8), + // XXX FIXME YSG + // U16(StrView), + // U32(Strview), U64(StrView), U128(StrView), + // U256(StrView), Bool(bool), Address(AccountAddress), Vector(Vec), @@ -148,8 +152,11 @@ impl From for AnnotatedMoveValueView { fn from(origin: AnnotatedMoveValue) -> Self { match origin { AnnotatedMoveValue::U8(u) => AnnotatedMoveValueView::U8(u), + // AnnotatedMoveValue::U16(u) => AnnotatedMoveValueView::U16(StrView(u)), + // AnnotatedMoveValue::U32(u) => AnnotatedMoveValueView::U32(StrView(u)), AnnotatedMoveValue::U64(u) => AnnotatedMoveValueView::U64(StrView(u)), AnnotatedMoveValue::U128(u) => AnnotatedMoveValueView::U128(StrView(u)), + // AnnotatedMoveValue::U256(u) => AnnotatedMoveValueView::U256(StrView(u)), AnnotatedMoveValue::Bool(b) => AnnotatedMoveValueView::Bool(b), AnnotatedMoveValue::Address(data) => AnnotatedMoveValueView::Address(data), AnnotatedMoveValue::Vector(data) => { @@ -157,6 +164,7 @@ impl From for AnnotatedMoveValueView { } AnnotatedMoveValue::Bytes(data) => AnnotatedMoveValueView::Bytes(StrView(data)), AnnotatedMoveValue::Struct(data) => AnnotatedMoveValueView::Struct(data.into()), + _ => todo!("XXX FIXME YSG"), } } } @@ -1164,6 +1172,8 @@ use starcoin_accumulator::accumulator_info::AccumulatorInfo; use starcoin_chain_api::{EventWithProof, TransactionInfoWithProof}; use starcoin_types::account_address::AccountAddress; use starcoin_vm_types::move_resource::MoveResource; +use starcoin_vm_types::state_store::state_key::{StateKey, TableItem}; +use starcoin_vm_types::state_store::table::TableHandle; pub use vm_status_translator::VmStatusExplainView; #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] @@ -1179,19 +1189,36 @@ pub struct TransactionOutputView { pub gas_used: StrView, pub write_set: Vec, pub events: Vec, + pub table_item_write_set: Vec, } impl From for TransactionOutputView { fn from(txn_output: TransactionOutput) -> Self { let (write_set, events, gas_used, status) = txn_output.into_inner(); + let mut access_write_set = vec![]; + let mut table_item_write_set = vec![]; + for (state_key, op) in write_set { + match state_key { + StateKey::AccessPath(access_path) => { + access_write_set.push((access_path, op)); + } + StateKey::TableItem(table_item) => { + table_item_write_set.push((table_item, op)); + } + } + } Self { events: events.into_iter().map(Into::into).collect(), gas_used: gas_used.into(), status: status.into(), - write_set: write_set + write_set: access_write_set .into_iter() .map(TransactionOutputAction::from) .collect(), + table_item_write_set: table_item_write_set + .into_iter() + .map(TransactionOutputTableItemAction::from) + .collect(), } } } @@ -1236,6 +1263,29 @@ pub enum WriteOpView { Value, } +impl From<(TableItem, WriteOp)> for TransactionOutputTableItemAction { + fn from((table_item, op): (TableItem, WriteOp)) -> Self { + let (action, value) = match op { + WriteOp::Deletion => (WriteOpView::Deletion, None), + WriteOp::Value(v) => (WriteOpView::Value, Some(StrView(v))), + }; + + TransactionOutputTableItemAction { + table_item: table_item.into(), + action, + value, + } + } +} + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct TransactionOutputTableItemAction { + pub table_item: TableItemView, + pub action: WriteOpView, + #[serde(skip_serializing_if = "Option::is_none")] + pub value: Option>>, +} + #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct ChainInfoView { pub chain_id: u8, @@ -1353,6 +1403,57 @@ impl From for StateWithProof { } } +#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize, JsonSchema)] +pub struct StateWithTableItemProofView { + pub state_proof: (StateWithProofView, HashValue), + pub table_handle_proof: (Option>>, SparseMerkleProofView, HashValue), + pub key_proof: (Option>>, SparseMerkleProofView, HashValue), +} + +impl StateWithTableItemProofView { + pub fn into_state_table_item_proof(self) -> StateWithTableItemProof { + self.into() + } +} + +impl From for StateWithTableItemProofView { + fn from(state_table_item_proof: StateWithTableItemProof) -> Self { + Self { + state_proof: ( + state_table_item_proof.state_proof.0.into(), + state_table_item_proof.state_proof.1, + ), + table_handle_proof: ( + state_table_item_proof.table_handle_proof.0.map(StrView), + state_table_item_proof.table_handle_proof.1.into(), + state_table_item_proof.table_handle_proof.2, + ), + key_proof: ( + state_table_item_proof.key_proof.0.map(StrView), + state_table_item_proof.key_proof.1.into(), + state_table_item_proof.key_proof.2, + ), + } + } +} + +impl From for StateWithTableItemProof { + fn from(view: StateWithTableItemProofView) -> Self { + let state_proof = (StateWithProof::from(view.state_proof.0), view.state_proof.1); + let table_handle_proof = ( + view.table_handle_proof.0.map(|v| v.0), + SparseMerkleProof::from(view.table_handle_proof.1), + view.table_handle_proof.2, + ); + let key_proof = ( + view.key_proof.0.map(|v| v.0), + SparseMerkleProof::from(view.key_proof.1), + view.key_proof.2, + ); + StateWithTableItemProof::new(state_proof, table_handle_proof, key_proof) + } +} + #[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize, JsonSchema)] pub struct AccumulatorProofView { pub siblings: Vec, @@ -1561,7 +1662,7 @@ impl FromStr for StructTagView { fn from_str(s: &str) -> Result { let type_tag = parse_type_tag(s)?; match type_tag { - TypeTag::Struct(s) => Ok(Self(s)), + TypeTag::Struct(s) => Ok(Self(*s)), t => anyhow::bail!("expect struct tag, actual: {}", t), } } @@ -1791,6 +1892,43 @@ impl From for BlockInfoView { } } +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] +#[serde(rename = "table_item")] +pub struct TableItemView { + handle: TableHandle, + #[schemars(with = "String")] + key: Vec, +} + +impl From for TableItemView { + fn from(table_item: TableItem) -> Self { + Self { + handle: table_item.handle, + key: table_item.key, + } + } +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] +pub enum StateKeyView { + #[serde(rename = "access_path")] + AccessPath(AccessPath), + #[serde(rename = "table_item")] + TableItem(TableItemView), +} + +impl From for StateKeyView { + fn from(state_key: StateKey) -> Self { + match state_key { + StateKey::AccessPath(access_path) => Self::AccessPath(access_path), + StateKey::TableItem(table_item) => Self::TableItem(TableItemView { + handle: table_item.handle, + key: table_item.key, + }), + } + } +} + #[cfg(test)] mod tests { use crate::types::{ByteCodeOrScriptFunction, FunctionId}; diff --git a/rpc/client/Cargo.toml b/rpc/client/Cargo.toml index 541be69954..9a747aceee 100644 --- a/rpc/client/Cargo.toml +++ b/rpc/client/Cargo.toml @@ -7,9 +7,19 @@ bcs-ext = { package = "bcs-ext", workspace = true } futures = { workspace = true } futures-timer = { workspace = true } hex = { workspace = true } -jsonrpc-client-transports = { features = [ "http", "ipc", "ws", "arbitrary_precision",], workspace = true } -jsonrpc-core = { features = [ "arbitrary_precision",], workspace = true } -jsonrpc-core-client = { features = [ "http", "ipc", "ws", "arbitrary_precision",], workspace = true } +jsonrpc-client-transports = { features = [ + "http", + "ipc", + "ws", + "arbitrary_precision", +], workspace = true } +jsonrpc-core = { features = ["arbitrary_precision"], workspace = true } +jsonrpc-core-client = { features = [ + "http", + "ipc", + "ws", + "arbitrary_precision", +], workspace = true } jsonrpc-derive = { workspace = true } jsonrpc-pubsub = { workspace = true } jsonrpc-server-utils = { workspace = true } @@ -19,8 +29,8 @@ network-p2p-types = { workspace = true } network-types = { workspace = true } parity-tokio-ipc = { workspace = true } parking_lot = { workspace = true } -serde = { features = [ "derive",], workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde = { features = ["derive"], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-abi-types = { workspace = true } starcoin-account-api = { workspace = true } starcoin-crypto = { workspace = true } diff --git a/rpc/client/src/lib.rs b/rpc/client/src/lib.rs index 4bb285fdf1..34b7da4156 100644 --- a/rpc/client/src/lib.rs +++ b/rpc/client/src/lib.rs @@ -35,8 +35,8 @@ use starcoin_rpc_api::types::{ ChainId, ChainInfoView, CodeView, ContractCall, DecodedMoveValue, DryRunOutputView, DryRunTransactionRequest, FactoryAction, FunctionIdView, ListCodeView, ListResourceView, MintedBlockView, ModuleIdView, PeerInfoView, ResourceView, SignedMessageView, - SignedUserTransactionView, StateWithProofView, StrView, StructTagView, - TransactionEventResponse, TransactionInfoView, TransactionInfoWithProofView, + SignedUserTransactionView, StateWithProofView, StateWithTableItemProofView, StrView, + StructTagView, TransactionEventResponse, TransactionInfoView, TransactionInfoWithProofView, TransactionRequest, TransactionView, }; use starcoin_rpc_api::{ @@ -57,6 +57,7 @@ use starcoin_types::sync_status::SyncStatus; use starcoin_types::system_events::MintBlockEvent; use starcoin_types::transaction::{RawUserTransaction, SignedUserTransaction}; use starcoin_vm_types::language_storage::{ModuleId, StructTag}; +use starcoin_vm_types::state_store::table::TableHandle; use starcoin_vm_types::token::token_code::TokenCode; use starcoin_vm_types::transaction::DryRunTransaction; use std::collections::HashMap; @@ -640,6 +641,20 @@ impl RpcClient { .map_err(map_err) } + pub fn state_get_with_table_item_proof_by_root( + &self, + handle: TableHandle, + key: Vec, + state_root: HashValue, + ) -> anyhow::Result { + self.call_rpc_blocking(|inner| { + inner + .state_client + .get_with_table_item_proof_by_root(handle, key, state_root) + }) + .map_err(map_err) + } + pub fn get_state_node_by_node_hash( &self, key_hash: HashValue, diff --git a/rpc/client/src/remote_state_reader.rs b/rpc/client/src/remote_state_reader.rs index b6a422e77f..8680f6f7d1 100644 --- a/rpc/client/src/remote_state_reader.rs +++ b/rpc/client/src/remote_state_reader.rs @@ -4,13 +4,15 @@ use crate::RpcClient; use anyhow::{format_err, Result}; use starcoin_crypto::HashValue; -use starcoin_state_api::{ChainStateReader, StateView, StateWithProof}; +use starcoin_state_api::{ChainStateReader, StateView, StateWithProof, StateWithTableItemProof}; use starcoin_state_tree::AccountStateSetIterator; use starcoin_types::access_path::AccessPath; use starcoin_types::account_address::AccountAddress; use starcoin_types::account_state::AccountState; use starcoin_types::block::BlockNumber; use starcoin_types::state_set::{AccountStateSet, ChainStateSet}; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::state_store::table::TableHandle; use std::str::FromStr; #[derive(Debug, Clone, Copy)] @@ -82,14 +84,14 @@ impl<'a> ChainStateReader for RemoteStateReader<'a> { //TODO implement get_account_state by root } + fn get_account_state_set(&self, _address: &AccountAddress) -> Result> { + unimplemented!() + } + fn state_root(&self) -> HashValue { //TODO change trait api to return Result self.state_root } - - fn get_account_state_set(&self, _address: &AccountAddress) -> Result> { - unimplemented!() - } fn dump(&self) -> Result { unimplemented!() } @@ -97,15 +99,37 @@ impl<'a> ChainStateReader for RemoteStateReader<'a> { fn dump_iter(&self) -> Result { unimplemented!() } + + fn get_with_table_item_proof( + &self, + handle: &TableHandle, + key: &[u8], + ) -> Result { + self.client + .state_get_with_table_item_proof_by_root(*handle, key.to_vec(), self.state_root) + .map(Into::into) + } } impl<'a> StateView for RemoteStateReader<'a> { - fn get(&self, access_path: &AccessPath) -> Result>> { - Ok(self - .client - .state_get_with_proof_by_root(access_path.clone(), self.state_root())? - .state - .map(|v| v.0)) + fn get_state_value(&self, state_key: &StateKey) -> Result>> { + match state_key { + StateKey::AccessPath(access_path) => Ok(self + .client + .state_get_with_proof_by_root(access_path.clone(), self.state_root())? + .state + .map(|v| v.0)), + StateKey::TableItem(table_item) => Ok(self + .client + .state_get_with_table_item_proof_by_root( + table_item.handle, + table_item.key.clone(), + self.state_root(), + )? + .key_proof + .0 + .map(|v| v.0)), + } } fn is_genesis(&self) -> bool { diff --git a/rpc/middleware/Cargo.toml b/rpc/middleware/Cargo.toml index 5fe600eb8b..29887ba51d 100644 --- a/rpc/middleware/Cargo.toml +++ b/rpc/middleware/Cargo.toml @@ -1,9 +1,9 @@ [dependencies] anyhow = { workspace = true } futures = { workspace = true } -jsonrpc-core = { features = [ "arbitrary_precision",], workspace = true } +jsonrpc-core = { features = ["arbitrary_precision"], workspace = true } once_cell = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-config = { workspace = true } starcoin-logger = { workspace = true } starcoin-metrics = { workspace = true } diff --git a/rpc/server/Cargo.toml b/rpc/server/Cargo.toml index fe24e0d572..949d1ea6e1 100644 --- a/rpc/server/Cargo.toml +++ b/rpc/server/Cargo.toml @@ -8,10 +8,15 @@ bcs-ext = { package = "bcs-ext", workspace = true } dashmap = { workspace = true } futures = { workspace = true } futures-channel = { workspace = true } -governor = { features = [ "dashmap",], workspace = true } +governor = { features = ["dashmap"], workspace = true } hex = { default-features = false, workspace = true } -jsonrpc-core = { features = [ "arbitrary_precision",], workspace = true } -jsonrpc-core-client = { features = [ "http", "ipc", "ws", "arbitrary_precision",], workspace = true } +jsonrpc-core = { features = ["arbitrary_precision"], workspace = true } +jsonrpc-core-client = { features = [ + "http", + "ipc", + "ws", + "arbitrary_precision", +], workspace = true } jsonrpc-derive = { workspace = true } jsonrpc-http-server = { workspace = true } jsonrpc-ipc-server = { workspace = true } @@ -25,8 +30,8 @@ network-p2p-types = { workspace = true } network-rpc-core = { workspace = true } network-types = { workspace = true } parking_lot = { workspace = true } -serde = { features = [ "derive",], workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde = { features = ["derive"], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-abi-decoder = { workspace = true } starcoin-abi-resolver = { workspace = true } starcoin-abi-types = { workspace = true } @@ -71,7 +76,7 @@ starcoin-transaction-builder = { workspace = true } starcoin-txpool-mock-service = { workspace = true } stest = { workspace = true } test-helper = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [package] authors = { workspace = true } diff --git a/rpc/server/src/module/state_rpc.rs b/rpc/server/src/module/state_rpc.rs index efdef39e38..e7f1acc62f 100644 --- a/rpc/server/src/module/state_rpc.rs +++ b/rpc/server/src/module/state_rpc.rs @@ -14,7 +14,7 @@ use starcoin_rpc_api::state::{ }; use starcoin_rpc_api::types::{ AccountStateSetView, AnnotatedMoveStructView, CodeView, ListCodeView, ListResourceView, - ResourceView, StateWithProofView, StrView, StructTagView, + ResourceView, StateWithProofView, StateWithTableItemProofView, StrView, StructTagView, }; use starcoin_rpc_api::FutureResult; use starcoin_state_api::{ChainStateAsyncService, StateView}; @@ -26,6 +26,8 @@ use starcoin_types::{ }; use starcoin_vm_types::identifier::Identifier; use starcoin_vm_types::language_storage::{struct_tag_match, StructTag}; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::state_store::table::TableHandle; use std::collections::BTreeMap; use std::sync::Arc; @@ -183,6 +185,35 @@ where Box::pin(fut) } + fn get_with_table_item_proof( + &self, + handle: TableHandle, + key: Vec, + ) -> FutureResult { + let fut = self + .service + .clone() + .get_with_table_item_proof(handle, key) + .map_ok(|p| p.into()) + .map_err(map_err); + Box::pin(fut) + } + + fn get_with_table_item_proof_by_root( + &self, + handle: TableHandle, + key: Vec, + state_root: HashValue, + ) -> FutureResult { + let fut = self + .service + .clone() + .get_with_table_item_proof_by_root(handle, key, state_root) + .map_ok(|p| p.into()) + .map_err(map_err); + Box::pin(fut) + } + fn get_code( &self, module_id: StrView, @@ -196,7 +227,8 @@ where .state_root .unwrap_or(service.clone().state_root().await?); let chain_state = ChainStateDB::new(state_store, Some(state_root)); - let code = chain_state.get(&AccessPath::from(&module_id.0))?; + let code = chain_state + .get_state_value(&StateKey::AccessPath(AccessPath::from(&module_id.0)))?; Ok(match code { None => None, Some(c) => { @@ -230,9 +262,8 @@ where .state_root .unwrap_or(service.clone().state_root().await?); let chain_state = ChainStateDB::new(state_store, Some(state_root)); - let data = chain_state.get(&AccessPath::resource_access_path( - addr, - resource_type.0.clone(), + let data = chain_state.get_state_value(&StateKey::AccessPath( + AccessPath::resource_access_path(addr, resource_type.0.clone()), ))?; Ok(match data { None => None, diff --git a/state/api/Cargo.toml b/state/api/Cargo.toml index 48d27f1398..5d6342c6af 100644 --- a/state/api/Cargo.toml +++ b/state/api/Cargo.toml @@ -2,13 +2,14 @@ anyhow = { workspace = true } async-trait = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } starcoin-crypto = { workspace = true } starcoin-service-registry = { workspace = true } starcoin-state-tree = { workspace = true } starcoin-types = { workspace = true } starcoin-vm-types = { workspace = true } forkable-jellyfish-merkle = { workspace = true } +once_cell = { workspace = true } [dev-dependencies] diff --git a/state/api/src/chain_state.rs b/state/api/src/chain_state.rs index 729866c0d7..3aadb689b5 100644 --- a/state/api/src/chain_state.rs +++ b/state/api/src/chain_state.rs @@ -1,7 +1,8 @@ // Copyright (c) The Starcoin Core Contributors // SPDX-License-Identifier: Apache-2.0 -use anyhow::{ensure, Result}; +use crate::TABLE_PATH; +use anyhow::{ensure, format_err, Result}; use forkable_jellyfish_merkle::{blob::Blob, proof::SparseMerkleProof, RawKey}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; @@ -14,8 +15,18 @@ use starcoin_types::{ access_path::AccessPath, account_address::AccountAddress, account_config::AccountResource, account_state::AccountState, state_set::ChainStateSet, }; +use starcoin_vm_types::account_config::{ + genesis_address, table_handle_address, BalanceResource, TokenInfo, G_STC_TOKEN_CODE, +}; use starcoin_vm_types::genesis_config::ChainId; -use starcoin_vm_types::on_chain_resource::{Epoch, EpochInfo, GlobalTimeOnChain}; +use starcoin_vm_types::language_storage::ModuleId; +use starcoin_vm_types::on_chain_resource::dao::{Proposal, ProposalAction}; +use starcoin_vm_types::on_chain_resource::{ + Epoch, EpochData, EpochInfo, GlobalTimeOnChain, Treasury, +}; +use starcoin_vm_types::sips::SIP; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::state_store::table::TableHandle; use starcoin_vm_types::token::token_code::TokenCode; use starcoin_vm_types::{ move_resource::MoveResource, on_chain_config::OnChainConfig, state_view::StateView, @@ -125,6 +136,12 @@ pub trait ChainStateReader: StateView { fn dump(&self) -> Result; fn dump_iter(&self) -> Result; + + fn get_with_table_item_proof( + &self, + handle: &TableHandle, + key: &[u8], + ) -> Result; } pub trait ChainStateWriter { @@ -144,7 +161,152 @@ pub trait ChainStateWriter { fn flush(&self) -> Result<()>; } -pub use starcoin_vm_types::state_view::StateReaderExt; +impl StateReaderExt for T where T: StateView {} + +pub trait StateReaderExt: StateView { + /// Get AccountResource by address + fn get_account_resource(&self, address: AccountAddress) -> Result> { + self.get_resource::(address) + } + + /// Get Resource by type R + fn get_resource(&self, address: AccountAddress) -> Result> + where + R: MoveResource + DeserializeOwned, + { + let access_path = AccessPath::new(address, R::resource_path()); + self.get_resource_by_access_path(access_path) + } + + fn get_resource_by_access_path(&self, access_path: AccessPath) -> Result> + where + R: MoveResource + DeserializeOwned, + { + let r = self + .get_state_value(&StateKey::AccessPath(access_path)) + .and_then(|state| match state { + Some(state) => Ok(Some(bcs_ext::from_bytes::(state.as_slice())?)), + None => Ok(None), + })?; + Ok(r) + } + + fn get_sequence_number(&self, address: AccountAddress) -> Result { + self.get_account_resource(address)? + .map(|resource| resource.sequence_number()) + .ok_or_else(|| format_err!("Can not find account by address:{}", address)) + } + + fn get_on_chain_config(&self) -> Result> + where + C: OnChainConfig, + Self: Sized, + { + C::fetch_config(self) + } + + fn get_balance(&self, address: AccountAddress) -> Result> { + self.get_balance_by_token_code(address, G_STC_TOKEN_CODE.clone()) + } + + /// Get balance by address and coin type + fn get_balance_by_type( + &self, + address: AccountAddress, + type_tag: StructTag, + ) -> Result> { + Ok(self + .get_state_value(&StateKey::AccessPath(AccessPath::new( + address, + BalanceResource::access_path_for(type_tag), + ))) + .and_then(|bytes| match bytes { + Some(bytes) => Ok(Some(bcs_ext::from_bytes::( + bytes.as_slice(), + )?)), + None => Ok(None), + })? + .map(|resource| resource.token())) + } + + fn get_balance_by_token_code( + &self, + address: AccountAddress, + token_code: TokenCode, + ) -> Result> { + self.get_balance_by_type(address, token_code.try_into()?) + } + + fn get_epoch(&self) -> Result { + self.get_resource::(genesis_address())? + .ok_or_else(|| format_err!("Epoch is none.")) + } + + fn get_epoch_info(&self) -> Result { + let epoch = self + .get_resource::(genesis_address())? + .ok_or_else(|| format_err!("Epoch is none."))?; + + let epoch_data = self + .get_resource::(genesis_address())? + .ok_or_else(|| format_err!("Epoch is none."))?; + + Ok(EpochInfo::new(epoch, epoch_data)) + } + + fn get_timestamp(&self) -> Result { + self.get_resource(genesis_address())? + .ok_or_else(|| format_err!("Timestamp resource should exist.")) + } + + fn get_chain_id(&self) -> Result { + self.get_resource::(genesis_address())? + .ok_or_else(|| format_err!("ChainId resource should exist at genesis address. ")) + } + + fn get_code(&self, module_id: ModuleId) -> Result>> { + self.get_state_value(&StateKey::AccessPath(AccessPath::from(&module_id))) + } + + /// Check the sip is activated. if the sip module exist, think it is activated. + fn is_activated(&self, sip: SIP) -> Result { + self.get_code(sip.module_id()).map(|code| code.is_some()) + } + + fn get_token_info(&self, token_code: TokenCode) -> Result> { + let type_tag = token_code.try_into()?; + let access_path = TokenInfo::resource_path_for(type_tag); + self.get_resource_by_access_path(access_path) + } + + fn get_stc_info(&self) -> Result> { + self.get_token_info(G_STC_TOKEN_CODE.clone()) + } + + fn get_treasury(&self, token_code: TokenCode) -> Result> { + let access_path = Treasury::resource_path_for(token_code.try_into()?); + self.get_resource_by_access_path(access_path) + } + + fn get_stc_treasury(&self) -> Result> { + self.get_treasury(G_STC_TOKEN_CODE.clone()) + } + + fn get_proposal(&self, token_code: TokenCode) -> Result>> + where + A: ProposalAction + DeserializeOwned, + { + let access_path = Proposal::::resource_path_for(token_code.try_into()?); + self.get_resource_by_access_path(access_path) + } + + fn get_stc_proposal(&self) -> Result>> + where + A: ProposalAction + DeserializeOwned, + { + self.get_proposal(G_STC_TOKEN_CODE.clone()) + } +} /// `AccountStateReader` is a helper struct for read account state. pub struct AccountStateReader<'a, Reader> { @@ -224,3 +386,51 @@ where self.reader.get_chain_id() } } + +#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)] +pub struct StateWithTableItemProof { + pub state_proof: (StateWithProof, HashValue), + pub table_handle_proof: (Option>, SparseMerkleProof, HashValue), + pub key_proof: (Option>, SparseMerkleProof, HashValue), +} + +impl StateWithTableItemProof { + pub fn new( + state_proof: (StateWithProof, HashValue), + table_handle_proof: (Option>, SparseMerkleProof, HashValue), + key_proof: (Option>, SparseMerkleProof, HashValue), + ) -> Self { + Self { + state_proof, + table_handle_proof, + key_proof, + } + } + + pub fn verify(&self, handle: &TableHandle, key: &[u8]) -> Result<()> { + self.state_proof.0.proof.verify( + self.state_proof.1, + AccessPath::new(table_handle_address(), TABLE_PATH.clone()), + self.state_proof.0.state.as_deref(), + )?; + self.table_handle_proof.1.verify( + self.table_handle_proof.2, + handle.key_hash(), + self.table_handle_proof + .0 + .as_ref() + .map(|v| Blob::from(v.clone())) + .as_ref(), + )?; + self.key_proof.1.verify( + self.key_proof.2, + key.to_vec().key_hash(), + self.key_proof + .0 + .as_ref() + .map(|v| Blob::from(v.clone())) + .as_ref(), + )?; + Ok(()) + } +} diff --git a/state/api/src/lib.rs b/state/api/src/lib.rs index b84b08c1d0..2c3bf91661 100644 --- a/state/api/src/lib.rs +++ b/state/api/src/lib.rs @@ -3,26 +3,40 @@ use crate::message::{StateRequest, StateResponse}; use anyhow::Result; +use once_cell::sync::Lazy; use starcoin_crypto::HashValue; use starcoin_service_registry::{ActorService, ServiceHandler, ServiceRef}; use starcoin_types::{ access_path::AccessPath, account_address::AccountAddress, account_state::AccountState, }; +use std::str::FromStr; pub use chain_state::{ AccountStateReader, ChainStateReader, ChainStateWriter, StateProof, StateReaderExt, - StateWithProof, + StateWithProof, StateWithTableItemProof, }; use serde::de::DeserializeOwned; pub use starcoin_state_tree::StateNodeStore; use starcoin_types::state_set::AccountStateSet; +use starcoin_vm_types::access_path::DataPath; +use starcoin_vm_types::account_config::table_handle_address; use starcoin_vm_types::move_resource::MoveResource; +use starcoin_vm_types::state_store::table::TableHandle; pub use starcoin_vm_types::state_view::StateView; mod chain_state; pub mod message; pub mod mock; +pub static TABLE_PATH: Lazy = Lazy::new(|| { + let str = format!( + "{}/1/{}::TableHandles::TableHandles", + table_handle_address(), + table_handle_address() + ); + AccessPath::from_str(str.as_str()).unwrap().path +}); + #[async_trait::async_trait] pub trait ChainStateAsyncService: Clone + std::marker::Unpin + Send + Sync { async fn get(self, access_path: AccessPath) -> Result>>; @@ -63,6 +77,18 @@ pub trait ChainStateAsyncService: Clone + std::marker::Unpin + Send + Sync { address: AccountAddress, state_root: HashValue, ) -> Result>; + + async fn get_with_table_item_proof( + self, + handle: TableHandle, + key: Vec, + ) -> Result; + async fn get_with_table_item_proof_by_root( + self, + handle: TableHandle, + key: Vec, + state_root: HashValue, + ) -> Result; } #[async_trait::async_trait] @@ -154,4 +180,37 @@ where panic!("Unexpect response type.") } } + + async fn get_with_table_item_proof( + self, + handle: TableHandle, + key: Vec, + ) -> Result { + let response = self + .send(StateRequest::GetWithTableItemProof(handle, key)) + .await??; + if let StateResponse::StateWithTableItemProof(state) = response { + Ok(*state) + } else { + panic!("Unexpect response type.") + } + } + + async fn get_with_table_item_proof_by_root( + self, + handle: TableHandle, + key: Vec, + state_root: HashValue, + ) -> Result { + let response = self + .send(StateRequest::GetWithTableItemProofByRoot( + handle, key, state_root, + )) + .await??; + if let StateResponse::StateWithTableItemProof(state) = response { + Ok(*state) + } else { + panic!("Unexpect response type.") + } + } } diff --git a/state/api/src/message.rs b/state/api/src/message.rs index 0bddab22cc..dd6ccf5f0d 100644 --- a/state/api/src/message.rs +++ b/state/api/src/message.rs @@ -1,7 +1,7 @@ // Copyright (c) The Starcoin Core Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::StateWithProof; +use crate::{StateWithProof, StateWithTableItemProof}; use anyhow::Result; use starcoin_crypto::HashValue; use starcoin_service_registry::ServiceRequest; @@ -9,6 +9,7 @@ use starcoin_types::state_set::AccountStateSet; use starcoin_types::{ access_path::AccessPath, account_address::AccountAddress, account_state::AccountState, }; +use starcoin_vm_types::state_store::table::TableHandle; #[derive(Debug, Clone)] pub enum StateRequest { @@ -22,6 +23,8 @@ pub enum StateRequest { }, GetAccountStateByRoot(AccountAddress, HashValue), StateRoot(), + GetWithTableItemProof(TableHandle, Vec), + GetWithTableItemProofByRoot(TableHandle, Vec, HashValue), } impl ServiceRequest for StateRequest { @@ -36,4 +39,5 @@ pub enum StateResponse { AccountState(Option), AccountStateSet(Option), None, + StateWithTableItemProof(Box), } diff --git a/state/api/src/mock/mock_chain_state_service.rs b/state/api/src/mock/mock_chain_state_service.rs index 3fe39807eb..b70fa51d36 100644 --- a/state/api/src/mock/mock_chain_state_service.rs +++ b/state/api/src/mock/mock_chain_state_service.rs @@ -1,13 +1,14 @@ // Copyright (c) The Starcoin Core Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{ChainStateAsyncService, StateWithProof}; +use crate::{ChainStateAsyncService, StateWithProof, StateWithTableItemProof}; use anyhow::Result; use starcoin_crypto::HashValue; use starcoin_types::access_path::AccessPath; use starcoin_types::account_address::AccountAddress; use starcoin_types::account_state::AccountState; use starcoin_types::state_set::AccountStateSet; +use starcoin_vm_types::state_store::table::TableHandle; //TODO implement Mock service #[derive(Clone, Default)] @@ -60,4 +61,21 @@ impl ChainStateAsyncService for MockChainStateService { ) -> Result> { unimplemented!() } + + async fn get_with_table_item_proof( + self, + _handle: TableHandle, + _key: Vec, + ) -> Result { + unimplemented!() + } + + async fn get_with_table_item_proof_by_root( + self, + _handle: TableHandle, + _key: Vec, + _state_root: HashValue, + ) -> Result { + unimplemented!() + } } diff --git a/state/service/Cargo.toml b/state/service/Cargo.toml index bad05446eb..54758e3d93 100644 --- a/state/service/Cargo.toml +++ b/state/service/Cargo.toml @@ -13,6 +13,7 @@ starcoin-storage = { workspace = true } starcoin-types = { workspace = true } stest = { workspace = true } tokio = { workspace = true } +starcoin-vm-types = { workspace = true } [dev-dependencies] test-helper = { workspace = true } diff --git a/state/service/src/service.rs b/state/service/src/service.rs index bf484afd0c..f9f883b88b 100644 --- a/state/service/src/service.rs +++ b/state/service/src/service.rs @@ -11,6 +11,7 @@ use starcoin_service_registry::{ use starcoin_state_api::message::{StateRequest, StateResponse}; use starcoin_state_api::{ ChainStateReader, StateNodeStore, StateReaderExt, StateView, StateWithProof, + StateWithTableItemProof, }; use starcoin_state_tree::AccountStateSetIterator; use starcoin_statedb::ChainStateDB; @@ -21,6 +22,8 @@ use starcoin_types::{ access_path::AccessPath, account_address::AccountAddress, account_state::AccountState, state_set::ChainStateSet, }; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::state_store::table::TableHandle; use std::sync::Arc; pub struct ChainStateService { @@ -77,7 +80,10 @@ impl ServiceHandler for ChainStateService { _ctx: &mut ServiceContext, ) -> Result { let response = match msg { - StateRequest::Get(access_path) => StateResponse::State(self.service.get(&access_path)?), + StateRequest::Get(access_path) => StateResponse::State( + self.service + .get_state_value(&StateKey::AccessPath(access_path))?, + ), StateRequest::GetWithProof(access_path) => { StateResponse::StateWithProof(Box::new(self.service.get_with_proof(&access_path)?)) } @@ -104,6 +110,17 @@ impl ServiceHandler for ChainStateService { self.service .get_account_state_set_with_root(address, state_root)?, ), + StateRequest::GetWithTableItemProof(handle, key) => { + StateResponse::StateWithTableItemProof(Box::new( + self.service.get_with_table_item_proof(&handle, &key)?, + )) + } + StateRequest::GetWithTableItemProofByRoot(handle, key, state_root) => { + StateResponse::StateWithTableItemProof(Box::new( + self.service + .get_with_table_item_proof_by_root(handle, key, state_root)?, + )) + } }; Ok(response) } @@ -160,6 +177,16 @@ impl Inner { reader.get_with_proof(&access_path) } + pub(crate) fn get_with_table_item_proof_by_root( + &self, + handle: TableHandle, + key: Vec, + state_root: HashValue, + ) -> Result { + let reader = self.state_db.fork_at(state_root); + reader.get_with_table_item_proof(&handle, &key) + } + pub(crate) fn get_account_state_by_root( &self, account: AccountAddress, @@ -209,11 +236,19 @@ impl ChainStateReader for Inner { fn dump_iter(&self) -> Result { unimplemented!() } + + fn get_with_table_item_proof( + &self, + handle: &TableHandle, + key: &[u8], + ) -> Result { + self.state_db.get_with_table_item_proof(handle, key) + } } impl StateView for Inner { - fn get(&self, access_path: &AccessPath) -> Result>> { - self.state_db.get(access_path) + fn get_state_value(&self, state_key: &StateKey) -> Result>> { + self.state_db.get_state_value(state_key) } fn is_genesis(&self) -> bool { diff --git a/state/statedb/src/lib.rs b/state/statedb/src/lib.rs index a7ffefcd23..f177627306 100644 --- a/state/statedb/src/lib.rs +++ b/state/statedb/src/lib.rs @@ -8,9 +8,11 @@ use forkable_jellyfish_merkle::proof::SparseMerkleProof; use forkable_jellyfish_merkle::RawKey; use lru::LruCache; use parking_lot::{Mutex, RwLock}; +use starcoin_crypto::hash::SPARSE_MERKLE_PLACEHOLDER_HASH; use starcoin_crypto::HashValue; use starcoin_logger::prelude::*; pub use starcoin_state_api::{ChainStateReader, ChainStateWriter, StateProof, StateWithProof}; +use starcoin_state_api::{StateWithTableItemProof, TABLE_PATH}; use starcoin_state_tree::mock::MockStateNodeStore; use starcoin_state_tree::AccountStateSetIterator; use starcoin_state_tree::{StateNodeStore, StateTree}; @@ -22,7 +24,9 @@ use starcoin_types::{ state_set::{AccountStateSet, ChainStateSet}, }; use starcoin_vm_types::access_path::{DataPath, ModuleName}; +use starcoin_vm_types::account_config::table_handle_address; use starcoin_vm_types::language_storage::StructTag; +use starcoin_vm_types::state_store::{state_key::StateKey, table::TableHandle}; use starcoin_vm_types::state_view::StateView; use std::collections::HashSet; use std::convert::TryInto; @@ -211,6 +215,11 @@ pub struct ChainStateDB { state_tree: StateTree, cache: Mutex>, updates: RwLock>, + updates_table_handle: RwLock>, + cache_table_handle: Mutex>>, + /// state_tree_table_handles root_hash save in table_handle_address() TABLE_PATH + /// state_tree_table_handles SMT save TableHandle -> TableHandleState.root_hash + state_tree_table_handles: StateTree, } static G_DEFAULT_CACHE_SIZE: usize = 10240; @@ -221,12 +230,26 @@ impl ChainStateDB { } pub fn new(store: Arc, root_hash: Option) -> Self { - Self { + let mut chain_statedb = ChainStateDB { store: store.clone(), - state_tree: StateTree::new(store, root_hash), + state_tree: StateTree::new(store.clone(), root_hash), cache: Mutex::new(LruCache::new(G_DEFAULT_CACHE_SIZE)), updates: RwLock::new(HashSet::new()), + updates_table_handle: RwLock::new(HashSet::new()), + cache_table_handle: Mutex::new(LruCache::new(G_DEFAULT_CACHE_SIZE)), + state_tree_table_handles: StateTree::new(store.clone(), None), + }; + let account_state_object = chain_statedb + .get_account_state_object(&table_handle_address(), true) + .expect("get account state success"); + let state_root = account_state_object + .get(&*TABLE_PATH) + .expect("get state_root success"); + if let Some(state_root) = state_root { + let hash = HashValue::from_slice(state_root.as_slice()).expect("hash value success"); + chain_statedb.state_tree_table_handles = StateTree::new(store, Some(hash)); } + chain_statedb } /// Fork a new statedb base current statedb @@ -236,12 +259,7 @@ impl ChainStateDB { /// Fork a new statedb at `root_hash` pub fn fork_at(&self, state_root: HashValue) -> Self { - Self { - store: self.store.clone(), - state_tree: StateTree::new(self.store.clone(), Some(state_root)), - cache: Mutex::new(LruCache::new(G_DEFAULT_CACHE_SIZE)), - updates: RwLock::new(HashSet::new()), - } + Self::new(self.store.clone(), Some(state_root)) } fn new_state_tree(&self, root_hash: HashValue) -> StateTree { @@ -306,17 +324,68 @@ impl ChainStateDB { None => Ok(None), }) } + + fn get_table_handle_state_object( + &self, + handle: &TableHandle, + ) -> Result> { + let mut cache = self.cache_table_handle.lock(); + let item = cache.get(handle); + let object = match item { + Some(item) => item.clone(), + None => { + let val = self.state_tree_table_handles.get(handle)?; + let hash = match val { + Some(val) => HashValue::from_slice(val)?, + None => *SPARSE_MERKLE_PLACEHOLDER_HASH, + }; + let obj = Arc::new(TableHandleStateObject::new( + *handle, + self.store.clone(), + hash, + )); + cache.put(*handle, obj.clone()); + obj + } + }; + Ok(object) + } + + #[cfg(test)] + fn table_handles_root_hash(&self) -> HashValue { + self.state_tree_table_handles.root_hash() + } + + #[cfg(test)] + fn table_handle_address_root_hash(&self) -> HashValue { + let account_state_object = self + .get_account_state_object(&table_handle_address(), true) + .expect("get account state success"); + let state_root = account_state_object + .get(&*TABLE_PATH) + .expect("get state_root success"); + HashValue::from_slice(state_root.unwrap()).unwrap() + } } impl StateView for ChainStateDB { - fn get(&self, access_path: &AccessPath) -> Result>> { - let account_address = &access_path.address; - let data_path = &access_path.path; - self.get_account_state_object_option(account_address) - .and_then(|account_state| match account_state { - Some(account_state) => account_state.get(data_path), - None => Ok(None), - }) + fn get_state_value(&self, state_key: &StateKey) -> Result>> { + match state_key { + StateKey::AccessPath(access_path) => { + let account_address = &access_path.address; + let data_path = &access_path.path; + self.get_account_state_object_option(account_address) + .and_then(|account_state| match account_state { + Some(account_state) => account_state.get(data_path), + None => Ok(None), + }) + } + StateKey::TableItem(table_item) => { + let table_handle_state_object = + self.get_table_handle_state_object(&table_item.handle)?; + table_handle_state_object.get(&table_item.key) + } + } } fn is_genesis(&self) -> bool { @@ -425,22 +494,53 @@ impl ChainStateReader for ChainStateDB { let iter = AccountStateSetIterator::new(self.store.clone(), jmt_into_iter); Ok(iter) } + + fn get_with_table_item_proof( + &self, + handle: &TableHandle, + key: &[u8], + ) -> Result { + let table_path_proof = + self.get_with_proof(&AccessPath::new(table_handle_address(), TABLE_PATH.clone()))?; + let table_handle_proof = self.state_tree_table_handles.get_with_proof(handle)?; + let table_handle_state_object = self.get_table_handle_state_object(handle)?; + let key_proof = table_handle_state_object.get_with_proof(&key.to_vec())?; + Ok(StateWithTableItemProof::new( + (table_path_proof, self.state_root()), + ( + table_handle_proof.0, + table_handle_proof.1, + self.state_tree_table_handles.root_hash(), + ), + ( + key_proof.0, + key_proof.1, + table_handle_state_object.root_hash(), + ), + )) + } } impl ChainStateWriter for ChainStateDB { fn set(&self, access_path: &AccessPath, value: Vec) -> Result<()> { self.apply_write_set( - WriteSetMut::new(vec![(access_path.clone(), WriteOp::Value(value))]) - .freeze() - .expect("freeze write_set must success."), + WriteSetMut::new(vec![( + StateKey::AccessPath(access_path.clone()), + WriteOp::Value(value), + )]) + .freeze() + .expect("freeze write_set must success."), ) } fn remove(&self, access_path: &AccessPath) -> Result<()> { self.apply_write_set( - WriteSetMut::new(vec![(access_path.clone(), WriteOp::Deletion)]) - .freeze() - .expect("freeze write_set must success."), + WriteSetMut::new(vec![( + StateKey::AccessPath(access_path.clone()), + WriteOp::Deletion, + )]) + .freeze() + .expect("freeze write_set must success."), ) } @@ -471,21 +571,40 @@ impl ChainStateWriter for ChainStateDB { } fn apply_write_set(&self, write_set: WriteSet) -> Result<()> { + let mut lock_table_handle = self.updates_table_handle.write(); let mut locks = self.updates.write(); - for (access_path, write_op) in write_set { + for (state_key, write_op) in write_set { //update self updates record - locks.insert(access_path.address); - let (account_address, data_path) = access_path.into_inner(); - match write_op { - WriteOp::Value(value) => { - let account_state_object = - self.get_account_state_object(&account_address, true)?; - account_state_object.set(data_path, value); + match state_key { + StateKey::AccessPath(access_path) => { + locks.insert(access_path.address); + let (account_address, data_path) = access_path.into_inner(); + match write_op { + WriteOp::Value(value) => { + let account_state_object = + self.get_account_state_object(&account_address, true)?; + account_state_object.set(data_path, value); + } + WriteOp::Deletion => { + let account_state_object = + self.get_account_state_object(&account_address, false)?; + account_state_object.remove(&data_path)?; + } + } } - WriteOp::Deletion => { - let account_state_object = - self.get_account_state_object(&account_address, false)?; - account_state_object.remove(&data_path)?; + StateKey::TableItem(table_item) => { + debug!("{:?}", table_item); + lock_table_handle.insert(table_item.handle); + let table_handle_state_object = + self.get_table_handle_state_object(&table_item.handle)?; + match write_op { + WriteOp::Value(value) => { + table_handle_state_object.set(table_item.key, value); + } + WriteOp::Deletion => { + table_handle_state_object.remove(&table_item.key); + } + } } } } @@ -494,6 +613,29 @@ impl ChainStateWriter for ChainStateDB { /// Commit fn commit(&self) -> Result { // cache commit + let len = self.updates_table_handle.read().len(); + + for handle in self.updates_table_handle.read().iter() { + let table_handle_state_object = self.get_table_handle_state_object(handle)?; + table_handle_state_object.commit()?; + // put table_handle_state_object commit + self.state_tree_table_handles + .put(*handle, table_handle_state_object.root_hash().to_vec()); + } + if len > 0 { + self.state_tree_table_handles.commit()?; + // update table_handle_address state + + let mut locks = self.updates.write(); + locks.insert(table_handle_address()); + let table_handle_account_state_object = + self.get_account_state_object(&table_handle_address(), true)?; + table_handle_account_state_object.set( + TABLE_PATH.clone(), + self.state_tree_table_handles.root_hash().to_vec(), + ); + } + for address in self.updates.read().iter() { let account_state_object = self.get_account_state_object(address, false)?; let state = account_state_object.commit()?; @@ -505,16 +647,76 @@ impl ChainStateWriter for ChainStateDB { /// flush data to db. fn flush(&self) -> Result<()> { //cache flush + let mut locks_table_handle = self.updates_table_handle.write(); + for h in locks_table_handle.iter() { + let table_handle_state_object = self.get_table_handle_state_object(h)?; + table_handle_state_object.flush()?; + } + locks_table_handle.clear(); + + self.state_tree_table_handles.flush()?; + let mut locks = self.updates.write(); for address in locks.iter() { let account_state_object = self.get_account_state_object(address, false)?; account_state_object.flush()?; } locks.clear(); + // self tree flush self.state_tree.flush() } } +/// represent TableHandleState in runtime memory. +/// TableHandle's SMT Save (table.key, table.value) +struct TableHandleStateObject { + _handle: TableHandle, + state_tree: Mutex>>, +} + +impl TableHandleStateObject { + pub fn new(_handle: TableHandle, store: Arc, root: HashValue) -> Self { + let state_tree = StateTree::>::new(store.clone(), Some(root)); + Self { + _handle, + state_tree: Mutex::new(state_tree), + } + } + + pub fn set(&self, key: Vec, value: Vec) { + self.state_tree.lock().put(key, value) + } + + pub fn remove(&self, key: &Vec) { + self.state_tree.lock().remove(key) + } + + pub fn commit(&self) -> Result<()> { + let state_tree = self.state_tree.lock(); + if state_tree.is_dirty() { + state_tree.commit()?; + } + Ok(()) + } + + pub fn flush(&self) -> Result<()> { + self.state_tree.lock().flush()?; + Ok(()) + } + + pub fn root_hash(&self) -> HashValue { + self.state_tree.lock().root_hash() + } + + pub fn get(&self, key: &Vec) -> Result>> { + self.state_tree.lock().get(key) + } + + pub fn get_with_proof(&self, key: &Vec) -> Result<(Option>, SparseMerkleProof)> { + self.state_tree.lock().get_with_proof(key) + } +} + #[cfg(test)] mod tests; diff --git a/state/statedb/src/tests.rs b/state/statedb/src/tests.rs index 0dd9e7bbb5..1ef495a3c1 100644 --- a/state/statedb/src/tests.rs +++ b/state/statedb/src/tests.rs @@ -1,8 +1,10 @@ use super::*; use starcoin_state_tree::mock::MockStateNodeStore; +use starcoin_types::access_path::AccessPath; use starcoin_types::write_set::{WriteOp, WriteSet, WriteSetMut}; use starcoin_vm_types::account_config::AccountResource; use starcoin_vm_types::move_resource::MoveResource; +use starcoin_vm_types::state_store::state_key::{StateKey, TableItem}; use std::collections::HashMap; fn random_bytes() -> Vec { @@ -10,9 +12,25 @@ fn random_bytes() -> Vec { } fn to_write_set(access_path: AccessPath, value: Vec) -> WriteSet { - WriteSetMut::new(vec![(access_path, WriteOp::Value(value))]) - .freeze() - .expect("freeze write_set must success.") + WriteSetMut::new(vec![( + StateKey::AccessPath(access_path), + WriteOp::Value(value), + )]) + .freeze() + .expect("freeze write_set must success.") +} + +fn state_keys_to_write_set(state_keys: Vec, values: Vec>) -> WriteSet { + WriteSetMut::new( + state_keys + .into_iter() + .zip(values) + .into_iter() + .map(|(key, val)| (key, WriteOp::Value(val))) + .collect::>(), + ) + .freeze() + .expect("freeze write_set must success.") } #[test] @@ -24,7 +42,7 @@ fn test_state_proof() -> Result<()> { chain_state_db.apply_write_set(to_write_set(access_path.clone(), state0.clone()))?; let state_root = chain_state_db.commit()?; - let state1 = chain_state_db.get(&access_path)?; + let state1 = chain_state_db.get_state_value(&StateKey::AccessPath(access_path.clone()))?; assert!(state1.is_some()); assert_eq!(state0, state1.unwrap()); println!("{}", access_path.address.key_hash()); @@ -97,7 +115,9 @@ fn test_state_version() -> Result<()> { chain_state_db.apply_write_set(to_write_set(access_path.clone(), new_state))?; let chain_state_db_ori = ChainStateDB::new(storage, Some(old_root)); - let old_state2 = chain_state_db_ori.get(&access_path)?.unwrap(); + let old_state2 = chain_state_db_ori + .get_state_value(&StateKey::AccessPath(access_path))? + .unwrap(); assert_eq!(old_state, old_state2); Ok(()) @@ -134,3 +154,143 @@ fn test_state_db_dump_iter() -> Result<()> { assert_eq!(kv1, kv2); Ok(()) } + +fn check_write_set(chain_state_db: &ChainStateDB, write_set: &WriteSet) -> Result<()> { + for (state_key, value) in write_set.iter() { + let val = chain_state_db.get_state_value(state_key)?; + assert!(val.is_some()); + assert_eq!(WriteOp::Value(val.unwrap()), *value); + } + Ok(()) +} + +#[test] +fn test_state_db_with_table_item_once() -> Result<()> { + let storage = MockStateNodeStore::new(); + let chain_state_db = ChainStateDB::new(Arc::new(storage), None); + let handle1 = TableHandle(AccountAddress::random()); + let handle2 = TableHandle(AccountAddress::random()); + let key2 = random_bytes(); + let val2 = random_bytes(); + let key3 = random_bytes(); + let val3 = random_bytes(); + let key4 = random_bytes(); + let val4 = random_bytes(); + let key5 = random_bytes(); + let val5 = random_bytes(); + let state_keys = vec![ + StateKey::AccessPath(AccessPath::random_code()), + StateKey::AccessPath(AccessPath::random_resource()), + StateKey::TableItem(TableItem { + handle: handle1, + key: key2.clone(), + }), + StateKey::TableItem(TableItem { + handle: handle1, + key: key3.clone(), + }), + StateKey::TableItem(TableItem { + handle: handle2, + key: key4.clone(), + }), + StateKey::TableItem(TableItem { + handle: handle2, + key: key5.clone(), + }), + ]; + let values = vec![ + random_bytes(), + random_bytes(), + val2.clone(), + val3.clone(), + val4.clone(), + val5.clone(), + ]; + let write_set = state_keys_to_write_set(state_keys, values); + let write_set1 = write_set.clone(); + chain_state_db.apply_write_set(write_set)?; + check_write_set(&chain_state_db, &write_set1)?; + chain_state_db.commit()?; + check_write_set(&chain_state_db, &write_set1)?; + chain_state_db.flush()?; + check_write_set(&chain_state_db, &write_set1)?; + + let storage1 = MockStateNodeStore::new(); + let storage2 = MockStateNodeStore::new(); + let table_handle_state1 = + TableHandleStateObject::new(handle1, Arc::new(storage1), *SPARSE_MERKLE_PLACEHOLDER_HASH); + let table_handle_state2 = + TableHandleStateObject::new(handle2, Arc::new(storage2), *SPARSE_MERKLE_PLACEHOLDER_HASH); + + table_handle_state1.set(key2, val2); + table_handle_state1.set(key3, val3); + table_handle_state2.set(key4, val4); + table_handle_state2.set(key5, val5); + table_handle_state1.commit()?; + table_handle_state1.flush()?; + table_handle_state2.commit()?; + table_handle_state2.flush()?; + + let storage3 = MockStateNodeStore::new(); + let state_tree_table_handles = StateTree::new(Arc::new(storage3), None); + state_tree_table_handles.put(handle1, table_handle_state1.root_hash().to_vec()); + state_tree_table_handles.put(handle2, table_handle_state2.root_hash().to_vec()); + state_tree_table_handles.commit()?; + state_tree_table_handles.flush()?; + + assert_eq!( + chain_state_db.table_handles_root_hash(), + state_tree_table_handles.root_hash() + ); + assert_eq!( + chain_state_db.table_handle_address_root_hash(), + state_tree_table_handles.root_hash() + ); + Ok(()) +} + +#[test] +fn test_state_with_table_item_proof() -> Result<()> { + let storage = MockStateNodeStore::new(); + let chain_state_db = ChainStateDB::new(Arc::new(storage), None); + let handle1 = TableHandle(AccountAddress::random()); + let handle2 = TableHandle(AccountAddress::random()); + let key1 = random_bytes(); + let val1 = random_bytes(); + let key2 = random_bytes(); + let val2 = random_bytes(); + let key3 = random_bytes(); + let val3 = random_bytes(); + let state_keys = vec![ + StateKey::AccessPath(AccessPath::random_code()), + StateKey::AccessPath(AccessPath::random_resource()), + StateKey::TableItem(TableItem { + handle: handle1, + key: key1.clone(), + }), + StateKey::TableItem(TableItem { + handle: handle1, + key: key2.clone(), + }), + StateKey::TableItem(TableItem { + handle: handle2, + key: key3.clone(), + }), + ]; + let values = vec![random_bytes(), random_bytes(), val1, val2, val3]; + let write_set = state_keys_to_write_set(state_keys, values); + chain_state_db.apply_write_set(write_set)?; + chain_state_db.commit()?; + chain_state_db.flush()?; + + let state_with_table_item_proof1 = + chain_state_db.get_with_table_item_proof(&handle1, key1.as_slice())?; + state_with_table_item_proof1.verify(&handle1, key1.as_slice())?; + let state_with_table_item_proof2 = + chain_state_db.get_with_table_item_proof(&handle1, key2.as_slice())?; + state_with_table_item_proof2.verify(&handle1, key2.as_slice())?; + let state_with_table_item_proof3 = + chain_state_db.get_with_table_item_proof(&handle2, key3.as_slice())?; + state_with_table_item_proof3.verify(&handle2, key3.as_slice())?; + Ok(()) +} diff --git a/storage/Cargo.toml b/storage/Cargo.toml index db61e3e89e..519e5a69c6 100644 --- a/storage/Cargo.toml +++ b/storage/Cargo.toml @@ -22,18 +22,19 @@ network-types = { workspace = true } starcoin-config = { workspace = true } starcoin-metrics = { workspace = true } starcoin-uint = { workspace = true } +starcoin-vm-types = { workspace = true } [dev-dependencies] proptest = { workspace = true } proptest-derive = { workspace = true } rand = { workspace = true } -starcoin-types = { features = [ "fuzzing",], workspace = true } +starcoin-types = { features = ["fuzzing"], workspace = true } starcoin-crypto = { workspace = true } stest = { workspace = true } [features] default = [] -fuzzing = [ "proptest", "proptest-derive", "starcoin-types/fuzzing",] +fuzzing = ["proptest", "proptest-derive", "starcoin-types/fuzzing"] [package] authors = { workspace = true } @@ -48,5 +49,5 @@ rust-version = { workspace = true } [dependencies.rocksdb] default-features = false -features = [ "lz4",] +features = ["lz4"] workspace = true diff --git a/storage/src/lib.rs b/storage/src/lib.rs index eb1c36bfb1..92f4bc23e8 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -10,6 +10,7 @@ use crate::chain_info::ChainInfoStorage; use crate::contract_event::ContractEventStorage; use crate::state_node::StateStorage; use crate::storage::{CodecKVStore, CodecWriteBatch, ColumnFamilyName, StorageInstance}; +//use crate::table_info::{TableInfoStorage, TableInfoStore}; use crate::transaction::TransactionStorage; use crate::transaction_info::{TransactionInfoHashStorage, TransactionInfoStorage}; use anyhow::{bail, format_err, Error, Result}; @@ -27,6 +28,7 @@ use starcoin_types::{ block::{Block, BlockBody, BlockHeader, BlockInfo}, startup_info::StartupInfo, }; +//use starcoin_vm_types::state_store::table::{TableHandle, TableInfo}; use std::collections::BTreeMap; use std::fmt::{Debug, Display, Formatter}; use std::sync::Arc; @@ -43,6 +45,7 @@ pub mod errors; pub mod metrics; pub mod state_node; pub mod storage; +pub mod table_info; #[cfg(test)] mod tests; pub mod transaction; @@ -51,6 +54,7 @@ mod upgrade; #[macro_use] pub mod storage_macros; + pub const DEFAULT_PREFIX_NAME: ColumnFamilyName = "default"; pub const BLOCK_ACCUMULATOR_NODE_PREFIX_NAME: ColumnFamilyName = "acc_node_block"; pub const TRANSACTION_ACCUMULATOR_NODE_PREFIX_NAME: ColumnFamilyName = "acc_node_transaction"; @@ -69,6 +73,7 @@ pub const TRANSACTION_INFO_PREFIX_NAME_V2: ColumnFamilyName = "transaction_info_ pub const TRANSACTION_INFO_HASH_PREFIX_NAME: ColumnFamilyName = "transaction_info_hash"; pub const CONTRACT_EVENT_PREFIX_NAME: ColumnFamilyName = "contract_event"; pub const FAILED_BLOCK_PREFIX_NAME: ColumnFamilyName = "failed_block"; +pub const TABLE_INFO_PREFIX_NAME: ColumnFamilyName = "table_info"; ///db storage use prefix_name vec to init /// Please note that adding a prefix needs to be added in vec simultaneously, remember!! @@ -131,6 +136,7 @@ static VEC_PREFIX_NAME_V3: Lazy> = Lazy::new(|| { TRANSACTION_INFO_HASH_PREFIX_NAME, CONTRACT_EVENT_PREFIX_NAME, FAILED_BLOCK_PREFIX_NAME, + // TABLE_INFO_PREFIX_NAME, ] }); #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, IntoPrimitive, TryFromPrimitive)] @@ -266,6 +272,7 @@ pub struct Storage { block_info_storage: BlockInfoStorage, event_storage: ContractEventStorage, chain_info_storage: ChainInfoStorage, + // table_info_storage: TableInfoStorage, // instance: StorageInstance, } @@ -285,6 +292,7 @@ impl Storage { block_info_storage: BlockInfoStorage::new(instance.clone()), event_storage: ContractEventStorage::new(instance.clone()), chain_info_storage: ChainInfoStorage::new(instance), + // table_info_storage: TableInfoStorage::new(instance), // instance, }; Ok(storage) @@ -638,3 +646,25 @@ impl Store for Storage { } } } + +/* +XXX FIXME YSG temp comment +impl TableInfoStore for Storage { + fn get_table_info(&self, key: TableHandle) -> Result> { + self.table_info_storage.get(key) + } + + fn save_table_info(&self, key: TableHandle, table_info: TableInfo) -> Result<()> { + self.table_info_storage.put(key, table_info) + } + + fn get_table_infos(&self, keys: Vec) -> Result>> { + self.table_info_storage.multiple_get(keys) + } + + fn save_table_infos(&self, keys: Vec, table_infos: Vec) -> Result<()> { + let batch = CodecWriteBatch::new_puts(keys.into_iter().zip(table_infos).collect()); + self.table_info_storage.write_batch(batch) + } +} +*/ diff --git a/storage/src/storage.rs b/storage/src/storage.rs index 9897918d60..9f65f0b474 100644 --- a/storage/src/storage.rs +++ b/storage/src/storage.rs @@ -8,6 +8,7 @@ use crate::upgrade::DBUpgrade; use anyhow::{bail, format_err, Result}; use byteorder::{BigEndian, ReadBytesExt}; use starcoin_crypto::HashValue; +use starcoin_vm_types::state_store::table::TableHandle; use std::convert::TryInto; use std::fmt::Debug; use std::marker::PhantomData; @@ -551,6 +552,16 @@ impl ValueCodec for Vec { } } +impl KeyCodec for TableHandle { + fn encode_key(&self) -> Result> { + bcs_ext::to_bytes(self) + } + + fn decode_key(data: &[u8]) -> Result { + bcs_ext::from_bytes(data) + } +} + impl CodecKVStore for S where K: KeyCodec, diff --git a/storage/src/table_info/mod.rs b/storage/src/table_info/mod.rs new file mode 100644 index 0000000000..9bbc34bdf9 --- /dev/null +++ b/storage/src/table_info/mod.rs @@ -0,0 +1,61 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::storage::{CodecKVStore, CodecWriteBatch, ValueCodec}; +use crate::{define_storage, TABLE_INFO_PREFIX_NAME}; +use anyhow::Result; +use bcs_ext::BCSCodec; +use starcoin_vm_types::state_store::table::{TableHandle, TableInfo}; + +define_storage!( + TableInfoStorage, + TableHandle, + TableInfo, + TABLE_INFO_PREFIX_NAME +); + +pub trait TableInfoStore { + fn get_table_info(&self, key: TableHandle) -> Result>; + fn save_table_info(&self, key: TableHandle, table_info: TableInfo) -> Result<()>; + fn get_table_infos(&self, keys: Vec) -> Result>>; + fn save_table_infos(&self, keys: Vec, table_infos: Vec) -> Result<()>; +} + +impl ValueCodec for TableHandle { + fn encode_value(&self) -> Result> { + self.encode() + } + + fn decode_value(data: &[u8]) -> Result { + Self::decode(data) + } +} + +impl ValueCodec for TableInfo { + fn encode_value(&self) -> Result> { + self.encode() + } + + fn decode_value(data: &[u8]) -> Result { + Self::decode(data) + } +} + +impl TableInfoStore for TableInfoStorage { + fn get_table_info(&self, key: TableHandle) -> Result> { + self.get(key) + } + + fn save_table_info(&self, key: TableHandle, table_info: TableInfo) -> Result<()> { + self.put(key, table_info) + } + + fn get_table_infos(&self, keys: Vec) -> Result>> { + self.multiple_get(keys) + } + + fn save_table_infos(&self, keys: Vec, table_infos: Vec) -> Result<()> { + let batch = CodecWriteBatch::new_puts(keys.into_iter().zip(table_infos).collect()); + self.write_batch(batch) + } +} diff --git a/storage/src/tests/test_storage.rs b/storage/src/tests/test_storage.rs index 986978528a..8b171b1c68 100644 --- a/storage/src/tests/test_storage.rs +++ b/storage/src/tests/test_storage.rs @@ -8,7 +8,8 @@ use crate::db_storage::DBStorage; use crate::storage::{CodecKVStore, InnerStore, StorageInstance, ValueCodec}; use crate::transaction_info::{BlockTransactionInfo, OldTransactionInfoStorage}; use crate::{ - BlockInfoStore, BlockStore, BlockTransactionInfoStore, Storage, StorageVersion, + BlockInfoStore, BlockStore, BlockTransactionInfoStore, Storage, + StorageVersion, /*TableInfoStore,*/ TransactionStore, DEFAULT_PREFIX_NAME, TRANSACTION_INFO_PREFIX_NAME, TRANSACTION_INFO_PREFIX_NAME_V2, }; @@ -17,11 +18,14 @@ use starcoin_accumulator::accumulator_info::AccumulatorInfo; use starcoin_config::RocksdbConfig; use starcoin_crypto::HashValue; use starcoin_types::block::{Block, BlockBody, BlockHeader, BlockInfo}; +//use starcoin_types::language_storage::TypeTag; use starcoin_types::startup_info::SnapshotRange; use starcoin_types::transaction::{ RichTransactionInfo, SignedUserTransaction, Transaction, TransactionInfo, }; use starcoin_types::vm_error::KeptVMStatus; +//use starcoin_vm_types::account_address::AccountAddress; +//use starcoin_vm_types::state_store::table::{TableHandle, TableInfo}; use std::path::Path; #[test] @@ -470,3 +474,44 @@ pub fn test_cache_evict_multi_get() -> Result<()> { assert_eq!(infos.get(2).unwrap().clone().unwrap(), transaction_info3); Ok(()) } + +/* +XXX FIXME YSG temp comment +#[test] +fn test_table_info_storage() -> Result<()> { + let tmpdir = starcoin_config::temp_dir(); + let instance = StorageInstance::new_cache_and_db_instance( + CacheStorage::new(None), + DBStorage::new(tmpdir.path(), RocksdbConfig::default(), None)?, + ); + let storage = Storage::new(instance)?; + let key1 = TableHandle(AccountAddress::random()); + let table_info1 = TableInfo::new(TypeTag::U8, TypeTag::U8); + storage.save_table_info(key1, table_info1.clone())?; + let val = storage.get_table_info(key1); + assert!(val.is_ok()); + assert_eq!(val.unwrap().unwrap(), table_info1); + let key2 = TableHandle(AccountAddress::random()); + let val = storage.get_table_info(key2); + assert!(val.is_ok()); + assert_eq!(val.unwrap(), None); + let keys = vec![ + TableHandle(AccountAddress::random()), + TableHandle(AccountAddress::random()), + ]; + let vals = vec![ + TableInfo::new(TypeTag::U8, TypeTag::Address), + TableInfo::new(TypeTag::Address, TypeTag::U128), + ]; + storage.save_table_infos(keys.clone(), vals.clone())?; + let vals2 = storage.get_table_infos(keys); + assert!(vals2.is_ok()); + let vals2 = vals2 + .unwrap() + .into_iter() + .map(|x| x.unwrap()) + .collect::>(); + assert_eq!(vals, vals2); + Ok(()) +} +*/ diff --git a/stratum/Cargo.toml b/stratum/Cargo.toml index 43ec272d81..af658af938 100644 --- a/stratum/Cargo.toml +++ b/stratum/Cargo.toml @@ -3,13 +3,13 @@ anyhow = { workspace = true } byteorder = { workspace = true } futures = { workspace = true } hex = { default-features = false, workspace = true } -jsonrpc-core = { features = ["arbitrary_precision", ], workspace = true } +jsonrpc-core = { features = ["arbitrary_precision"], workspace = true } jsonrpc-core-client = { workspace = true } jsonrpc-derive = { workspace = true } jsonrpc-pubsub = { workspace = true } jsonrpc-tcp-server = { workspace = true } serde = { workspace = true } -serde_json = { features = ["arbitrary_precision", ], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-config = { workspace = true } starcoin-crypto = { workspace = true } starcoin-logger = { workspace = true } diff --git a/sync/Cargo.toml b/sync/Cargo.toml index 54d34520d2..ea87053e30 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -56,7 +56,7 @@ starcoin-statedb = { workspace = true } starcoin-txpool-mock-service = { workspace = true } starcoin-executor = { workspace = true } test-helper = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } [package] authors = { workspace = true } diff --git a/test-helper/Cargo.toml b/test-helper/Cargo.toml index 676cf9176f..c5feb78d01 100644 --- a/test-helper/Cargo.toml +++ b/test-helper/Cargo.toml @@ -47,7 +47,7 @@ starcoin-types = { workspace = true } starcoin-vm-types = { workspace = true } stdlib = { workspace = true } thiserror = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } move-ir-compiler = { workspace = true } [dev-dependencies] diff --git a/test-helper/src/dao.rs b/test-helper/src/dao.rs index 0548d5e40c..f443106ca3 100644 --- a/test-helper/src/dao.rs +++ b/test-helper/src/dao.rs @@ -22,7 +22,6 @@ use starcoin_types::identifier::Identifier; use starcoin_types::language_storage::{ModuleId, StructTag, TypeTag}; use starcoin_types::transaction::{ScriptFunction, TransactionPayload}; use starcoin_vm_types::account_config::core_code_address; -use starcoin_vm_types::gas_schedule::GasAlgebra; use starcoin_vm_types::on_chain_config::VMConfig; use starcoin_vm_types::value::{serialize_values, MoveValue}; @@ -88,36 +87,36 @@ pub fn proposal_exist( } pub fn on_chain_config_type_tag(params_type_tag: TypeTag) -> TypeTag { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("OnChainConfigDao").unwrap(), name: Identifier::new("OnChainConfigUpdate").unwrap(), type_params: vec![params_type_tag], - }) + })) } pub fn reward_config_type_tag() -> TypeTag { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("RewardConfig").unwrap(), name: Identifier::new("RewardConfig").unwrap(), type_params: vec![], - }) + })) } pub fn transaction_timeout_type_tag() -> TypeTag { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("TransactionTimeoutConfig").unwrap(), name: Identifier::new("TransactionTimeoutConfig").unwrap(), type_params: vec![], - }) + })) } pub fn txn_publish_config_type_tag() -> TypeTag { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("TransactionPublishOption").unwrap(), name: Identifier::new("TransactionPublishOption").unwrap(), type_params: vec![], - }) + })) } fn execute_create_account( @@ -383,17 +382,17 @@ pub fn vote_vm_config_script(_net: &ChainNetwork, vm_config: VMConfig) -> Script .unwrap(), bcs_ext::to_bytes(&bcs_ext::to_bytes(&vm_config.gas_schedule.native_table).unwrap()) .unwrap(), - bcs_ext::to_bytes(&gas_constants.global_memory_per_byte_cost.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.global_memory_per_byte_write_cost.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.min_transaction_gas_units.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.large_transaction_cutoff.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.intrinsic_gas_per_byte.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.maximum_number_of_gas_units.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.min_price_per_gas_unit.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.max_price_per_gas_unit.get()).unwrap(), + bcs_ext::to_bytes(&gas_constants.global_memory_per_byte_cost).unwrap(), + bcs_ext::to_bytes(&gas_constants.global_memory_per_byte_write_cost).unwrap(), + bcs_ext::to_bytes(&gas_constants.min_transaction_gas_units).unwrap(), + bcs_ext::to_bytes(&gas_constants.large_transaction_cutoff).unwrap(), + bcs_ext::to_bytes(&gas_constants.intrinsic_gas_per_byte).unwrap(), + bcs_ext::to_bytes(&gas_constants.maximum_number_of_gas_units).unwrap(), + bcs_ext::to_bytes(&gas_constants.min_price_per_gas_unit).unwrap(), + bcs_ext::to_bytes(&gas_constants.max_price_per_gas_unit).unwrap(), bcs_ext::to_bytes(&gas_constants.max_transaction_size_in_bytes).unwrap(), bcs_ext::to_bytes(&gas_constants.gas_unit_scaling_factor).unwrap(), - bcs_ext::to_bytes(&gas_constants.default_account_size.get()).unwrap(), + bcs_ext::to_bytes(&gas_constants.default_account_size).unwrap(), bcs_ext::to_bytes(&0u64).unwrap(), ], ) diff --git a/test-helper/src/executor.rs b/test-helper/src/executor.rs index 5fb5076c31..a3f59433de 100644 --- a/test-helper/src/executor.rs +++ b/test-helper/src/executor.rs @@ -115,7 +115,7 @@ pub fn compile_modules_with_address(address: AccountAddress, code: &str) -> Vec< compiled_result .into_iter() - .map(|m| Module::new(m.serialize())) + .map(|m| Module::new(m.serialize(None))) .collect() } @@ -132,7 +132,7 @@ pub fn compile_script(code: impl AsRef) -> Result> { .pop() .expect("at least contain one script") .into_compiled_unit() - .serialize()) + .serialize(None)) } pub fn compile_ir_script(code: impl AsRef) -> Result> { diff --git a/test-helper/src/starcoin_dao.rs b/test-helper/src/starcoin_dao.rs index e966df9440..7be7ba0ae5 100644 --- a/test-helper/src/starcoin_dao.rs +++ b/test-helper/src/starcoin_dao.rs @@ -437,12 +437,12 @@ fn block_from_metadata(block_meta: BlockMetadata, chain_state: &ChainStateDB) -> } pub fn starcoin_dao_type_tag() -> TypeTag { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("StarcoinDAO").unwrap(), name: Identifier::new("StarcoinDAO").unwrap(), type_params: vec![], - }) + })) } pub fn execute_create_account( diff --git a/testsuite/Cargo.toml b/testsuite/Cargo.toml index 32c878e099..5a7608bd9e 100644 --- a/testsuite/Cargo.toml +++ b/testsuite/Cargo.toml @@ -5,15 +5,15 @@ test = false [dependencies] anyhow = { workspace = true } -clap = { features = [ "derive",], workspace = true } -cucumber = { workspace = true} +clap = { features = ["derive"], workspace = true } +cucumber = { workspace = true } jpst = { workspace = true } jsonpath = { workspace = true } regex = { workspace = true } scmd = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } serde_bytes = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } starcoin-account-api = { workspace = true } starcoin-account-provider = { workspace = true } starcoin-chain = { workspace = true } @@ -36,7 +36,6 @@ starcoin-types = { workspace = true } starcoin-vm-runtime = { workspace = true } starcoin-vm-types = { workspace = true } - [dev-dependencies] starcoin-transaction-builder = { workspace = true } diff --git a/testsuite/features/cmd.feature b/testsuite/features/cmd.feature index da607d3116..56324551e0 100644 --- a/testsuite/features/cmd.feature +++ b/testsuite/features/cmd.feature @@ -184,7 +184,6 @@ Feature: cmd integration test Examples: | | - #StarcoinFramework checkpoint Scenario Outline: [ignore] starcoin-framework checkpoint Then cmd: "dev get-coin" @@ -192,7 +191,7 @@ Feature: cmd integration test Then cmd: "account execute-function --function 0x1::Block::checkpoint_entry -b" Then cmd: "dev call-api chain.get_block_by_number [1,{\"raw\":true}]" Then cmd: "account execute-function --function 0x1::Block::update_state_root_entry --arg {{$.dev[1].ok.raw.header}} -b" - Then cmd: "dev call --function 0x1::Block::latest_state_root" + Then cmd: "dev call --function 0x1::Block::latest_state_root" Then assert: "{{$.dev[2].ok[1]}} == {{$.dev[1].ok.header.state_root}}" Examples: diff --git a/types/Cargo.toml b/types/Cargo.toml index 2fd1c132d5..bf690da14b 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -4,7 +4,7 @@ bcs-ext = { package = "bcs-ext", workspace = true } byteorder = { default-features = false, workspace = true } bytes = { workspace = true } forkable-jellyfish-merkle = { workspace = true } -hex = { default-features = false, features = [ "serde",], workspace = true } +hex = { default-features = false, features = ["serde"], workspace = true } num_enum = { workspace = true } proptest = { default-features = false, optional = true, workspace = true } proptest-derive = { default-features = false, optional = true, workspace = true } @@ -21,7 +21,7 @@ thiserror = { workspace = true } [features] default = [] -fuzzing = [ "proptest", "proptest-derive", "starcoin-vm-types/fuzzing",] +fuzzing = ["proptest", "proptest-derive", "starcoin-vm-types/fuzzing"] [package] authors = { workspace = true } diff --git a/types/src/account.rs b/types/src/account.rs index 8179897b4f..3711315ffb 100644 --- a/types/src/account.rs +++ b/types/src/account.rs @@ -20,6 +20,7 @@ use starcoin_vm_types::account_config::{core_code_address, stc_type_tag, STC_TOK use starcoin_vm_types::genesis_config::ChainId; use starcoin_vm_types::identifier::Identifier; use starcoin_vm_types::language_storage::ModuleId; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::token::token_code::TokenCode; use starcoin_vm_types::transaction::ScriptFunction; use starcoin_vm_types::value::{MoveStructLayout, MoveTypeLayout}; @@ -558,7 +559,10 @@ impl AccountData { .unwrap() .simple_serialize(&AccountData::layout()) .unwrap(); - write_set.push((self.make_account_access_path(), WriteOp::Value(account))); + write_set.push(( + StateKey::AccessPath(self.make_account_access_path()), + WriteOp::Value(account), + )); for (code, balance_blob) in balance_blobs.into_iter() { let balance = balance_blob .value_as::() @@ -566,7 +570,7 @@ impl AccountData { .simple_serialize(&Balance::layout()) .unwrap(); write_set.push(( - self.make_balance_access_path(code.as_str()), + StateKey::AccessPath(self.make_balance_access_path(code.as_str())), WriteOp::Value(balance), )); } @@ -577,7 +581,7 @@ impl AccountData { .simple_serialize(&EventHandleGenerator::layout()) .unwrap(); write_set.push(( - self.make_event_generator_access_path(), + StateKey::AccessPath(self.make_event_generator_access_path()), WriteOp::Value(event_generator), )); WriteSetMut::new(write_set).freeze().unwrap() diff --git a/vm/compiler/Cargo.toml b/vm/compiler/Cargo.toml index cb3592a851..6857a1844d 100644 --- a/vm/compiler/Cargo.toml +++ b/vm/compiler/Cargo.toml @@ -5,7 +5,10 @@ move-command-line-common = { workspace = true } move-compiler = { package = "move-compiler", workspace = true } once_cell = { workspace = true } petgraph = { workspace = true } -regex = { default-features = false, features = [ "std", "perf",], workspace = true } +regex = { default-features = false, features = [ + "std", + "perf", +], workspace = true } starcoin-crypto = { workspace = true } starcoin-logger = { workspace = true } starcoin-vm-types = { workspace = true } diff --git a/vm/compiler/src/bytecode_transpose.rs b/vm/compiler/src/bytecode_transpose.rs index 69f18de297..e265103ce6 100644 --- a/vm/compiler/src/bytecode_transpose.rs +++ b/vm/compiler/src/bytecode_transpose.rs @@ -1,7 +1,7 @@ use anyhow::Result; use move_binary_format::access::ModuleAccess; use move_binary_format::file_format::{Bytecode, CompiledScript}; -use move_binary_format::file_format_common::{VERSION_3, VERSION_4}; +use move_binary_format::file_format_common::{VERSION_3, VERSION_4, VERSION_6}; use move_binary_format::CompiledModule; pub struct ModuleBytecodeDowngrader; @@ -11,7 +11,7 @@ impl ModuleBytecodeDowngrader { VERSION_4 => Self::from_v4_to_v3(m), VERSION_3 => { let mut bytes = vec![]; - m.serialize_to_version(&mut bytes, VERSION_3)?; + m.serialize_for_version(Some(VERSION_3), &mut bytes)?; Ok(bytes) } _ => anyhow::bail!("unsupport module bytecode version {}", m.version), @@ -44,7 +44,47 @@ impl ModuleBytecodeDowngrader { } let mut bytes = vec![]; - m.serialize_to_version(&mut bytes, VERSION_3)?; + m.serialize_for_version(Some(VERSION_3), &mut bytes)?; + Ok(bytes) + } + + pub fn to_v4(m: &CompiledModule) -> Result> { + match m.version { + VERSION_6 => Self::from_v6_to_v4(m), + VERSION_4 => { + let mut bytes = vec![]; + m.serialize_for_version(Some(VERSION_4), &mut bytes)?; + Ok(bytes) + } + _ => anyhow::bail!("unsupport module bytecode version {}", m.version), + } + } + pub fn from_v6_to_v4(m: &CompiledModule) -> Result> { + anyhow::ensure!(m.version() == VERSION_6, "bytecode version is not v6"); + + for fd in &m.function_defs { + if let Some(cu) = &fd.code { + for c in &cu.code { + if matches!( + c, + Bytecode::LdU16(_) + | Bytecode::LdU32(_) + | Bytecode::LdU256(_) + | Bytecode::CastU16 + | Bytecode::CastU32 + | Bytecode::CastU256 + ) { + anyhow::bail!( + "module {:?} contains bytecodes introduced in v6 bytecode version", + m.self_id() + ); + } + } + } + } + + let mut bytes = vec![]; + m.serialize_for_version(Some(VERSION_4), &mut bytes)?; Ok(bytes) } } @@ -71,7 +111,29 @@ impl ScriptBytecodeDowgrader { } let mut bytes = vec![]; - s.serialize_to_version(&mut bytes, VERSION_3)?; + s.serialize_for_version(Some(VERSION_3), &mut bytes)?; + Ok(bytes) + } + + pub fn from_v6_to_v4(s: &CompiledScript) -> Result> { + anyhow::ensure!(s.version == VERSION_6, "bytecode version is not v6"); + + for c in &s.code.code { + if matches!( + c, + Bytecode::LdU16(_) + | Bytecode::LdU32(_) + | Bytecode::LdU256(_) + | Bytecode::CastU16 + | Bytecode::CastU32 + | Bytecode::CastU256 + ) { + anyhow::bail!("script contains bytecodes introduced in v6 bytecode version",); + } + } + + let mut bytes = vec![]; + s.serialize_for_version(Some(VERSION_4), &mut bytes)?; Ok(bytes) } } diff --git a/vm/compiler/src/lib.rs b/vm/compiler/src/lib.rs index 5377f02805..b9f0b4cd12 100644 --- a/vm/compiler/src/lib.rs +++ b/vm/compiler/src/lib.rs @@ -9,6 +9,7 @@ pub use move_compiler::Compiler; use crate::diagnostics::report_diagnostics_to_color_buffer; /// A wrap to move-lang compiler use anyhow::{bail, ensure, Result}; +use move_binary_format::errors::PartialVMResult; use move_compiler::compiled_unit::AnnotatedCompiledUnit; use move_compiler::diagnostics::{unwrap_or_report_diagnostics, Diagnostics, FilesSourceText}; use move_compiler::shared::{Flags, NumericalAddress}; @@ -187,9 +188,12 @@ pub fn compile_source_string_no_report( for dep in deps { windows_line_ending_to_unix_in_file(dep)?; } - let compiler = move_compiler::Compiler::new(&targets, deps) - .set_named_address_values(starcoin_framework_named_addresses()) - .set_flags(Flags::empty().set_sources_shadow_deps(true)); + let compiler = move_compiler::Compiler::from_files( + targets, + deps.to_vec(), + starcoin_framework_named_addresses(), + ) + .set_flags(Flags::empty().set_sources_shadow_deps(true)); compiler.build() } @@ -202,16 +206,25 @@ pub fn check_module_compat(pre_code: &[u8], new_code: &[u8]) -> VMResult { let old = Module::new(&pre_module); let new = Module::new(&new_module); - - Ok(Compatibility::check(&old, &new).is_fully_compatible()) + if Compatibility::new(true, true, false) + .check(&old, &new) + .is_err() + { + Ok(false) + } else { + Ok(true) + } } /// check module compatibility -pub fn check_compiled_module_compat(pre: &CompiledModule, new: &CompiledModule) -> Compatibility { +pub fn check_compiled_module_compat( + pre: &CompiledModule, + new: &CompiledModule, +) -> PartialVMResult<()> { let old = Module::new(pre); let new = Module::new(new); - Compatibility::check(&old, &new) + Compatibility::new(true, true, false).check(&old, &new) } /// Load bytecode file, return the bytecode bytes, and whether it's script. @@ -353,7 +366,7 @@ mod tests { .pop() .unwrap() .into_compiled_unit() - .serialize(); + .serialize(None); let new_code = compile_source_string_no_report(new_source_code, &[], CORE_CODE_ADDRESS) .unwrap() .1 @@ -362,7 +375,7 @@ mod tests { .pop() .unwrap() .into_compiled_unit() - .serialize(); + .serialize(None); let compatible = check_module_compat(pre_code.as_slice(), new_code.as_slice()).unwrap(); assert_eq!(compatible, expect); } diff --git a/vm/gas-algebra-ext/Cargo.toml b/vm/gas-algebra-ext/Cargo.toml new file mode 100644 index 0000000000..82da3aae01 --- /dev/null +++ b/vm/gas-algebra-ext/Cargo.toml @@ -0,0 +1,22 @@ +[dependencies] +move-core-types = { workspace = true } +move-binary-format = { workspace = true } +move-stdlib = { workspace = true } +move-table-extension = { workspace = true } +move-vm-types = { workspace = true } +move-vm-test-utils = { workspace = true } +starcoin-natives = { workspace = true } +serde = { workspace = true } + + +[package] +authors = { workspace = true } +description = "starcoin Move VM gas algebra ext" +edition = { workspace = true } +license = { workspace = true } +name = "starcoin-gas-algebra-ext" +publish = { workspace = true } +version = "1.12.9" +homepage = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } diff --git a/vm/gas-algebra-ext/src/algebra.rs b/vm/gas-algebra-ext/src/algebra.rs new file mode 100644 index 0000000000..e72629b565 --- /dev/null +++ b/vm/gas-algebra-ext/src/algebra.rs @@ -0,0 +1,18 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_core_types::gas_algebra::{GasQuantity, InternalGasUnit, UnitDiv}; + +/// Unit of (external) gas. +pub enum GasUnit {} + +/// Unit of gas currency. 1 NanoSTC = 10^-9 Starcoin coins. +pub enum NanoSTC {} + +pub type Gas = GasQuantity; + +pub type GasScalingFactor = GasQuantity>; + +// pub type Fee = GasQuantity; + +pub type FeePerGasUnit = GasQuantity>; diff --git a/vm/gas-algebra-ext/src/gas_meter.rs b/vm/gas-algebra-ext/src/gas_meter.rs new file mode 100644 index 0000000000..14e18e54eb --- /dev/null +++ b/vm/gas-algebra-ext/src/gas_meter.rs @@ -0,0 +1,31 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module contains the official gas meter implementation, along with some top-level gas +//! parameters and traits to help manipulate them. + +use std::collections::BTreeMap; + +pub(crate) const EXECUTION_GAS_MULTIPLIER: u64 = 1; + +/// A trait for converting from a map representation of the on-chain gas schedule. +pub trait FromOnChainGasSchedule: Sized { + /// Constructs a value of this type from a map representation of the on-chain gas schedule. + /// `None` should be returned when the gas schedule is missing some required entries. + /// Unused entries should be safely ignored. + fn from_on_chain_gas_schedule(gas_schedule: &BTreeMap) -> Option; +} + +/// A trait for converting to a list of entries of the on-chain gas schedule. +pub trait ToOnChainGasSchedule { + /// Converts `self` into a list of entries of the on-chain gas schedule. + /// Each entry is a key-value pair where the key is a string representing the name of the + /// parameter, where the value is the gas parameter itself. + fn to_on_chain_gas_schedule(&self) -> Vec<(String, u64)>; +} + +/// A trait for defining an initial value to be used in the genesis. +pub trait InitialGasSchedule: Sized { + /// Returns the initial value of this type, which is used in the genesis. + fn initial() -> Self; +} diff --git a/vm/gas-algebra-ext/src/instr.rs b/vm/gas-algebra-ext/src/instr.rs new file mode 100644 index 0000000000..141f63d6da --- /dev/null +++ b/vm/gas-algebra-ext/src/instr.rs @@ -0,0 +1,258 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module defines all the gas parameters and formulae for instructions, along with their +//! initial values in the genesis and a mapping between the Rust representation and the on-chain +//! gas schedule. + +use crate::gas_meter::EXECUTION_GAS_MULTIPLIER as MUL; +use move_binary_format::errors::PartialVMResult; +use move_core_types::gas_algebra::{ + InternalGas, InternalGasPerAbstractMemoryUnit, InternalGasPerArg, InternalGasPerByte, +}; +use move_vm_types::gas::SimpleInstruction; + +// see starcoin/vm/types/src/on_chain_config/genesis_gas_schedule.rs +// same order as https://github.com/starcoinorg/starcoin-framework/blob/main/sources/VMConfig.move#instruction_schedule +// modify should with impl From for GasSchedule +crate::params::define_gas_parameters!( + InstructionGasParameters, + "instr", + [ + [pop: InternalGas, "pop", (1 + 1)* MUL], + [ret: InternalGas, "ret", (638 + 1) * MUL], + [br_true: InternalGas, "br_true", (1+1)* MUL], + [br_false: InternalGas, "br_false", (1 + 1) * MUL], + [branch: InternalGas, "branch", (1 + 1)* MUL], + [ld_u64: InternalGas, "ld_u64", (1 + 1)* MUL], + [ + ld_const_per_byte: InternalGasPerByte, + "ld_const.per_byte", + (1 + 1) * MUL + ], + [ld_true: InternalGas, "ld_true", (1 + 1)* MUL], + [ld_false: InternalGas, "ld_false", (1 + 1)* MUL], + [ + copy_loc_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "copy_loc.per_abs_mem_unit", + (1 + 1) * MUL + ], + [move_loc_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, "move_loc.per_abs_mem_unit", (1 + 1)* MUL], + [st_loc_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, "st_loc.per_abs_mem_unit", (1 + 1)* MUL], + [mut_borrow_loc: InternalGas, "mut_borrow_loc", (2 + 1) * MUL], + [imm_borrow_loc: InternalGas, "imm_borrow_loc", (1 + 1)* MUL], + [mut_borrow_field: InternalGas, "mut_borrow_field", (1 + 1)* MUL], + [imm_borrow_field: InternalGas, "imm_borrow_field", (1 + 1)* MUL], + [call_per_arg: InternalGasPerArg, "call.per_arg", (1132 + 1) * MUL], + [pack_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, "pack.per_abs_mem_unit", (2 + 1) * MUL], + [unpack_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, "unpack.per_abs_mem_unit", (2 + 1) * MUL], + [ + read_ref_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "read_ref.per_abs_mem_unit", + (1 + 1) * MUL + ], + [write_ref_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, "write_ref.per_abs_mem_unit", (1 + 1)* MUL], + [add: InternalGas, "add", (1 + 1)* MUL], + [sub: InternalGas, "sub", (1 + 1)* MUL], + [mul: InternalGas, "mul", (1 + 1)* MUL], + [mod_: InternalGas, "mod", (1 + 1)* MUL], + [div: InternalGas, "div", (3 + 1) * MUL], + [bit_or: InternalGas, "bit_or", (2 + 1) * MUL], + [bit_and: InternalGas, "bit_and", (2 + 1) * MUL], + [xor: InternalGas, "xor", (1 + 1)* MUL], + [or: InternalGas, "or", (2 + 1) * MUL], + [and: InternalGas, "and", (1 + 1)* MUL], + [not: InternalGas, "not", (1 + 1)* MUL], + [ + eq_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "eq.per_abs_mem_unit", + (1 + 1) * MUL + ], + [ + neq_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "neq.per_abs_mem_unit", + (1 + 1) * MUL + ], + // comparison + [lt: InternalGas, "lt", (2 + 1) * MUL], + [gt: InternalGas, "gt", (1 + 1)* MUL], + [le: InternalGas, "le", (2 + 1) * MUL], + [ge: InternalGas, "ge", (1 + 1)* MUL], + [abort: InternalGas, "abort", (1 + 1)* MUL], + // nop + [nop: InternalGas, "nop", (1 + 1)* MUL], + [exists_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, "exists.per_abs_mem_unit", (41 + 1) * MUL], + [ + mut_borrow_global_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "mut_borrow_global.per_abs_mem_unit", + (21 + 1) * MUL + ], + [ + imm_borrow_global_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "imm_borrow_global.per_abs_mem_unit", + (23 + 1) * MUL + ], + [move_from_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, "move_from.per_abs_mem_unit", (459 + 1) * MUL], + [move_to_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, "move_to.per_abs_mem_unit", (13 + 1) * MUL], + [freeze_ref: InternalGas, "freeze_ref", (1 + 1)* MUL], + [shl: InternalGas, "shl", (2 + 1) * MUL], + [shr: InternalGas, "shr", (1 + 1)* MUL], + [ld_u8: InternalGas, "ld_u8", (1 + 1)* MUL], + [ld_u128: InternalGas, "ld_u128", (1 + 1)* MUL], + // casting + [cast_u8: InternalGas, "cast_u8", (2 + 1) * MUL], + [cast_u64: InternalGas, "cast_u64", (1 + 1)* MUL], + [cast_u128: InternalGas, "cast_u128", (1 + 1)* MUL], + [ + mut_borrow_field_generic: InternalGas, + "mut_borrow_field_generic.base", + (1 + 1)* MUL + ], + [ + imm_borrow_field_generic: InternalGas, + "imm_borrow_field_generic.base", + (1 + 1)* MUL + ], + [ + call_generic_per_arg: InternalGasPerArg, + "call_generic.per_arg", + (582 + 1) * MUL + ], + [ + pack_generic_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "pack_generic.per_abs_mem_unit", + (2 + 1) * MUL + ], + [ + unpack_generic_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "unpack_generic.per_abs_mem_unit", + (2 + 1) * MUL + ], + [ + exists_generic_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "exists_generic.per_abs_mem_unit", + (34 + 1) * MUL + ], + [ + mut_borrow_global_generic_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "mut_borrow_global_generic.per_abs_mem_unit", + (15 + 1) * MUL + ], + [ + imm_borrow_global_generic_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "imm_borrow_global_generic.per_abs_mem_unit", + (14 + 1) * MUL + ], + [ + move_from_generic_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "move_from_generic.per_abs_mem_unit", + (13 + 1) * MUL + ], + [ + move_to_generic_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + "move_to_generic.per_abs_mem_unit", + (27 + 1) * MUL + ], + [ + vec_pack_per_elem: InternalGasPerArg, + optional "vec_pack.per_elem", + (84 + 1) * MUL + ], + [vec_len_base: InternalGas, optional "vec_len.base", (98 + 1) * MUL], + [ + vec_imm_borrow_base: InternalGas, + optional "vec_imm_borrow.base", + (1334 + 1) * MUL + ], + [ + vec_mut_borrow_base: InternalGas, + optional "vec_mut_borrow.base", + (1902 + 1) * MUL + ], + [ + vec_push_back_per_abs_mem_unit: InternalGasPerAbstractMemoryUnit, + optional "vec_push_back.per_abs_mem_unit", + (52 + 1) * MUL + ], + [ + vec_pop_back_base: InternalGas, + optional "vec_pop_back.base", + (227 + 1) * MUL + ], + [ + vec_unpack_per_expected_elem: InternalGasPerArg, + optional "vec_unpack.per_expected_elem", + (572 + 1) * MUL + ], + [vec_swap_base: InternalGas, optional "vec_swap.base", (1436 + 1) * MUL], + // XXX FIXME YSG, check v6 bytecode cost + [cast_u16: InternalGas, "cast_u16", (2 + 1) * MUL], + [cast_u32: InternalGas, "cast_u32", (1 + 1)* MUL], + [cast_u256: InternalGas, "cast_u256", (2 + 1)* MUL], + [ld_u16: InternalGas, "ld_u16", (2 + 1) * MUL], + [ld_u32: InternalGas, "ld_u32", (1 + 1)* MUL], + [ld_u256: InternalGas, "ld_u256", (2 + 1)* MUL], + ] +); + +impl InstructionGasParameters { + pub fn simple_instr_cost(&self, instr: SimpleInstruction) -> PartialVMResult { + Ok(match instr { + SimpleInstruction::Nop => self.nop, + + SimpleInstruction::Abort => self.abort, + SimpleInstruction::Ret => self.ret, + + SimpleInstruction::BrTrue => self.br_true, + SimpleInstruction::BrFalse => self.br_false, + SimpleInstruction::Branch => self.branch, + + SimpleInstruction::LdU8 => self.ld_u8, + SimpleInstruction::LdU64 => self.ld_u64, + SimpleInstruction::LdU128 => self.ld_u128, + SimpleInstruction::LdTrue => self.ld_true, + SimpleInstruction::LdFalse => self.ld_false, + + SimpleInstruction::ImmBorrowLoc => self.imm_borrow_loc, + SimpleInstruction::MutBorrowLoc => self.mut_borrow_loc, + SimpleInstruction::ImmBorrowField => self.imm_borrow_field, + SimpleInstruction::MutBorrowField => self.mut_borrow_field, + SimpleInstruction::ImmBorrowFieldGeneric => self.imm_borrow_field_generic, + SimpleInstruction::MutBorrowFieldGeneric => self.mut_borrow_field_generic, + SimpleInstruction::FreezeRef => self.freeze_ref, + + SimpleInstruction::CastU8 => self.cast_u8, + SimpleInstruction::CastU64 => self.cast_u64, + SimpleInstruction::CastU128 => self.cast_u128, + + SimpleInstruction::Add => self.add, + SimpleInstruction::Sub => self.sub, + SimpleInstruction::Mul => self.mul, + SimpleInstruction::Mod => self.mod_, + SimpleInstruction::Div => self.div, + + SimpleInstruction::BitOr => self.bit_or, + SimpleInstruction::BitAnd => self.bit_and, + SimpleInstruction::Xor => self.xor, + SimpleInstruction::Shl => self.shl, + SimpleInstruction::Shr => self.shr, + + SimpleInstruction::Or => self.or, + SimpleInstruction::And => self.and, + SimpleInstruction::Not => self.not, + + SimpleInstruction::Lt => self.lt, + SimpleInstruction::Gt => self.gt, + SimpleInstruction::Le => self.le, + SimpleInstruction::Ge => self.ge, + + SimpleInstruction::LdU16 => self.ld_u16, + SimpleInstruction::LdU32 => self.ld_u32, + SimpleInstruction::LdU256 => self.ld_u256, + + SimpleInstruction::CastU16 => self.cast_u16, + SimpleInstruction::CastU32 => self.cast_u32, + SimpleInstruction::CastU256 => self.cast_u256, + }) + } +} diff --git a/vm/gas-algebra-ext/src/lib.rs b/vm/gas-algebra-ext/src/lib.rs new file mode 100644 index 0000000000..6c84ccf8be --- /dev/null +++ b/vm/gas-algebra-ext/src/lib.rs @@ -0,0 +1,83 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_core_types::gas_algebra::{Arg, GasQuantity, UnitDiv}; +pub use move_vm_test_utils::gas_schedule::GasCost; +use serde::{Deserialize, Serialize}; + +#[macro_use] +pub mod natives; + +#[macro_use] +pub mod params; + +mod algebra; +mod gas_meter; +mod starcoin_framework; +//pub mod gen; +mod instr; +mod move_stdlib; +mod nursery; +mod table; +mod transaction; + +pub use algebra::{FeePerGasUnit, Gas}; +pub use gas_meter::{FromOnChainGasSchedule, InitialGasSchedule, ToOnChainGasSchedule}; +pub use instr::InstructionGasParameters; +pub use transaction::TransactionGasParameters; + +/// Unit of abstract value size -- a conceptual measurement of the memory space a Move value occupies. +pub enum AbstractValueUnit {} + +pub type AbstractValueSize = GasQuantity; + +pub type AbstractValueSizePerArg = GasQuantity>; + +#[derive(Clone, Debug, Serialize, PartialEq, Eq, Deserialize)] +pub struct GasConstants { + /// The cost per-byte read from global storage. + pub global_memory_per_byte_cost: u64, + + /// The cost per-byte written to storage. + pub global_memory_per_byte_write_cost: u64, + + /// The flat minimum amount of gas required for any transaction. + /// Charged at the start of execution. + pub min_transaction_gas_units: u64, + + /// Any transaction over this size will be charged an additional amount per byte. + pub large_transaction_cutoff: u64, + + /// The units of gas that to be charged per byte over the `large_transaction_cutoff` in addition to + /// `min_transaction_gas_units` for transactions whose size exceeds `large_transaction_cutoff`. + pub intrinsic_gas_per_byte: u64, + + /// ~5 microseconds should equal one unit of computational gas. We bound the maximum + /// computational time of any given transaction at roughly 20 seconds. We want this number and + /// `MAX_PRICE_PER_GAS_UNIT` to always satisfy the inequality that + /// MAXIMUM_NUMBER_OF_GAS_UNITS * MAX_PRICE_PER_GAS_UNIT < min(u64::MAX, GasUnits::MAX) + /// NB: The bound is set quite high since custom scripts aren't allowed except from predefined + /// and vetted senders. + pub maximum_number_of_gas_units: u64, + + /// The minimum gas price that a transaction can be submitted with. + pub min_price_per_gas_unit: u64, + + /// The maximum gas unit price that a transaction can be submitted with. + pub max_price_per_gas_unit: u64, + + pub max_transaction_size_in_bytes: u64, + + pub gas_unit_scaling_factor: u64, + pub default_account_size: u64, +} + +/// The cost tables, keyed by the serialized form of the bytecode instruction. We use the +/// serialized form as opposed to the instruction enum itself as the key since this will be the +/// on-chain representation of bytecode instructions in the future. +#[derive(Clone, Debug, Serialize, PartialEq, Eq, Deserialize)] +pub struct CostTable { + pub instruction_table: Vec, + pub native_table: Vec, + pub gas_constants: GasConstants, +} diff --git a/vm/gas-algebra-ext/src/move_stdlib.rs b/vm/gas-algebra-ext/src/move_stdlib.rs new file mode 100644 index 0000000000..35dc5c392c --- /dev/null +++ b/vm/gas-algebra-ext/src/move_stdlib.rs @@ -0,0 +1,52 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::gas_meter::EXECUTION_GAS_MULTIPLIER as MUL; +use move_stdlib::natives::GasParameters; + +// see starcoin/vm/types/src/on_chain_config/genesis_gas_schedule.rs +// same order as https://github.com/starcoinorg/starcoin-framework/blob/main/sources/VMConfig.move#native_schedule +// modify should with impl From for GasSchedule +crate::natives::define_gas_parameters_for_natives!(GasParameters, "move_stdlib", [ + + + // [.hash.sha2_256.base, "hash.sha2_256.base", 0 * MUL], + [.hash.sha2_256.per_byte, "hash.sha2_256.per_byte", (21 + 1) * MUL], + [.hash.sha2_256.legacy_min_input_len, "hash.sha2_256.legacy_min_input_len", MUL], + // [.hash.sha3_256.base, "hash.sha3_256.base", 0 * MUL], + [.hash.sha3_256.per_byte, "hash.sha3_256.per_byte", (64 + 1) * MUL], + [.hash.sha3_256.legacy_min_input_len, "hash.sha3_256.legacy_min_input_len", MUL], + + [.bcs.to_bytes.per_byte_serialized, "bcs.to_bytes.per_byte_serialized", (181 + 1) * MUL], + [.bcs.to_bytes.failure, "bcs.to_bytes.failure", (181 + 1) * MUL], + [.bcs.to_bytes.legacy_min_output_size, "bcs.to_bytes.legacy_min_output_size", MUL], + + [.vector.length.base, "vector.length.base", (98 + 1) * MUL], + [.vector.empty.base, "vector.empty.base", (84 + 1) * MUL], + [.vector.borrow.base, "vector.borrow.base", (1334 + 1) * MUL], + // [.vector.push_back.base, "vector.push_back.base", 0 * MUL], + [.vector.push_back.legacy_per_abstract_memory_unit, "vector.push_back.legacy_per_abstract_memory_unit", (53 + 1) * MUL], + [.vector.pop_back.base, "vector.pop_back.base", (227 + 1) * MUL], + [.vector.destroy_empty.base, "vector.destroy_empty.base", (572 + 1) * MUL], + [.vector.swap.base, "vector.swap.base", (1436 + 1) * MUL], + + // Note(Gas): this initial value is guesswork. + [.signer.borrow_address.base, "signer.borrow_address.base", (353 + 1) * MUL], + // [.bcs.to_address.base, "bcs.to_address.base", 0 * MUL], + [.bcs.to_address.per_byte, "bcs.to_address.per_byte", (26 + 1) *MUL], + + //[.vector.append.base, optional "vector.append.base", 0 * MUL], + [.vector.append.legacy_per_abstract_memory_unit, optional "vector.append.legacy_per_abstract_memory_unit", (40 + 1) * MUL], + //[.vector.remove.base, optional "vector.remove.base", 0 * MUL], + [.vector.remove.legacy_per_abstract_memory_unit, optional "vector.remove.legacy_per_abstract_memory_unit", (20 + 1) * MUL], + //[.vector.reverse.base, optional "vector.reverse.base", 0 * MUL], + [.vector.reverse.legacy_per_abstract_memory_unit, optional "vector.reverse.legacy_per_abstract_memory_unit", (10 + 1) * MUL], + // Note(Gas): these initial values are guesswork. + // [.string.check_utf8.base, optional "string.check_utf8.base", 0 * MUL], + [.string.check_utf8.per_byte, optional "string.check_utf8.per_byte", (4 + 1) * MUL], + [.string.is_char_boundary.base, optional "string.is_char_boundary.base", (4 + 1) * MUL], + // [.string.sub_string.base, optional "string.sub_string.base", 0 * MUL], + [.string.sub_string.per_byte, optional "string.sub_string.per_byte", (4 + 1) * MUL], + // [.string.index_of.base, optional "string.index_of.base", 0 * MUL], + [.string.index_of.per_byte_searched, optional "string.index_of.per_byte_searched", (4 + 1) * MUL], +], allow_unmapped = 2 /* bcs */ + 2 /* hash */ + 4 /* vector */ + 3 /* string*/ + 4 /* XXX FIXME YSG for nextest*/); diff --git a/vm/gas-algebra-ext/src/natives.rs b/vm/gas-algebra-ext/src/natives.rs new file mode 100644 index 0000000000..664128179b --- /dev/null +++ b/vm/gas-algebra-ext/src/natives.rs @@ -0,0 +1,212 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module defines some macros to help implement the mapping between the on-chain gas schedule +//! and its rust representation. + +macro_rules! expand_get_impl_for_native_gas_params { + ($params: ident $(.$field: ident)+, $map: ident, $prefix: literal, optional $key: literal) => { + if let Some(val) = $map.get(&format!("{}.{}", $prefix, $key)) { + $params $(.$field)+ = (*val).into(); + } + }; + ($params: ident $(.$field: ident)+, $map: ident, $prefix: literal, $key: literal) => { + $params $(.$field)+ = $map.get(&format!("{}.{}", $prefix, $key)).cloned()?.into(); + }; +} + +macro_rules! expand_get_for_native_gas_params { + (test_only $(.$field: ident)+, $(optional $($dummy: ident)?)? $key: literal, $initial_val: expr, $param_ty: ty, $package_name: literal, $params: ident, $gas_schedule: ident) => { + // TODO(Gas): this is a hack to work-around issue + // https://github.com/rust-lang/rust/issues/15701 + { + #[cfg(feature = "testing")] + fn assign(params: &mut $param_ty, gas_schedule: &std::collections::BTreeMap) -> Option<()> { + $crate::natives::expand_get_impl_for_native_gas_params!(params $(.$field)+, gas_schedule, $package_name, $(optional $($dummy)?)? $key); + Some(()) + } + + #[cfg(not(feature = "testing"))] + fn assign(_params: &mut $param_ty, _gas_schedule: &std::collections::BTreeMap) -> Option<()> { + Some(()) + } + + assign(&mut $params, &$gas_schedule)?; + } + }; + ($(.$field: ident)+, $(optional $($dummy: ident)?)? $key: literal, $initial_val: expr, $param_ty: ty, $package_name: literal, $params: ident, $gas_schedule: ident) => { + $crate::natives::expand_get_impl_for_native_gas_params!($params $(.$field)+, $gas_schedule, $package_name, $(optional $($dummy)?)? $key); + } +} + +macro_rules! expand_set_for_native_gas_params { + (test_only $(.$field: ident)+, $(optional)? $key: literal, $initial_val: expr, $param_ty: ty, $package_name: literal, $params: ident) => { + { + #[cfg(feature = "testing")] + fn assign(params: &mut $param_ty) { + params $(.$field)+ = $initial_val.into(); + } + + #[cfg(not(feature = "testing"))] + fn assign(_params: &mut $param_ty) { + } + + assign(&mut $params); + } + }; + ($(.$field: ident)+, $(optional)? $key: literal, $initial_val: expr, $param_ty: ty, $package_name: literal, $params: ident) => { + $params $(.$field)+ = $initial_val.into() + }; +} + +macro_rules! expand_kv_for_native_gas_params { + (test_only $(.$field: ident)+, $(optional)? $key: literal, $initial_val: expr, $self: ident) => { + #[cfg(feature = "testing")] + ($key, u64::from($self $(.$field)+)) + }; + ($(.$field: ident)+, $(optional)? $key: literal, $initial_val: expr, $self: ident) => { + ($key, u64::from($self $(.$field)+)) + } +} + +#[cfg(test)] +macro_rules! extract_key_for_native_gas_params { + (test_only $(.$field: ident)+, $(optional)? $key: literal, $initial_val: expr) => { + #[cfg(feature = "testing")] + $key + }; + ($(.$field: ident)+, $(optional)? $key: literal, $initial_val: expr) => { + $key + }; +} + +#[cfg(test)] +macro_rules! extract_path_for_native_gas_params { + (test_only $(.$field: ident)+, $(optional)? $key: literal, $initial_val: expr) => { + #[cfg(feature = "testing")] + stringify!($($field).*) + }; + ($(.$field: ident)+, $(optional)? $key: literal, $initial_val: expr) => { + stringify!($($field).*) + }; +} + +macro_rules! define_gas_parameters_for_natives { + ($param_ty: ty, $package_name: literal, [$([$($t: tt)*]),* $(,)?] $(, allow_unmapped = $allow_unmapped: expr)?) => { + impl crate::gas_meter::FromOnChainGasSchedule for $param_ty { + fn from_on_chain_gas_schedule(gas_schedule: &std::collections::BTreeMap) -> Option { + let mut params = <$param_ty>::zeros(); + + $( + crate::natives::expand_get_for_native_gas_params!($($t)*, $param_ty, $package_name, params, gas_schedule); + )* + + Some(params) + } + } + + impl crate::gas_meter::ToOnChainGasSchedule for $param_ty { + fn to_on_chain_gas_schedule(&self) -> Vec<(String, u64)> { + [$(crate::natives::expand_kv_for_native_gas_params!($($t)*, self)),*] + .into_iter().map(|(key, val)| (format!("{}.{}", $package_name, key), val)).collect() + } + } + + impl crate::gas_meter::InitialGasSchedule for $param_ty { + fn initial() -> Self { + let mut params = <$param_ty>::zeros(); + + $( + crate::natives::expand_set_for_native_gas_params!($($t)*, $param_ty, $package_name, params); + )* + + params + } + } + + #[test] + fn keys_should_be_unique() { + let mut map = std::collections::BTreeMap::<&str, ()>::new(); + + for key in [$(crate::natives::extract_key_for_native_gas_params!($($t)*)),*] { + if map.insert(key.clone(), ()).is_some() { + panic!("duplicated key {}", key); + } + } + } + + #[test] + fn paths_must_be_unique() { + let mut map = std::collections::BTreeMap::<&str, ()>::new(); + + for path in [$(crate::natives::extract_path_for_native_gas_params!($($t)*)),*] { + if map.insert(path.clone(), ()).is_some() { + panic!("duplicated path {}", path); + } + } + } + + #[test] + fn all_parameters_mapped() { + let total = format!("{:?}", &<$param_ty>::zeros()).matches(": 0").count(); + let mapped = [$(crate::natives::extract_key_for_native_gas_params!($($t)*)),*].len() $(+ $allow_unmapped)?; + if mapped != total { + panic!("only {} out of the {} entries are mapped", mapped, total) + } + } + }; +} + +pub(crate) use define_gas_parameters_for_natives; +pub(crate) use expand_get_for_native_gas_params; +pub(crate) use expand_get_impl_for_native_gas_params; +pub(crate) use expand_kv_for_native_gas_params; +pub(crate) use expand_set_for_native_gas_params; + +#[cfg(test)] +pub(crate) use extract_key_for_native_gas_params; +#[cfg(test)] +pub(crate) use extract_path_for_native_gas_params; + +#[cfg(test)] +mod tests { + use super::*; + use crate::gas_meter::FromOnChainGasSchedule; + use move_core_types::gas_algebra::InternalGas; + + #[derive(Debug, Clone)] + struct GasParameters { + pub foo: InternalGas, + pub bar: InternalGas, + } + + impl GasParameters { + pub fn zeros() -> Self { + Self { + foo: 0.into(), + bar: 0.into(), + } + } + } + + define_gas_parameters_for_natives!( + GasParameters, + "test", + [[.foo, "foo", 0], [.bar, optional "bar", 0]] + ); + + #[test] + fn optional_should_be_honored() { + assert!(matches!( + GasParameters::from_on_chain_gas_schedule( + &[("test.foo".to_string(), 0)].into_iter().collect(), + ), + Some(_) + )); + + assert!(matches!( + GasParameters::from_on_chain_gas_schedule(&[].into_iter().collect()), + None + )); + } +} diff --git a/vm/gas-algebra-ext/src/nursery.rs b/vm/gas-algebra-ext/src/nursery.rs new file mode 100644 index 0000000000..33e6f624bd --- /dev/null +++ b/vm/gas-algebra-ext/src/nursery.rs @@ -0,0 +1,10 @@ +use crate::gas_meter::EXECUTION_GAS_MULTIPLIER as MUL; +use move_stdlib::natives::NurseryGasParameters; + +// see starcoin/vm/types/src/on_chain_config/genesis_gas_schedule.rs +// convert from https://github.com/starcoinorg/starcoin-framework/blob/main/sources/VMConfig.move#native_schedule +crate::natives::define_gas_parameters_for_natives!(NurseryGasParameters, "nursery", [ + [.event.write_to_event_store.unit_cost, "event.write_to_event_store.unit_cost", (52 + 1) * MUL], + [.debug.print.base_cost, optional "debug.print.base_cost", MUL], + [.debug.print_stack_trace.base_cost, optional "debug.print_stack_trace.base_cost", MUL], +]); diff --git a/vm/gas-algebra-ext/src/params.rs b/vm/gas-algebra-ext/src/params.rs new file mode 100644 index 0000000000..872a96ee7e --- /dev/null +++ b/vm/gas-algebra-ext/src/params.rs @@ -0,0 +1,105 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +macro_rules! expand_get_for_gas_parameters { + ($params: ident . $name: ident, $map: ident, $prefix: literal, optional $key: literal) => { + if let Some(val) = $map.get(&format!("{}.{}", $prefix, $key)) { + $params.$name = (*val).into(); + } + }; + ($params: ident . $name: ident, $map: ident, $prefix: literal, $key: literal) => { + $params.$name = $map.get(&format!("{}.{}", $prefix, $key)).cloned()?.into(); + }; +} + +macro_rules! define_gas_parameters { + ( + $params_name: ident, + $prefix: literal, + [$( + [$name: ident: $ty: ty, $(optional $($dummy: ident)?)? $key: literal $(,)?, $initial: expr $(,)?] + ),* $(,)?] + ) => { + #[derive(Debug, Clone)] + pub struct $params_name { + $(pub $name : $ty),* + } + + impl $crate::gas_meter::FromOnChainGasSchedule for $params_name { + fn from_on_chain_gas_schedule(gas_schedule: &std::collections::BTreeMap) -> Option { + let mut params = $params_name::zeros(); + + $( + $crate::params::expand_get_for_gas_parameters!(params . $name, gas_schedule, $prefix, $(optional $($dummy)?)? $key); + )* + + Some(params) + } + } + + impl $crate::gas_meter::ToOnChainGasSchedule for $params_name { + fn to_on_chain_gas_schedule(&self) -> Vec<(String, u64)> { + vec![$((format!("{}.{}", $prefix, $key), self.$name.into())),*] + } + } + + impl $params_name { + pub fn zeros() -> Self { + Self { + $($name: 0.into()),* + } + } + } + + impl $crate::gas_meter::InitialGasSchedule for $params_name { + fn initial() -> Self { + Self { + $($name: $initial.into()),* + } + } + } + + #[test] + fn keys_should_be_unique() { + let mut map = std::collections::BTreeMap::<&str, ()>::new(); + + for key in [$($key),*] { + assert!(map.insert(key, ()).is_none()); + } + } + }; +} + +pub(crate) use define_gas_parameters; +pub(crate) use expand_get_for_gas_parameters; + +#[cfg(test)] +mod tests { + use crate::gas_meter::FromOnChainGasSchedule; + + use super::*; + use move_core_types::gas_algebra::InternalGas; + + define_gas_parameters!( + GasParameters, + "test", + [[foo: InternalGas, "foo", 0], [bar: InternalGas, optional "bar", 0]] + ); + + #[test] + fn optional_should_be_honored() { + assert!( + matches!( + GasParameters::from_on_chain_gas_schedule( + &[("test.foo".to_string(), 0)].into_iter().collect(), + ), + Some(_) + ) + ); + + assert!(matches!( + GasParameters::from_on_chain_gas_schedule(&[].into_iter().collect()), + None + )); + } +} diff --git a/vm/gas-algebra-ext/src/starcoin_framework.rs b/vm/gas-algebra-ext/src/starcoin_framework.rs new file mode 100644 index 0000000000..5cb03b57ec --- /dev/null +++ b/vm/gas-algebra-ext/src/starcoin_framework.rs @@ -0,0 +1,36 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::gas_meter::EXECUTION_GAS_MULTIPLIER as MUL; +use starcoin_natives::GasParameters; + +// see starcoin/vm/types/src/on_chain_config/genesis_gas_schedule.rs +// same order as from https://github.com/starcoinorg/starcoin-framework/blob/main/sources/VMConfig.move#native_schedule +// modify should with impl From for GasSchedule +crate::natives::define_gas_parameters_for_natives!(GasParameters, "starcoin_natives", [ + // [.signature.ed25519_verify.base, "signature.ed25519_verify.base", 0 * MUL], + [.signature.ed25519_verify.per_byte, "signature.ed25519_verify.per_byte", (61 + 1)* MUL], + // [.signature.ed25519_validate_key.base, "signature.ed25519_validate_key.base", 0 * MUL], + [.signature.ed25519_validate_key.per_byte, optional "signature.ed25519_validate_key.per_byte",(26 + 1) * MUL], + + [.account.create_signer.base, "account.create_signer.base", (24 + 1) * MUL], + [.account.destroy_signer.base, "account.destroy_signer.base", (212 + 1)* MUL], + + [.token.name_of.base, "token.name_of.base", (2002 + 1) * MUL], + + // [.hash.keccak256.base, optional "hash.keccak256.base", 0 * MUL], + [.hash.keccak256.per_byte, optional "hash.keccak256.per_byte", (64 + 1) *MUL], + // [.hash.ripemd160.base, optional "hash.ripemd160.base", 0 * MUL], + [.hash.ripemd160.per_byte, optional "hash.ripemd160.per_byte", (64 + 1) * MUL], + // [.signature.ec_recover.base, optional "signature.ec_recover.base", 0 * MUL], + [.signature.ec_recover.per_byte, optional "signature.ec_recover.per_byte", (128 + 1) * MUL], + + //[.u256.from_bytes.base, optional "u256.from_bytes.base", 0 * MUL], + [.u256.from_bytes.per_byte, optional "u256.from_bytes.per_byte", (2 + 1) * MUL], + [.u256.add.base, optional "u256.add.base", (4 + 1) * MUL], + [.u256.sub.base, optional "u256.sub.base", (4 + 1) * MUL], + [.u256.mul.base, optional "u256.mul.base", (4 + 1) * MUL], + [.u256.div.base, optional "u256.div.base", (10 + 1) * MUL], + [.u256.rem.base, optional "u256.rem.base", (4 + 1) * MUL], + [.u256.pow.base, optional "u256.pow.base", (8 + 1) * MUL], +], allow_unmapped = 3 /* signature */ + 2 /* hash */ + 1 /* u256 */); diff --git a/vm/gas-algebra-ext/src/table.rs b/vm/gas-algebra-ext/src/table.rs new file mode 100644 index 0000000000..8b3a3a09ac --- /dev/null +++ b/vm/gas-algebra-ext/src/table.rs @@ -0,0 +1,27 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::gas_meter::EXECUTION_GAS_MULTIPLIER as MUL; +use move_table_extension::GasParameters; + +// same order as from https://github.com/starcoinorg/starcoin-framework/blob/main/sources/VMConfig.move#native_schedule +// modify should with impl From for GasSchedule +crate::natives::define_gas_parameters_for_natives!(GasParameters, "table", [ + // Note(Gas): These are legacy parameters for loading from storage so they do not + // need to be multiplied. + + [.new_table_handle.base, optional "new_table_handle.base", (4 + 1) * MUL], + + [.add_box.per_byte_serialized, optional "add_box.per_byte_serialized", (4 + 1) * MUL], + + [.borrow_box.per_byte_serialized, optional "borrow_box.per_byte_serialized", (10 + 1) * MUL], + + [.remove_box.per_byte_serialized, optional "remove_box.per_byte_serialized", (8 + 1) * MUL], + + [.contains_box.per_byte_serialized, optional "contains_box.per_byte_serialized", (40 + 1) * MUL], + + + [.destroy_empty_box.base, optional "destroy_empty_box.base", (20 + 1) * MUL], + + [.drop_unchecked_box.base, optional "drop_unchecked_box.base", (73 + 1) * MUL], +], allow_unmapped = 4 /* table */ + 3 /* common */); diff --git a/vm/gas-algebra-ext/src/transaction.rs b/vm/gas-algebra-ext/src/transaction.rs new file mode 100644 index 0000000000..e8e06d1552 --- /dev/null +++ b/vm/gas-algebra-ext/src/transaction.rs @@ -0,0 +1,129 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module defines all the gas parameters for transactions, along with their initial values +//! in the genesis and a mapping between the Rust representation and the on-chain gas schedule. + +use crate::algebra::{FeePerGasUnit, Gas, GasScalingFactor, GasUnit}; +use move_core_types::gas_algebra::{ + InternalGas, InternalGasPerByte, InternalGasUnit, NumBytes, ToUnitFractionalWithParams, + ToUnitWithParams, +}; +// see starcoin/config/src/genesis_config.rs G_GAS_CONSTANTS_V2 +// convert from https://github.com/starcoinorg/starcoin-framework/blob/main/sources/VMConfig.move#GasConstants +// modify should with impl From for GasSchedule +crate::params::define_gas_parameters!( + TransactionGasParameters, + "txn", + [ + [ + global_memory_per_byte_cost: InternalGasPerByte, + "global_memory_per_byte_cost", + 4 + ], + [ + global_memory_per_byte_write_cost: InternalGasPerByte, + "global_memory_per_byte_write_cost", + 9 + ], + // The flat minimum amount of gas required for any transaction. + // Charged at the start of execution. + [ + min_transaction_gas_units: InternalGas, + "min_transaction_gas_units", + 600 + ], + // Any transaction over this size will be charged an additional amount per byte. + [ + large_transaction_cutoff: NumBytes, + "large_transaction_cutoff", + 600 + ], + // The units of gas that to be charged per byte over the `large_transaction_cutoff` in addition to + // `min_transaction_gas_units` for transactions whose size exceeds `large_transaction_cutoff`. + [ + intrinsic_gas_per_byte: InternalGasPerByte, + "intrinsic_gas_per_byte", + 8 + ], + // ~5 microseconds should equal one unit of computational gas. We bound the maximum + // computational time of any given transaction at roughly 20 seconds. We want this number and + // `MAX_PRICE_PER_GAS_UNIT` to always satisfy the inequality that + // MAXIMUM_NUMBER_OF_GAS_UNITS * MAX_PRICE_PER_GAS_UNIT < min(u64::MAX, GasUnits::MAX) + [ + maximum_number_of_gas_units: Gas, + "maximum_number_of_gas_units", + 40_000_000 + ], + // The minimum gas price that a transaction can be submitted with. + // TODO(Gas): should probably change this to something > 0 + [ + min_price_per_gas_unit: FeePerGasUnit, + "min_price_per_gas_unit", + 1 + ], + // The maximum gas unit price that a transaction can be submitted with. + [ + max_price_per_gas_unit: FeePerGasUnit, + "max_price_per_gas_unit", + 10_000 + ], + [ + max_transaction_size_in_bytes: NumBytes, + "max_transaction_size_in_bytes", + 1024 * 128 + ], + [ + gas_unit_scaling_factor: GasScalingFactor, + "gas_unit_scaling_factor", + 1 + ], + // For V1 all accounts will be ~800 bytes + [default_account_size: NumBytes, "default_account_size", 800], + ] +); + +impl TransactionGasParameters { + // TODO(Gas): Right now we are relying on this to avoid div by zero errors when using the all-zero + // gas parameters. See if there's a better way we can handle this. + fn scaling_factor(&self) -> GasScalingFactor { + match u64::from(self.gas_unit_scaling_factor) { + 0 => 1.into(), + x => x.into(), + } + } + + /// Calculate the intrinsic gas for the transaction based upon its size in bytes. + pub fn calculate_intrinsic_gas(&self, transaction_size: NumBytes) -> InternalGas { + let min_transaction_fee = self.min_transaction_gas_units; + + if transaction_size > self.large_transaction_cutoff { + let excess = transaction_size + .checked_sub(self.large_transaction_cutoff) + .unwrap(); + min_transaction_fee + (excess * self.intrinsic_gas_per_byte) + } else { + min_transaction_fee + } + } + + pub fn cal_write_set_gas(&self) -> InternalGas { + self.global_memory_per_byte_write_cost * self.default_account_size + } +} + +impl ToUnitWithParams for GasUnit { + type Params = TransactionGasParameters; + + fn multiplier(params: &Self::Params) -> u64 { + params.scaling_factor().into() + } +} + +impl ToUnitFractionalWithParams for InternalGasUnit { + type Params = TransactionGasParameters; + + fn ratio(params: &Self::Params) -> (u64, u64) { + (1, params.scaling_factor().into()) + } +} diff --git a/vm/move-coverage/Cargo.toml b/vm/move-coverage/Cargo.toml index e671481232..f62f85f502 100644 --- a/vm/move-coverage/Cargo.toml +++ b/vm/move-coverage/Cargo.toml @@ -1,8 +1,8 @@ [dependencies] anyhow = { workspace = true } bcs = { workspace = true } -clap = { features = [ "derive",], workspace = true } -codespan = { features = [ "serialization",], workspace = true } +clap = { features = ["derive"], workspace = true } +codespan = { features = ["serialization"], workspace = true } colored = { workspace = true } petgraph = { workspace = true } serde = { default-features = false, workspace = true } diff --git a/vm/move-explain/Cargo.toml b/vm/move-explain/Cargo.toml index 26f6d75743..1bdeae9ff6 100644 --- a/vm/move-explain/Cargo.toml +++ b/vm/move-explain/Cargo.toml @@ -1,6 +1,6 @@ [dependencies] bcs-ext = { package = "bcs-ext", workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } move-core-types = { workspace = true } stdlib = { package = "stdlib", workspace = true } diff --git a/vm/move-explain/src/lib.rs b/vm/move-explain/src/lib.rs index e6819d381b..44f469ed8e 100644 --- a/vm/move-explain/src/lib.rs +++ b/vm/move-explain/src/lib.rs @@ -2,13 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 use move_core_types::{ - errmap::{ErrorContext, ErrorMapping}, + errmap::{ErrorDescription, ErrorMapping}, language_storage::ModuleId, }; /// Given the module ID and the abort code raised from that module, returns the human-readable /// explanation of that abort if possible. -pub fn get_explanation(module_id: &ModuleId, abort_code: u64) -> Option { +pub fn get_explanation(module_id: &ModuleId, abort_code: u64) -> Option { let error_descriptions: ErrorMapping = bcs_ext::from_bytes(stdlib::ERROR_DESCRIPTIONS).expect("Decode err map failed"); error_descriptions.get_explanation(module_id, abort_code) diff --git a/vm/move-explain/src/main.rs b/vm/move-explain/src/main.rs index 4f3eb808d7..9bb8fa8328 100644 --- a/vm/move-explain/src/main.rs +++ b/vm/move-explain/src/main.rs @@ -42,11 +42,8 @@ fn main() { args.location, args.abort_code ), Some(error_desc) => println!( - "Category:\n Name: {}\n Description: {}\nReason:\n Name: {}\n Description: {}", - error_desc.category.code_name, - error_desc.category.code_description, - error_desc.reason.code_name, - error_desc.reason.code_description, + "Category:\n Name: {}\n Description: {}", + error_desc.code_name, error_desc.code_description, ), } } diff --git a/vm/move-package-manager/Cargo.toml b/vm/move-package-manager/Cargo.toml index d126df53b3..3e2b57b1b6 100644 --- a/vm/move-package-manager/Cargo.toml +++ b/vm/move-package-manager/Cargo.toml @@ -5,19 +5,29 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } bcs = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } difference = { workspace = true } -include_dir = { features = [ "search",], workspace = true } +include_dir = { features = ["search"], workspace = true } itertools = { workspace = true } -jsonrpc-client-transports = { features = [ "http", "ipc", "ws", "arbitrary_precision",], workspace = true } -jsonrpc-core-client = { features = [ "http", "ipc", "ws", "arbitrary_precision",], workspace = true } +jsonrpc-client-transports = { features = [ + "http", + "ipc", + "ws", + "arbitrary_precision", +], workspace = true } +jsonrpc-core-client = { features = [ + "http", + "ipc", + "ws", + "arbitrary_precision", +], workspace = true } once_cell = { workspace = true } walkdir = { workspace = true } futures = { workspace = true } tempfile = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -datatest-stable = {git = "https://github.com/starcoinorg/diem-devtools", branch = "feature/pub-test-opts"} +datatest-stable = { git = "https://github.com/starcoinorg/diem-devtools", branch = "feature/pub-test-opts" } move-binary-format = { workspace = true } move-bytecode-verifier = { workspace = true } move-cli = { workspace = true } @@ -40,10 +50,11 @@ starcoin-rpc-api = { workspace = true } starcoin-rpc-client = { workspace = true } starcoin-transactional-test-harness = { workspace = true } starcoin-types = { workspace = true } -starcoin-vm-runtime = { features = [ "testing",], workspace = true } +starcoin-vm-runtime = { features = ["testing"], workspace = true } starcoin-vm-types = { workspace = true } stdlib = { workspace = true } vm-status-translator = { workspace = true } +move-vm-test-utils = { workspace = true } [dev-dependencies] diff --git a/vm/move-package-manager/src/compatibility_check_cmd.rs b/vm/move-package-manager/src/compatibility_check_cmd.rs index 185d58ba8a..61ca9b5e10 100644 --- a/vm/move-package-manager/src/compatibility_check_cmd.rs +++ b/vm/move-package-manager/src/compatibility_check_cmd.rs @@ -55,7 +55,7 @@ pub fn handle_compatibility_check( let remote_view = RemoteViewer::from_url(&rpc, cmd.block_number)?; let mut incompatible_module_ids = vec![]; - for m in pkg.modules()? { + for m in pkg.root_compiled_units.as_slice() { let m = module(&m.unit)?; let old_module = remote_view .get_module(&m.self_id()) @@ -63,7 +63,7 @@ pub fn handle_compatibility_check( if let Some(old) = old_module { let old_module = CompiledModule::deserialize(&old)?; let compatibility = check_compiled_module_compat(&old_module, m); - if !compatibility.is_fully_compatible() { + if compatibility.is_err() { incompatible_module_ids.push((m.self_id(), compatibility)); } } @@ -74,10 +74,8 @@ pub fn handle_compatibility_check( "Modules {} is incompatible with remote chain: {}!", incompatible_module_ids .into_iter() - .map(|(module_id, compat)| format!( - "{}(struct_layout:{},struct_and_function_linking:{})", - module_id, compat.struct_layout, compat.struct_and_function_linking - )) + // XXX FIXME YSG + .map(|(module_id, compat)| format!("{} {}", module_id, compat.is_err())) .join(","), &rpc ); @@ -92,7 +90,10 @@ pub fn handle_compatibility_check( return Ok(()); } - handle_pre_version_compatibility_check(cmd.pre_modules.unwrap(), pkg.modules()?.collect_vec())?; + handle_pre_version_compatibility_check( + cmd.pre_modules.unwrap(), + pkg.all_modules().collect_vec(), + )?; Ok(()) } @@ -129,9 +130,8 @@ fn handle_pre_version_compatibility_check( let new_module = module(&m.unit).unwrap(); let module_id = new_module.self_id(); if let Some(old_module) = pre_stable_modules.get(&module_id) { - let compatibility = - check_compiled_module_compat(old_module, new_module).is_fully_compatible(); - if !compatibility { + let compatibility = check_compiled_module_compat(old_module, new_module); + if compatibility.is_err() { Some(module_id) } else { None diff --git a/vm/move-package-manager/src/lib.rs b/vm/move-package-manager/src/lib.rs index 8ee015dcb6..029aa470d1 100644 --- a/vm/move-package-manager/src/lib.rs +++ b/vm/move-package-manager/src/lib.rs @@ -8,6 +8,7 @@ use move_command_line_common::testing::UPDATE_BASELINE; use move_compiler::command_line::compiler::construct_pre_compiled_lib_from_compiler; use move_compiler::diagnostics::report_diagnostics; use move_compiler::shared::unique_map::UniqueMap; +use move_compiler::shared::NamedAddressMaps; use move_compiler::{ cfgir, expansion, hlir, naming, parser, typing, Compiler, FullyCompiledProgram, }; @@ -22,6 +23,7 @@ use std::sync::Mutex; pub mod compatibility_check_cmd; pub mod deployment; +pub mod package; pub mod release; // use `integration-tests` rather than `tests`, for avoid conflict with `mpm package test` @@ -131,7 +133,8 @@ pub fn run_integration_test(move_arg: Move, cmd: IntegrationTestCommand) -> Resu let rerooted_path = { let path = &move_arg.package_path; // Always root ourselves to the package root, and then compile relative to that. - let rooted_path = SourcePackageLayout::try_find_root(&path.canonicalize()?)?; + let rooted_path = + SourcePackageLayout::try_find_root(&path.as_ref().unwrap().canonicalize()?)?; std::env::set_current_dir(&rooted_path).unwrap(); PathBuf::from(".") }; @@ -139,10 +142,12 @@ pub fn run_integration_test(move_arg: Move, cmd: IntegrationTestCommand) -> Resu // force move to rebuild all packages, so that we can use compile_driver to generate the full compiled program. let mut build_config = move_arg.build_config; build_config.force_recompilation = true; - let resolved_graph = build_config.resolution_graph_for_package(&rerooted_path)?; + let resolved_graph = + build_config.resolution_graph_for_package(&rerooted_path, &mut std::io::stdout())?; let mut pre_compiled_lib = FullyCompiledProgram { files: Default::default(), parser: parser::ast::Program { + named_address_maps: NamedAddressMaps::new(), source_definitions: vec![], lib_definitions: vec![], }, @@ -168,78 +173,79 @@ pub fn run_integration_test(move_arg: Move, cmd: IntegrationTestCommand) -> Resu }, compiled: vec![], }; - let compiled = BuildPlan::create(resolved_graph)? - .compile_with_driver( - &mut std::io::stdout(), - |compiler: Compiler, _is_root: bool| { - let full_program = match construct_pre_compiled_lib_from_compiler(compiler)? { - Ok(full_program) => full_program, - Err((file, s)) => report_diagnostics(&file, s), - }; - pre_compiled_lib.files.extend(full_program.files.clone()); - pre_compiled_lib - .parser - .lib_definitions - .extend(full_program.parser.source_definitions); - pre_compiled_lib.expansion.modules = - pre_compiled_lib.expansion.modules.union_with( - &full_program.expansion.modules.filter_map(|_k, v| { - if v.is_source_module { - Some(v) - } else { - None - } - }), - |_k, v1, _v2| v1.clone(), - ); - pre_compiled_lib.naming.modules = pre_compiled_lib.naming.modules.union_with( - &full_program.naming.modules.filter_map(|_k, v| { - if v.is_source_module { - Some(v) - } else { - None - } - }), - |_k, v1, _v2| v1.clone(), - ); - pre_compiled_lib.typing.modules = pre_compiled_lib.typing.modules.union_with( - &full_program.typing.modules.filter_map(|_k, v| { - if v.is_source_module { - Some(v) - } else { - None - } - }), - |_k, v1, _v2| v1.clone(), - ); - pre_compiled_lib.hlir.modules = pre_compiled_lib.hlir.modules.union_with( - &full_program.hlir.modules.filter_map(|_k, v| { - if v.is_source_module { - Some(v) - } else { - None - } - }), - |_k, v1, _v2| v1.clone(), - ); - pre_compiled_lib.cfgir.modules = pre_compiled_lib.cfgir.modules.union_with( - &full_program.cfgir.modules.filter_map(|_k, v| { - if v.is_source_module { - Some(v) - } else { - None - } - }), - |_k, v1, _v2| v1.clone(), - ); - pre_compiled_lib - .compiled - .extend(full_program.compiled.clone()); + let compiled = BuildPlan::create(resolved_graph)?.compile_with_driver( + &mut std::io::stdout(), + |compiler: Compiler| { + let full_program = match construct_pre_compiled_lib_from_compiler(compiler)? { + Ok(full_program) => full_program, + Err((file, s)) => report_diagnostics(&file, s), + }; + pre_compiled_lib.files.extend(full_program.files.clone()); + pre_compiled_lib + .parser + .source_definitions + .extend(full_program.parser.source_definitions); + pre_compiled_lib + .parser + .named_address_maps + .extend(&full_program.parser.named_address_maps); + pre_compiled_lib.expansion.modules = pre_compiled_lib.expansion.modules.union_with( + &full_program.expansion.modules.filter_map(|_k, v| { + if v.is_source_module { + Some(v) + } else { + None + } + }), + |_k, v1, _v2| v1.clone(), + ); + pre_compiled_lib.naming.modules = pre_compiled_lib.naming.modules.union_with( + &full_program.naming.modules.filter_map(|_k, v| { + if v.is_source_module { + Some(v) + } else { + None + } + }), + |_k, v1, _v2| v1.clone(), + ); + pre_compiled_lib.typing.modules = pre_compiled_lib.typing.modules.union_with( + &full_program.typing.modules.filter_map(|_k, v| { + if v.is_source_module { + Some(v) + } else { + None + } + }), + |_k, v1, _v2| v1.clone(), + ); + pre_compiled_lib.hlir.modules = pre_compiled_lib.hlir.modules.union_with( + &full_program.hlir.modules.filter_map(|_k, v| { + if v.is_source_module { + Some(v) + } else { + None + } + }), + |_k, v1, _v2| v1.clone(), + ); + pre_compiled_lib.cfgir.modules = pre_compiled_lib.cfgir.modules.union_with( + &full_program.cfgir.modules.filter_map(|_k, v| { + if v.is_source_module { + Some(v) + } else { + None + } + }), + |_k, v1, _v2| v1.clone(), + ); + pre_compiled_lib + .compiled + .extend(full_program.compiled.clone()); - Ok((full_program.files, full_program.compiled)) - }, - )? - .0; + Ok((full_program.files, full_program.compiled)) + }, + )?; (pre_compiled_lib, compiled) }; @@ -266,7 +272,6 @@ pub fn run_integration_test(move_arg: Move, cmd: IntegrationTestCommand) -> Resu eprintln!("No integration tests file in the dir `integration-tests`."); return Ok(()); } - *starcoin_transactional_test_harness::G_FLAG_RELOAD_STDLIB .lock() .unwrap() = cmd.current_as_stdlib; diff --git a/vm/move-package-manager/src/main.rs b/vm/move-package-manager/src/main.rs index a8272c123b..fa44932244 100644 --- a/vm/move-package-manager/src/main.rs +++ b/vm/move-package-manager/src/main.rs @@ -3,17 +3,20 @@ use anyhow::Result; use clap::Parser; -use move_cli::package::cli::handle_package_commands; -use move_cli::{experimental, package, sandbox, Move, DEFAULT_STORAGE_DIR}; +// use move_cli::package::cli::handle_package_commands; +use move_cli::{experimental, sandbox, Move, DEFAULT_STORAGE_DIR}; use move_core_types::errmap::ErrorMapping; use move_package_manager::compatibility_check_cmd::{ handle_compatibility_check, CompatibilityCheckCommand, }; use move_package_manager::deployment::{handle_deployment, DeploymentCommand}; +use move_package_manager::package::{handle_package_commands, PackageCommand}; use move_package_manager::release::{handle_release, Release}; use move_package_manager::{run_integration_test, IntegrationTestCommand}; +use move_vm_test_utils::gas_schedule::CostTable; +use starcoin_config::genesis_config::G_LATEST_GAS_PARAMS; use starcoin_vm_runtime::natives::starcoin_natives; -use starcoin_vm_types::gas_schedule::G_LATEST_GAS_SCHEDULE; +use starcoin_vm_types::on_chain_config::G_LATEST_INSTRUCTION_TABLE; use std::path::PathBuf; #[derive(Parser)] @@ -33,7 +36,7 @@ pub enum Commands { #[clap(name = "package")] Package { #[clap(subcommand)] - cmd: package::cli::PackageCommand, + cmd: PackageCommand, }, /// Release the package. #[clap(name = "release")] @@ -77,18 +80,17 @@ fn main() -> Result<()> { let args: CliOptions = CliOptions::parse(); let move_args = &args.move_args; - let natives = starcoin_natives(); + let gas_params = G_LATEST_GAS_PARAMS.clone(); + let natives = starcoin_natives(gas_params.natives); + let cost_table = CostTable { + instruction_table: G_LATEST_INSTRUCTION_TABLE.clone(), + }; match args.cmd { Commands::IntegrationTest(cmd) => run_integration_test(args.move_args, cmd), - Commands::Package { cmd } => handle_package_commands( - &move_args.package_path, - move_args.build_config.clone(), - &cmd, - natives, - ), + Commands::Package { cmd } => handle_package_commands(natives, args.move_args, cmd), Commands::Sandbox { storage_dir, cmd } => cmd.handle_command( natives, - &G_LATEST_GAS_SCHEDULE, + &cost_table, &error_descriptions, move_args, &storage_dir, diff --git a/vm/move-package-manager/src/package.rs b/vm/move-package-manager/src/package.rs new file mode 100644 index 0000000000..8c578cb224 --- /dev/null +++ b/vm/move-package-manager/src/package.rs @@ -0,0 +1,60 @@ +use clap::Parser; +use move_cli::base::{ + build::Build, coverage::Coverage, disassemble::Disassemble, errmap::Errmap, info::Info, + new::New, prove::Prove, test::Test, +}; +use move_cli::Move; +use move_vm_runtime::native_functions::NativeFunctionTable; + +#[derive(Parser)] +pub enum PackageCommand { + /// Create a new Move package with name `name` at `path`. If `path` is not provided the package + /// will be created in the directory `name`. + #[clap(name = "new")] + New(New), + /// Build the package at `path`. If no path is provided defaults to current directory. + #[clap(name = "build")] + Build(Build), + /// Print address information. + #[clap(name = "info")] + Info(Info), + /// Generate error map for the package and its dependencies at `path` for use by the Move + /// explanation tool. + #[clap(name = "errmap")] + Errmap(Errmap), + /// Run the Move Prover on the package at `path`. If no path is provided defaults to current + /// directory. Use `.. prove .. -- ` to pass on options to the prover. + #[clap(name = "prove")] + Prove(Prove), + /// Inspect test coverage for this package. A previous test run with the `--coverage` flag must + /// have previously been run. + #[clap(name = "coverage")] + Coverage(Coverage), + /// Run Move unit tests in this package. + #[clap(name = "test")] + Test(Test), + /// Disassemble the Move bytecode pointed to + #[clap(name = "disassemble")] + Disassemble(Disassemble), +} +pub fn handle_package_commands( + natives: NativeFunctionTable, + move_args: Move, + cmd: PackageCommand, +) -> anyhow::Result<()> { + match cmd { + PackageCommand::New(c) => c.execute_with_defaults(move_args.package_path), + PackageCommand::Build(c) => c.execute(move_args.package_path, move_args.build_config), + PackageCommand::Info(c) => c.execute(move_args.package_path, move_args.build_config), + PackageCommand::Errmap(c) => c.execute(move_args.package_path, move_args.build_config), + PackageCommand::Prove(c) => c.execute(move_args.package_path, move_args.build_config), + PackageCommand::Coverage(c) => c.execute(move_args.package_path, move_args.build_config), + PackageCommand::Test(c) => c.execute( + move_args.package_path, + move_args.build_config, + natives, + None, + ), + PackageCommand::Disassemble(c) => c.execute(move_args.package_path, move_args.build_config), + } +} diff --git a/vm/move-package-manager/src/release.rs b/vm/move-package-manager/src/release.rs index d5d6c5d58e..a7fef1d31c 100644 --- a/vm/move-package-manager/src/release.rs +++ b/vm/move-package-manager/src/release.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use clap::Parser; -use move_binary_format::file_format_common::VERSION_3; +use move_binary_format::file_format_common::VERSION_4; use move_binary_format::CompiledModule; use move_cli::sandbox::utils::PackageContext; use move_cli::Move; @@ -19,9 +19,10 @@ use std::path::PathBuf; pub const DEFAULT_RELEASE_DIR: &str = "release"; +// XXX FIXME YSG, mpm release use v4, v5, v6 #[derive(Parser)] pub struct Release { - #[clap(name = "move-version", long = "move-version", default_value="4", possible_values=&["3", "4"])] + #[clap(name = "move-version", long = "move-version", default_value="4", possible_values=&["4", "6"])] /// specify the move lang version for the release. /// currently, only v3, v4 are supported. language_version: u8, @@ -64,18 +65,22 @@ pub fn handle_release( let pkg_version = move_args .build_config .clone() - .resolution_graph_for_package(&move_args.package_path) + .resolution_graph_for_package( + move_args.package_path.as_ref().unwrap(), + &mut std::io::stdout(), + ) .unwrap() .root_package .package .version; let pkg_name = pkg.compiled_package_info.package_name.as_str(); println!("Packaging Modules:"); - for m in pkg.modules()? { + for m in pkg.root_compiled_units.as_slice() { let m = module(&m.unit)?; println!("\t {}", m.self_id()); - let code = if language_version as u32 == VERSION_3 { - ModuleBytecodeDowngrader::to_v3(m)? + // XXX FIXME YSG, mpm release + let code = if language_version as u32 == VERSION_4 { + ModuleBytecodeDowngrader::to_v4(m)? } else { let mut data = vec![]; m.serialize(&mut data)?; diff --git a/vm/move-prover/Cargo.toml b/vm/move-prover/Cargo.toml index ddbac5bbf4..f726ff0df4 100644 --- a/vm/move-prover/Cargo.toml +++ b/vm/move-prover/Cargo.toml @@ -17,14 +17,14 @@ once_cell = { workspace = true } shell-words = { workspace = true } tempfile = { workspace = true } walkdir = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } hex = { workspace = true } itertools = { workspace = true } log = { workspace = true } num = { workspace = true } pretty = { workspace = true } rand = { workspace = true } -serde = { features = [ "derive",], workspace = true } +serde = { features = ["derive"], workspace = true } serde_json = { workspace = true } simplelog = { workspace = true } toml = { workspace = true } diff --git a/vm/natives/Cargo.toml b/vm/natives/Cargo.toml index abc3943d4b..ec886976ab 100644 --- a/vm/natives/Cargo.toml +++ b/vm/natives/Cargo.toml @@ -16,8 +16,7 @@ ripemd160 = { workspace = true } smallvec = { workspace = true } starcoin-crypto = { workspace = true } starcoin-uint = { workspace = true } -starcoin-vm-types = { workspace = true } -tiny-keccak = { features = [ "keccak",], workspace = true } +tiny-keccak = { features = ["keccak"], workspace = true } walkdir = { workspace = true } [dev-dependencies] @@ -25,7 +24,7 @@ hex = { workspace = true } rand = { workspace = true } [features] -testing = [ "move-stdlib/testing",] +testing = ["move-stdlib/testing"] [package] authors = { workspace = true } diff --git a/vm/natives/src/account.rs b/vm/natives/src/account.rs index d9ff58d0ec..fd328053bd 100644 --- a/vm/natives/src/account.rs +++ b/vm/natives/src/account.rs @@ -3,19 +3,29 @@ use move_binary_format::errors::PartialVMResult; use move_core_types::account_address::AccountAddress; -use move_vm_runtime::native_functions::NativeContext; +use move_core_types::gas_algebra::InternalGas; +use move_vm_runtime::native_functions::{NativeContext, NativeFunction}; use move_vm_types::{ - loaded_data::runtime_types::Type, - natives::function::{native_gas, NativeResult}, - pop_arg, - values::Value, + loaded_data::runtime_types::Type, natives::function::NativeResult, pop_arg, values::Value, }; use smallvec::smallvec; -use starcoin_vm_types::gas_schedule::NativeCostIndex; use std::collections::VecDeque; +use std::sync::Arc; + +/*************************************************************************************************** + * native fun create_signer + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CreateSignerGasParameters { + pub base: InternalGas, +} pub fn native_create_signer( - context: &mut NativeContext, + gas_params: &CreateSignerGasParameters, + _context: &mut NativeContext, ty_args: Vec, mut arguments: VecDeque, ) -> PartialVMResult { @@ -23,28 +33,70 @@ pub fn native_create_signer( debug_assert!(arguments.len() == 1); let address = pop_arg!(arguments, AccountAddress); - let cost = native_gas( - context.cost_table(), - NativeCostIndex::CREATE_SIGNER as u8, - 0, - ); - Ok(NativeResult::ok(cost, smallvec![Value::signer(address)])) + Ok(NativeResult::ok( + gas_params.base, + smallvec![Value::signer(address)], + )) +} + +pub fn make_native_create_signer(gas_params: CreateSignerGasParameters) -> NativeFunction { + Arc::new(move |context, ty_args, args| { + native_create_signer(&gas_params, context, ty_args, args) + }) +} + +/*************************************************************************************************** + * native fun destroy_signer + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DestroySignerGasParameters { + pub base: InternalGas, } /// NOTE: this function will be deprecated after the Diem v3 release, but must /// remain for replaying old transactions pub fn native_destroy_signer( - context: &mut NativeContext, + gas_params: &DestroySignerGasParameters, + _context: &mut NativeContext, ty_args: Vec, arguments: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.is_empty()); debug_assert!(arguments.len() == 1); - let cost = native_gas( - context.cost_table(), - NativeCostIndex::DESTROY_SIGNER as u8, - 0, - ); - Ok(NativeResult::ok(cost, smallvec![])) + Ok(NativeResult::ok(gas_params.base, smallvec![])) +} + +pub fn make_native_destroy_signer(gas_params: DestroySignerGasParameters) -> NativeFunction { + Arc::new(move |context, ty_args, args| { + native_destroy_signer(&gas_params, context, ty_args, args) + }) +} + +/*************************************************************************************************** + * module + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GasParameters { + pub create_signer: CreateSignerGasParameters, + pub destroy_signer: DestroySignerGasParameters, +} + +pub fn make_all(gas_params: GasParameters) -> impl Iterator { + let natives = [ + ( + "create_signer", + make_native_create_signer(gas_params.create_signer), + ), + ( + "destroy_signer", + make_native_destroy_signer(gas_params.destroy_signer), + ), + ]; + + crate::helpers::make_module_natives(natives) } diff --git a/vm/natives/src/bcs.rs b/vm/natives/src/bcs.rs deleted file mode 100644 index 52ef37db0e..0000000000 --- a/vm/natives/src/bcs.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// SPDX-License-Identifier: Apache-2.0 - -// Copyright (c) The Starcoin Core Contributors -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::errors::PartialVMResult; -use move_core_types::account_address::AccountAddress; -use move_core_types::vm_status::sub_status::NFE_BCS_TO_ADDRESS_FAILURE; -use move_vm_runtime::native_functions::NativeContext; -use move_vm_types::loaded_data::runtime_types::Type; -use move_vm_types::natives::function::{native_gas, NativeResult}; -use move_vm_types::pop_arg; -use move_vm_types::values::Value; -use smallvec::smallvec; -use starcoin_vm_types::gas_schedule::NativeCostIndex; -use std::collections::VecDeque; -use std::convert::TryFrom; - -/// Rust implementation of Move's `public fun from_public_key_vec(pub_key_vec: vector): address;` -pub fn native_to_address( - context: &mut NativeContext, - mut _ty_args: Vec, - mut args: VecDeque, -) -> PartialVMResult { - debug_assert!(_ty_args.is_empty()); - debug_assert!(args.len() == 1); - - let key = pop_arg!(args, Vec); - let cost = native_gas( - context.cost_table(), - NativeCostIndex::BCS_TO_ADDRESS as u8, - key.len(), - ); - if key.len() != AccountAddress::LENGTH { - return Ok(NativeResult::err(cost, NFE_BCS_TO_ADDRESS_FAILURE)); - } - - let address = match AccountAddress::try_from(&key[..AccountAddress::LENGTH]) { - Ok(addr) => addr, - Err(_) => return Ok(NativeResult::err(cost, NFE_BCS_TO_ADDRESS_FAILURE)), - }; - let return_values = smallvec![Value::address(address)]; - Ok(NativeResult::ok(cost, return_values)) -} diff --git a/vm/natives/src/debug.rs b/vm/natives/src/debug.rs deleted file mode 100644 index d1099b6040..0000000000 --- a/vm/natives/src/debug.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) The Diem Core Contributors -// SPDX-License-Identifier: Apache-2.0 - -use move_binary_format::errors::PartialVMResult; -use move_core_types::gas_schedule::ONE_GAS_UNIT; -use move_vm_runtime::native_functions::NativeContext; -#[allow(unused_imports)] -use move_vm_types::values::{values_impl::debug::print_reference, Reference}; -#[allow(unused_imports)] -use move_vm_types::{ - loaded_data::runtime_types::Type, natives::function::NativeResult, pop_arg, values::Value, -}; -use smallvec::smallvec; -use std::collections::VecDeque; - -#[allow(unused_mut)] -#[allow(unused_variables)] -pub fn native_print( - context: &mut NativeContext, - mut ty_args: Vec, - mut args: VecDeque, -) -> PartialVMResult { - debug_assert!(ty_args.len() == 1); - debug_assert!(args.len() == 1); - - // No-op if the feature flag is not present. - #[cfg(feature = "testing")] - { - let ty = ty_args.pop().unwrap(); - let r = pop_arg!(args, Reference); - - let mut buf = String::new(); - print_reference(&mut buf, &r)?; - println!("[debug] {}", buf); - } - - Ok(NativeResult::ok(ONE_GAS_UNIT, smallvec![])) -} - -#[allow(unused_variables)] -pub fn native_print_stack_trace( - context: &mut NativeContext, - ty_args: Vec, - args: VecDeque, -) -> PartialVMResult { - debug_assert!(ty_args.is_empty()); - debug_assert!(args.is_empty()); - - #[cfg(feature = "testing")] - { - let mut s = String::new(); - context.print_stack_trace(&mut s)?; - println!("{}", s); - } - - Ok(NativeResult::ok(ONE_GAS_UNIT, smallvec![])) -} diff --git a/vm/natives/src/ecrecover.rs b/vm/natives/src/ecrecover.rs index bd4ead2f15..079559af85 100644 --- a/vm/natives/src/ecrecover.rs +++ b/vm/natives/src/ecrecover.rs @@ -6,16 +6,14 @@ use libsecp256k1::curve::Scalar; use libsecp256k1::{recover, Message, PublicKey, RecoveryId, Signature}; use log::debug; use move_binary_format::errors::PartialVMResult; -use move_vm_runtime::native_functions::NativeContext; +use move_core_types::gas_algebra::{InternalGas, InternalGasPerByte, NumBytes}; +use move_vm_runtime::native_functions::{NativeContext, NativeFunction}; use move_vm_types::{ - loaded_data::runtime_types::Type, - natives::function::{native_gas, NativeResult}, - pop_arg, - values::Value, + loaded_data::runtime_types::Type, natives::function::NativeResult, pop_arg, values::Value, }; use smallvec::smallvec; -use starcoin_vm_types::gas_schedule::NativeCostIndex; use std::collections::VecDeque; +use std::sync::Arc; use tiny_keccak::Hasher; const HASH_LENGTH: usize = 32; @@ -24,9 +22,22 @@ const SIG_LENGTH: usize = SCALAR_LENGTH + SCALAR_LENGTH; const SIG_REC_LENGTH: usize = SIG_LENGTH + 1; const ZERO_ADDR: [u8; 0] = [0; 0]; +/*************************************************************************************************** + * native fun Ecrecover + * + * gas cost: base_cost + unit_cost * data_length + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EcrecoverGasParameters { + pub base: InternalGas, + pub per_byte: InternalGasPerByte, +} + /// recover address from signature, if recover fail, return an zero address pub fn native_ecrecover( - context: &mut NativeContext, + gas_params: &EcrecoverGasParameters, + _context: &mut NativeContext, _ty_args: Vec, mut arguments: VecDeque, ) -> PartialVMResult { @@ -38,11 +49,7 @@ pub fn native_ecrecover( // first arg is hash let hash_arg = pop_arg!(arguments, Vec); - let cost = native_gas( - context.cost_table(), - NativeCostIndex::ECRECOVER as u8, - hash_arg.len(), - ); + let cost = gas_params.base + gas_params.per_byte * NumBytes::new(hash_arg.len() as u64); if hash_arg.len() != HASH_LENGTH || sig_arg.len() != SIG_REC_LENGTH { debug!("ecrecover failed, invalid hash or sig"); return Ok(NativeResult::ok( @@ -73,6 +80,10 @@ pub fn native_ecrecover( } } +pub fn make_native_ecrecover(gas_params: EcrecoverGasParameters) -> NativeFunction { + Arc::new(move |context, ty_args, args| native_ecrecover(&gas_params, context, ty_args, args)) +} + pub(crate) fn keccak(input: &[u8]) -> [u8; 32] { let mut output = [0u8; 32]; let mut keccak = tiny_keccak::Keccak::v256(); diff --git a/vm/natives/src/hash.rs b/vm/natives/src/hash.rs index ea73bf8011..66040f5e2c 100644 --- a/vm/natives/src/hash.rs +++ b/vm/natives/src/hash.rs @@ -1,22 +1,33 @@ // Copyright (c) The Starcoin Core Contributors // SPDX-License-Identifier: Apache-2.0 +use crate::util::make_native_from_func; use move_binary_format::errors::PartialVMResult; -use move_vm_runtime::native_functions::NativeContext; +use move_core_types::gas_algebra::{InternalGas, InternalGasPerByte, NumBytes}; +use move_vm_runtime::native_functions::{NativeContext, NativeFunction}; use move_vm_types::{ - loaded_data::runtime_types::Type, - natives::function::{native_gas, NativeResult}, - pop_arg, - values::Value, + loaded_data::runtime_types::Type, natives::function::NativeResult, pop_arg, values::Value, }; use ripemd160::digest::Output; use ripemd160::{Digest, Ripemd160}; use smallvec::smallvec; -use starcoin_vm_types::gas_schedule::NativeCostIndex; use std::collections::VecDeque; +/*************************************************************************************************** + * native fun native_keccak_256 + * + * gas cost: base_cost + per_byte * data_length + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Keccak256HashGasParameters { + pub base: InternalGas, + pub per_byte: InternalGasPerByte, +} + pub fn native_keccak_256( - context: &mut NativeContext, + gas_params: &Keccak256HashGasParameters, + _context: &mut NativeContext, _ty_args: Vec, mut arguments: VecDeque, ) -> PartialVMResult { @@ -25,18 +36,28 @@ pub fn native_keccak_256( let input_arg = pop_arg!(arguments, Vec); - let cost = native_gas( - context.cost_table(), - NativeCostIndex::KECCAK_256 as u8, - input_arg.len(), - ); + let cost = gas_params.base + gas_params.per_byte * NumBytes::new(input_arg.len() as u64); + let output = crate::ecrecover::keccak(input_arg.as_slice()); Ok(NativeResult::ok(cost, smallvec![Value::vector_u8(output)])) } +/*************************************************************************************************** + * native fun native_ripemd160 + * + * gas cost: base_cost + per_byte * data_length + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Ripemd160HashGasParameters { + pub base: InternalGas, + pub per_byte: InternalGasPerByte, +} + pub fn native_ripemd160( - context: &mut NativeContext, + gas_params: &Ripemd160HashGasParameters, + _context: &mut NativeContext, _ty_args: Vec, mut arguments: VecDeque, ) -> PartialVMResult { @@ -45,11 +66,7 @@ pub fn native_ripemd160( let input_arg = pop_arg!(arguments, Vec); - let cost = native_gas( - context.cost_table(), - NativeCostIndex::RIPEMD160 as u8, - input_arg.len(), - ); + let cost = gas_params.base + gas_params.per_byte * NumBytes::new(input_arg.len() as u64); let result = ripemd160(input_arg.as_slice()); Ok(NativeResult::ok(cost, smallvec![Value::vector_u8(result)])) @@ -61,6 +78,31 @@ fn ripemd160(input: &[u8]) -> Output { hasher.finalize() } +/*************************************************************************************************** + * module + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GasParameters { + pub keccak256: Keccak256HashGasParameters, + pub ripemd160: Ripemd160HashGasParameters, +} + +pub fn make_all(gas_params: GasParameters) -> impl Iterator { + let natives = [ + ( + "keccak_256", + make_native_from_func(gas_params.keccak256, native_keccak_256), + ), + ( + "ripemd160", + make_native_from_func(gas_params.ripemd160, native_ripemd160), + ), + ]; + + crate::helpers::make_module_natives(natives) +} + #[cfg(test)] mod test { use super::*; diff --git a/vm/natives/src/helpers.rs b/vm/natives/src/helpers.rs new file mode 100644 index 0000000000..6d5cc357d6 --- /dev/null +++ b/vm/natives/src/helpers.rs @@ -0,0 +1,12 @@ +// Copyright (c) The Diem Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_vm_runtime::native_functions::NativeFunction; + +pub fn make_module_natives( + natives: impl IntoIterator, NativeFunction)>, +) -> impl Iterator { + natives + .into_iter() + .map(|(func_name, func)| (func_name.into(), func)) +} diff --git a/vm/natives/src/lib.rs b/vm/natives/src/lib.rs index 7d0608e51f..883e2ce68f 100644 --- a/vm/natives/src/lib.rs +++ b/vm/natives/src/lib.rs @@ -2,8 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 pub mod account; -pub mod bcs; -pub mod debug; pub mod hash; pub mod signature; pub mod token; @@ -11,129 +9,64 @@ pub mod u256; // for support evm compat and cross chain. pub mod ecrecover; -pub mod vector; +mod helpers; +pub mod util; -use move_core_types::identifier::Identifier; -use move_core_types::language_storage::CORE_CODE_ADDRESS; -use move_vm_runtime::native_functions::{NativeFunction, NativeFunctionTable}; +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GasParameters { + pub account: account::GasParameters, + pub hash: hash::GasParameters, + pub signature: signature::GasParameters, + pub token: token::GasParameters, + pub u256: u256::GasParameters, +} -/// The function returns all native functions supported by Starcoin. -/// NOTICE: -/// - mostly re-use natives defined in move-stdlib. -/// - be careful with the native cost table index used in the implementation -pub fn starcoin_natives() -> NativeFunctionTable { - const NATIVES: &[(&str, &str, NativeFunction)] = &[ - ( - "Hash", - "sha2_256", - move_stdlib::natives::hash::native_sha2_256, - ), - ( - "Hash", - "sha3_256", - move_stdlib::natives::hash::native_sha3_256, - ), - ("Hash", "keccak_256", hash::native_keccak_256), - ("Hash", "ripemd160", hash::native_ripemd160), - ( - "BCS", - "to_bytes", - move_stdlib::natives::bcs::native_to_bytes, - ), - ("BCS", "to_address", bcs::native_to_address), - ( - "Signature", - "ed25519_validate_pubkey", - signature::native_ed25519_publickey_validation, - ), - ( - "Signature", - "ed25519_verify", - signature::native_ed25519_signature_verification, - ), - ("Signature", "native_ecrecover", ecrecover::native_ecrecover), - ( - "Vector", - "length", - move_stdlib::natives::vector::native_length, - ), - ( - "Vector", - "empty", - move_stdlib::natives::vector::native_empty, - ), - ( - "Vector", - "borrow", - move_stdlib::natives::vector::native_borrow, - ), - ( - "Vector", - "borrow_mut", - move_stdlib::natives::vector::native_borrow, - ), - ( - "Vector", - "push_back", - move_stdlib::natives::vector::native_push_back, - ), - ( - "Vector", - "pop_back", - move_stdlib::natives::vector::native_pop, - ), - ( - "Vector", - "destroy_empty", - move_stdlib::natives::vector::native_destroy_empty, - ), - ("Vector", "swap", move_stdlib::natives::vector::native_swap), - ("Vector", "native_append", vector::native_append), - ("Vector", "native_remove", vector::native_remove), - ("Vector", "native_reverse", vector::native_reverse), - ( - "Event", - "write_to_event_store", - move_stdlib::natives::event::write_to_event_store, - ), - ("Account", "create_signer", account::native_create_signer), - ("Account", "destroy_signer", account::native_destroy_signer), - ( - "Signer", - "borrow_address", - move_stdlib::natives::signer::native_borrow_address, - ), - ("Token", "name_of", token::native_token_name_of), - ("Debug", "print", debug::native_print), - ( - "Debug", - "print_stack_trace", - debug::native_print_stack_trace, - ), - #[cfg(feature = "testing")] - ( - "UnitTest", - "create_signers_for_testing", - move_stdlib::natives::unit_test::native_create_signers_for_testing, - ), - ("U256", "from_bytes", u256::native_u256_from_bytes), - ("U256", "native_add", u256::native_u256_add), - ("U256", "native_sub", u256::native_u256_sub), - ("U256", "native_mul", u256::native_u256_mul), - ("U256", "native_div", u256::native_u256_div), - ("U256", "native_rem", u256::native_u256_rem), - ("U256", "native_pow", u256::native_u256_pow), - ]; - NATIVES - .iter() - .cloned() - .map(|(module_name, func_name, func)| { - ( - CORE_CODE_ADDRESS, - Identifier::new(module_name).unwrap(), - Identifier::new(func_name).unwrap(), - func, - ) - }) - .collect() +impl GasParameters { + pub fn zeros() -> Self { + Self { + account: account::GasParameters { + create_signer: account::CreateSignerGasParameters { base: 0.into() }, + destroy_signer: account::DestroySignerGasParameters { base: 0.into() }, + }, + hash: hash::GasParameters { + keccak256: hash::Keccak256HashGasParameters { + base: 0.into(), + per_byte: 0.into(), + }, + ripemd160: hash::Ripemd160HashGasParameters { + base: 0.into(), + per_byte: 0.into(), + }, + }, + signature: signature::GasParameters { + ed25519_validate_key: signature::Ed25519ValidateKeyGasParameters { + base: 0.into(), + per_byte: 0.into(), + }, + ed25519_verify: signature::Ed25519VerifyGasParameters { + base: 0.into(), + per_byte: 0.into(), + }, + ec_recover: ecrecover::EcrecoverGasParameters { + base: 0.into(), + per_byte: 0.into(), + }, + }, + token: token::GasParameters { + name_of: token::NameOfGasParameters { base: 0.into() }, + }, + u256: u256::GasParameters { + add: u256::U256AddGasParameters { base: 0.into() }, + sub: u256::U256SubGasParameters { base: 0.into() }, + mul: u256::U256MulGasParameters { base: 0.into() }, + div: u256::U256DivGasParameters { base: 0.into() }, + rem: u256::U256RemGasParameters { base: 0.into() }, + pow: u256::U256PowGasParameters { base: 0.into() }, + from_bytes: u256::U256FromBytesGasParameters { + base: 0.into(), + per_byte: 0.into(), + }, + }, + } + } } diff --git a/vm/natives/src/signature.rs b/vm/natives/src/signature.rs index 8ded6c59e4..9753cc1a80 100644 --- a/vm/natives/src/signature.rs +++ b/vm/natives/src/signature.rs @@ -1,21 +1,33 @@ // Copyright (c) The Diem Core Contributors // SPDX-License-Identifier: Apache-2.0 +use crate::ecrecover::{make_native_ecrecover, EcrecoverGasParameters}; use move_binary_format::errors::PartialVMResult; -use move_vm_runtime::native_functions::NativeContext; +use move_core_types::gas_algebra::{InternalGas, InternalGasPerByte, NumBytes}; +use move_vm_runtime::native_functions::{NativeContext, NativeFunction}; use move_vm_types::{ - loaded_data::runtime_types::Type, - natives::function::{native_gas, NativeResult}, - pop_arg, - values::Value, + loaded_data::runtime_types::Type, natives::function::NativeResult, pop_arg, values::Value, }; use smallvec::smallvec; use starcoin_crypto::{ed25519, traits::*}; -use starcoin_vm_types::gas_schedule::NativeCostIndex; +use std::sync::Arc; use std::{collections::VecDeque, convert::TryFrom}; +/*************************************************************************************************** + * native fun Ed25519PublickeyValidation + * + * gas cost: base_cost + unit_cost * data_length + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Ed25519ValidateKeyGasParameters { + pub base: InternalGas, + pub per_byte: InternalGasPerByte, +} + pub fn native_ed25519_publickey_validation( - context: &mut NativeContext, + gas_params: &Ed25519ValidateKeyGasParameters, + _context: &mut NativeContext, _ty_args: Vec, mut arguments: VecDeque, ) -> PartialVMResult { @@ -24,19 +36,36 @@ pub fn native_ed25519_publickey_validation( let key = pop_arg!(arguments, Vec); - let cost = native_gas( - context.cost_table(), - NativeCostIndex::ED25519_VALIDATE_KEY as u8, - key.len(), - ); + let cost = gas_params.base + gas_params.per_byte * NumBytes::new(key.len() as u64); // This deserialization performs point-on-curve and small subgroup checks let valid = ed25519::Ed25519PublicKey::try_from(&key[..]).is_ok(); Ok(NativeResult::ok(cost, smallvec![Value::bool(valid)])) } +pub fn make_native_ed25519_validate_pubkey( + gas_params: Ed25519ValidateKeyGasParameters, +) -> NativeFunction { + Arc::new(move |context, ty_args, args| { + native_ed25519_publickey_validation(&gas_params, context, ty_args, args) + }) +} + +/*************************************************************************************************** + * native fun Ed25519PublickeyValidation + * + * gas cost: base_cost + unit_cost * data_length + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Ed25519VerifyGasParameters { + pub base: InternalGas, + pub per_byte: InternalGasPerByte, +} + pub fn native_ed25519_signature_verification( - context: &mut NativeContext, + gas_params: &Ed25519VerifyGasParameters, + _context: &mut NativeContext, _ty_args: Vec, mut arguments: VecDeque, ) -> PartialVMResult { @@ -47,11 +76,7 @@ pub fn native_ed25519_signature_verification( let pubkey = pop_arg!(arguments, Vec); let signature = pop_arg!(arguments, Vec); - let cost = native_gas( - context.cost_table(), - NativeCostIndex::ED25519_VERIFY as u8, - msg.len(), - ); + let cost = gas_params.base + gas_params.per_byte * NumBytes::new(msg.len() as u64); let sig = match ed25519::Ed25519Signature::try_from(signature.as_slice()) { Ok(sig) => sig, @@ -72,3 +97,39 @@ pub fn native_ed25519_signature_verification( smallvec![Value::bool(verify_result)], )) } + +pub fn make_native_ed25519_verify(gas_params: Ed25519VerifyGasParameters) -> NativeFunction { + Arc::new(move |context, ty_args, args| { + native_ed25519_signature_verification(&gas_params, context, ty_args, args) + }) +} + +/*************************************************************************************************** + * module + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GasParameters { + pub ed25519_validate_key: Ed25519ValidateKeyGasParameters, + pub ed25519_verify: Ed25519VerifyGasParameters, + pub ec_recover: EcrecoverGasParameters, +} + +pub fn make_all(gas_params: GasParameters) -> impl Iterator { + let natives = [ + ( + "ed25519_validate_pubkey", + make_native_ed25519_validate_pubkey(gas_params.ed25519_validate_key), + ), + ( + "ed25519_verify", + make_native_ed25519_verify(gas_params.ed25519_verify), + ), + ( + "native_ecrecover", + make_native_ecrecover(gas_params.ec_recover), + ), + ]; + + crate::helpers::make_module_natives(natives) +} diff --git a/vm/natives/src/token.rs b/vm/natives/src/token.rs index e14fe3767f..1de3055fb0 100644 --- a/vm/natives/src/token.rs +++ b/vm/natives/src/token.rs @@ -2,31 +2,38 @@ // SPDX-License-Identifier: Apache-2.0 use move_binary_format::errors::PartialVMResult; +use move_core_types::gas_algebra::InternalGas; use move_core_types::language_storage::TypeTag; use move_core_types::vm_status::sub_status::NFE_TOKEN_INVALID_TYPE_ARG_FAILURE; -use move_vm_runtime::native_functions::NativeContext; +use move_vm_runtime::native_functions::{NativeContext, NativeFunction}; use move_vm_types::{ - loaded_data::runtime_types::Type, - natives::function::{native_gas, NativeResult}, - values::Value, + loaded_data::runtime_types::Type, natives::function::NativeResult, values::Value, }; use smallvec::smallvec; -use starcoin_vm_types::gas_schedule::NativeCostIndex; use std::collections::VecDeque; +use std::sync::Arc; + +/*************************************************************************************************** + * native fun token_name_of + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct NameOfGasParameters { + pub base: InternalGas, +} /// Return Token types ModuleAddress, ModuleName and StructName pub fn native_token_name_of( + gas_params: &NameOfGasParameters, context: &mut NativeContext, ty_args: Vec, arguments: VecDeque, ) -> PartialVMResult { debug_assert!(ty_args.len() == 1); debug_assert!(arguments.is_empty()); - let cost = native_gas( - context.cost_table(), - NativeCostIndex::TOKEN_NAME_OF as u8, - 1, - ); + let cost = gas_params.base; let type_tag = context.type_to_type_tag(&ty_args[0])?; if let TypeTag::Struct(struct_tag) = type_tag { let mut name = struct_tag.name.as_bytes().to_vec(); @@ -61,6 +68,28 @@ fn format_type_params(type_params: &[TypeTag]) -> Result NativeFunction { + Arc::new( + move |context, ty_args, args| -> PartialVMResult { + native_token_name_of(&gas_params, context, ty_args, args) + }, + ) +} +/*************************************************************************************************** + * module + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GasParameters { + pub name_of: NameOfGasParameters, +} + +pub fn make_all(gas_params: GasParameters) -> impl Iterator { + let natives = [("name_of", make_native_token_name_of(gas_params.name_of))]; + + crate::helpers::make_module_natives(natives) +} + #[test] fn test_type_params_formatting() { use move_core_types::account_address::AccountAddress; @@ -79,7 +108,7 @@ fn test_type_params_formatting() { ", u64>", ), ( - vec![TypeTag::U64, TypeTag::Struct(a_struct)], + vec![TypeTag::U64, TypeTag::Struct(Box::new(a_struct))], ">", ), ]; diff --git a/vm/natives/src/u256.rs b/vm/natives/src/u256.rs index a1f61af984..824f943eae 100644 --- a/vm/natives/src/u256.rs +++ b/vm/natives/src/u256.rs @@ -1,21 +1,22 @@ +use crate::util::make_native_from_func; use move_binary_format::errors::{PartialVMError, PartialVMResult}; -use move_core_types::gas_schedule::GasAlgebra; +use move_core_types::gas_algebra::{InternalGas, InternalGasPerByte, NumBytes}; use move_core_types::vm_status::StatusCode; -use move_vm_runtime::native_functions::NativeContext; +use move_vm_runtime::native_functions::{NativeContext, NativeFunction}; use move_vm_types::loaded_data::runtime_types::Type; -use move_vm_types::natives::function::{native_gas, NativeResult}; +use move_vm_types::natives::function::NativeResult; use move_vm_types::pop_arg; use move_vm_types::values::{Reference, Struct, StructRef, VMValueCast, Value}; use smallvec::smallvec; use starcoin_uint::U256; -use starcoin_vm_types::gas_schedule::NativeCostIndex::*; use std::collections::VecDeque; use std::convert::TryFrom; macro_rules! impl_native { - ($func:ident,$cost_index: ident, $op:ident) => { + ($func:ident,$params: ident, $op:ident) => { pub fn $func( - context: &mut NativeContext, + gas_params: &$params, + _context: &mut NativeContext, _ty_args: Vec, mut arguments: VecDeque, ) -> PartialVMResult { @@ -50,21 +51,100 @@ macro_rules! impl_native { let field_ref: Reference = a_ref.borrow_field(0)?.cast()?; field_ref.write_ref(Value::vector_u64(res))?; } - let cost = native_gas(context.cost_table(), $cost_index as u8, 1); + let cost = gas_params.base; Ok(NativeResult::ok(cost, smallvec![])) } }; } -impl_native!(native_u256_add, U256_ADD, checked_add); -impl_native!(native_u256_sub, U256_SUB, checked_sub); -impl_native!(native_u256_mul, U256_MUL, checked_mul); -impl_native!(native_u256_div, U256_DIV, checked_div); -impl_native!(native_u256_rem, U256_REM, checked_rem); -impl_native!(native_u256_pow, U256_POW, checked_pow); +impl_native!(native_u256_add, U256AddGasParameters, checked_add); +impl_native!(native_u256_sub, U256SubGasParameters, checked_sub); +impl_native!(native_u256_mul, U256MulGasParameters, checked_mul); +impl_native!(native_u256_div, U256DivGasParameters, checked_div); +impl_native!(native_u256_rem, U256RemGasParameters, checked_rem); +impl_native!(native_u256_pow, U256PowGasParameters, checked_pow); + +/*************************************************************************************************** + * native fun native_u256_add + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct U256AddGasParameters { + pub base: InternalGas, +} + +/*************************************************************************************************** + * native fun native_u256_sub + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct U256SubGasParameters { + pub base: InternalGas, +} + +/*************************************************************************************************** + * native fun native_u256_mul + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct U256MulGasParameters { + pub base: InternalGas, +} + +/*************************************************************************************************** + * native fun native_u256_div + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct U256DivGasParameters { + pub base: InternalGas, +} + +/*************************************************************************************************** + * native fun native_u256_rem + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct U256RemGasParameters { + pub base: InternalGas, +} + +/*************************************************************************************************** + * native fun native_u256_pow + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct U256PowGasParameters { + pub base: InternalGas, +} + +/*************************************************************************************************** + * native fun native_u256_pow + * + * gas cost: base_cost + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct U256FromBytesGasParameters { + pub base: InternalGas, + pub per_byte: InternalGasPerByte, +} pub fn native_u256_from_bytes( - context: &mut NativeContext, + gas_params: &U256FromBytesGasParameters, + _context: &mut NativeContext, _ty_args: Vec, mut arguments: VecDeque, ) -> PartialVMResult { @@ -84,10 +164,56 @@ pub fn native_u256_from_bytes( }; let ret = Value::struct_(Struct::pack(vec![Value::vector_u64(ret.0)])); - let cost = native_gas( - context.cost_table(), - U256_FROM_BYTES as u8, - ret.size().get() as usize, - ); + let cost = gas_params.base + gas_params.per_byte * NumBytes::new(ret.legacy_size().into()); Ok(NativeResult::ok(cost, smallvec![ret])) } + +/*************************************************************************************************** + * module + * + **************************************************************************************************/ +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GasParameters { + pub add: U256AddGasParameters, + pub sub: U256SubGasParameters, + pub mul: U256MulGasParameters, + pub div: U256DivGasParameters, + pub rem: U256RemGasParameters, + pub pow: U256PowGasParameters, + pub from_bytes: U256FromBytesGasParameters, +} + +pub fn make_all(gas_params: GasParameters) -> impl Iterator { + let natives = [ + ( + "native_add", + make_native_from_func(gas_params.add, native_u256_add), + ), + ( + "native_sub", + make_native_from_func(gas_params.sub, native_u256_sub), + ), + ( + "native_mul", + make_native_from_func(gas_params.mul, native_u256_mul), + ), + ( + "native_div", + make_native_from_func(gas_params.div, native_u256_div), + ), + ( + "native_rem", + make_native_from_func(gas_params.rem, native_u256_rem), + ), + ( + "native_pow", + make_native_from_func(gas_params.pow, native_u256_pow), + ), + ( + "from_bytes", + make_native_from_func(gas_params.from_bytes, native_u256_from_bytes), + ), + ]; + + crate::helpers::make_module_natives(natives) +} diff --git a/vm/natives/src/util.rs b/vm/natives/src/util.rs new file mode 100644 index 0000000000..78a3846243 --- /dev/null +++ b/vm/natives/src/util.rs @@ -0,0 +1,17 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::errors::PartialVMResult; +use move_vm_runtime::native_functions::{NativeContext, NativeFunction}; +use move_vm_types::{ + loaded_data::runtime_types::Type, natives::function::NativeResult, values::Value, +}; +use std::{collections::VecDeque, sync::Arc}; + +/// Used to pass gas parameters into native functions. +pub fn make_native_from_func( + gas_params: T, + func: fn(&T, &mut NativeContext, Vec, VecDeque) -> PartialVMResult, +) -> NativeFunction { + Arc::new(move |context, ty_args, args| func(&gas_params, context, ty_args, args)) +} diff --git a/vm/natives/src/vector.rs b/vm/natives/src/vector.rs deleted file mode 100644 index bda4002458..0000000000 --- a/vm/natives/src/vector.rs +++ /dev/null @@ -1,49 +0,0 @@ -use move_binary_format::errors::PartialVMResult; -use move_vm_runtime::native_functions::NativeContext; -use move_vm_types::loaded_data::runtime_types::Type; -use move_vm_types::natives::function::{native_gas, NativeResult}; -use move_vm_types::pop_arg; -use move_vm_types::values::{Value, VectorRef}; -use starcoin_vm_types::gas_schedule::NativeCostIndex; -use std::collections::VecDeque; - -pub fn native_append( - context: &mut NativeContext, - ty_args: Vec, - mut args: VecDeque, -) -> PartialVMResult { - debug_assert!(ty_args.len() == 1); - debug_assert!(args.len() == 2); - - let other = args.pop_back().unwrap(); - let lhs = pop_arg!(args, VectorRef); - let cost = native_gas(context.cost_table(), NativeCostIndex::VEC_APPEND as u8, 1); - lhs.append(cost, other.value_as()?, &ty_args[0]) -} - -pub fn native_remove( - context: &mut NativeContext, - ty_args: Vec, - mut args: VecDeque, -) -> PartialVMResult { - debug_assert!(ty_args.len() == 1); - debug_assert!(args.len() == 2); - - let idx: u64 = args.pop_back().unwrap().value_as()?; - let lhs = pop_arg!(args, VectorRef); - - let cost = native_gas(context.cost_table(), NativeCostIndex::VEC_REMOVE as u8, 1); - lhs.remove(idx as usize, cost, &ty_args[0]) -} - -pub fn native_reverse( - context: &mut NativeContext, - ty_args: Vec, - mut args: VecDeque, -) -> PartialVMResult { - debug_assert!(ty_args.len() == 1); - debug_assert!(args.len() == 1); - let lhs = pop_arg!(args, VectorRef); - let cost = native_gas(context.cost_table(), NativeCostIndex::VEC_REVERSE as u8, 1); - lhs.reverse(cost, &ty_args[0]) -} diff --git a/vm/resource-viewer/Cargo.toml b/vm/resource-viewer/Cargo.toml index 2df1e524d6..99d164c3fd 100644 --- a/vm/resource-viewer/Cargo.toml +++ b/vm/resource-viewer/Cargo.toml @@ -3,7 +3,7 @@ anyhow = { workspace = true } hex = { workspace = true } move-binary-format = { workspace = true } move-core-types = { workspace = true } -serde = { features = [ "derive", "rc",], workspace = true } +serde = { features = ["derive", "rc"], workspace = true } serde_json = { workspace = true } starcoin-vm-types = { workspace = true } diff --git a/vm/resource-viewer/src/fat_type.rs b/vm/resource-viewer/src/fat_type.rs index aaed0f3ff7..e5e790a6bb 100644 --- a/vm/resource-viewer/src/fat_type.rs +++ b/vm/resource-viewer/src/fat_type.rs @@ -66,6 +66,10 @@ pub(crate) enum FatType { Reference(Box), MutableReference(Box), TyParam(usize), + // NOTE: Added in bytecode version v6, do not reorder! + U16, + U32, + U256, } impl FatStructType { @@ -124,8 +128,11 @@ impl FatType { Bool => Bool, U8 => U8, + U16 => U16, + U32 => U32, U64 => U64, U128 => U128, + U256 => U256, Address => Address, Signer => Signer, Vector(ty) => Vector(Box::new(ty.subst(ty_args)?)), @@ -144,12 +151,15 @@ impl FatType { let res = match self { Bool => TypeTag::Bool, U8 => TypeTag::U8, + U16 => TypeTag::U16, + U32 => TypeTag::U32, U64 => TypeTag::U64, U128 => TypeTag::U128, + U256 => TypeTag::U256, Address => TypeTag::Address, Signer => TypeTag::Signer, Vector(ty) => TypeTag::Vector(Box::new(ty.type_tag()?)), - Struct(struct_ty) => TypeTag::Struct(struct_ty.struct_tag()?), + Struct(struct_ty) => TypeTag::Struct(Box::new(struct_ty.struct_tag()?)), Reference(_) | MutableReference(_) | TyParam(_) => { return Err( @@ -183,8 +193,11 @@ impl TryInto for &FatType { Ok(match self { FatType::Address => MoveTypeLayout::Address, FatType::U8 => MoveTypeLayout::U8, + FatType::U16 => MoveTypeLayout::U16, + FatType::U32 => MoveTypeLayout::U32, FatType::U64 => MoveTypeLayout::U64, FatType::U128 => MoveTypeLayout::U128, + FatType::U256 => MoveTypeLayout::U256, FatType::Bool => MoveTypeLayout::Bool, FatType::Vector(v) => MoveTypeLayout::Vector(Box::new(v.as_ref().try_into()?)), FatType::Struct(s) => MoveTypeLayout::Struct(MoveStructLayout::new( diff --git a/vm/resource-viewer/src/lib.rs b/vm/resource-viewer/src/lib.rs index d24f33752e..254b974a4b 100644 --- a/vm/resource-viewer/src/lib.rs +++ b/vm/resource-viewer/src/lib.rs @@ -9,11 +9,12 @@ use crate::{ resolver::Resolver, }; use anyhow::{anyhow, Result}; +use move_core_types::u256; use starcoin_vm_types::language_storage::TypeTag; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::state_view::StateView; use starcoin_vm_types::value::MoveTypeLayout; use starcoin_vm_types::{ - access_path::AccessPath, account_address::AccountAddress, contract_event::ContractEvent, errors::{Location, PartialVMError}, @@ -56,6 +57,10 @@ pub enum AnnotatedMoveValue { Vector(Vec), Bytes(Vec), Struct(AnnotatedMoveStruct), + // NOTE: Added in bytecode version v6, do not reorder! + U16(u16), + U32(u32), + U256(u256::U256), } // impl Serialize for AnnotatedMoveValue { @@ -173,8 +178,11 @@ impl<'a> MoveValueAnnotator<'a> { Ok(match (value, ty) { (MoveValue::Bool(b), FatType::Bool) => AnnotatedMoveValue::Bool(*b), (MoveValue::U8(i), FatType::U8) => AnnotatedMoveValue::U8(*i), + (MoveValue::U16(i), FatType::U16) => AnnotatedMoveValue::U16(*i), + (MoveValue::U32(i), FatType::U32) => AnnotatedMoveValue::U32(*i), (MoveValue::U64(i), FatType::U64) => AnnotatedMoveValue::U64(*i), (MoveValue::U128(i), FatType::U128) => AnnotatedMoveValue::U128(*i), + (MoveValue::U256(i), FatType::U256) => AnnotatedMoveValue::U256(*i), (MoveValue::Address(a), FatType::Address) => AnnotatedMoveValue::Address(*a), (MoveValue::Vector(a), FatType::Vector(ty)) => match ty.as_ref() { FatType::U8 => AnnotatedMoveValue::Bytes( @@ -194,7 +202,17 @@ impl<'a> MoveValueAnnotator<'a> { (MoveValue::Struct(s), FatType::Struct(ty)) => { AnnotatedMoveValue::Struct(self.annotate_struct(s, ty.as_ref())?) } - _ => { + (MoveValue::U8(_), _) + | (MoveValue::U64(_), _) + | (MoveValue::U128(_), _) + | (MoveValue::Bool(_), _) + | (MoveValue::Address(_), _) + | (MoveValue::Vector(_), _) + | (MoveValue::Struct(_), _) + | (MoveValue::Signer(_), _) + | (MoveValue::U16(_), _) + | (MoveValue::U32(_), _) + | (MoveValue::U256(_), _) => { return Err(anyhow!( "Cannot annotate value {:?} with type {:?}", value, @@ -220,8 +238,11 @@ fn pretty_print_value( match value { AnnotatedMoveValue::Bool(b) => write!(f, "{}", b), AnnotatedMoveValue::U8(v) => write!(f, "{}u8", v), + AnnotatedMoveValue::U16(v) => write!(f, "{}u16", v), + AnnotatedMoveValue::U32(v) => write!(f, "{}u32", v), AnnotatedMoveValue::U64(v) => write!(f, "{}", v), AnnotatedMoveValue::U128(v) => write!(f, "{}u128", v), + AnnotatedMoveValue::U256(v) => write!(f, "{}u256", v), AnnotatedMoveValue::Address(a) => write!(f, "0x{:#x}", a), AnnotatedMoveValue::Vector(v) => { writeln!(f, "[")?; @@ -295,7 +316,7 @@ pub struct NullStateView; // impl StateView for NullStateView { - fn get(&self, _access_path: &AccessPath) -> Result>> { + fn get_state_value(&self, _state_key: &StateKey) -> Result>> { Ok(None) } diff --git a/vm/resource-viewer/src/resolver.rs b/vm/resource-viewer/src/resolver.rs index 2d5a3029a3..827a482d81 100644 --- a/vm/resource-viewer/src/resolver.rs +++ b/vm/resource-viewer/src/resolver.rs @@ -9,6 +9,7 @@ use crate::{ module_cache::ModuleCache, }; use anyhow::{anyhow, Result}; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::{ access::ModuleAccess, access_path::AccessPath, @@ -55,7 +56,7 @@ impl<'a> Resolver<'a> { let access_path = AccessPath::from(&module_id); let blob = self .state - .get(&access_path)? + .get_state_value(&StateKey::AccessPath(access_path))? .ok_or_else(|| anyhow!("Module {:?} can't be found", module_id))?; let compiled_module = CompiledModule::deserialize(&blob).map_err(|status| { anyhow!( @@ -74,8 +75,11 @@ impl<'a> Resolver<'a> { TypeTag::Bool => FatType::Bool, TypeTag::Struct(st) => FatType::Struct(Box::new(self.resolve_struct(st)?)), TypeTag::U8 => FatType::U8, + TypeTag::U16 => FatType::U16, + TypeTag::U32 => FatType::U32, TypeTag::U64 => FatType::U64, TypeTag::U128 => FatType::U128, + TypeTag::U256 => FatType::U256, TypeTag::Vector(ty) => FatType::Vector(Box::new(self.resolve_type(ty)?)), }) } @@ -117,8 +121,11 @@ impl<'a> Resolver<'a> { Ok(match sig { SignatureToken::Bool => FatType::Bool, SignatureToken::U8 => FatType::U8, + SignatureToken::U16 => FatType::U16, + SignatureToken::U32 => FatType::U32, SignatureToken::U64 => FatType::U64, SignatureToken::U128 => FatType::U128, + SignatureToken::U256 => FatType::U256, SignatureToken::Address => FatType::Address, SignatureToken::Signer => FatType::Signer, SignatureToken::Vector(ty) => { diff --git a/vm/starcoin-gas/Cargo.toml b/vm/starcoin-gas/Cargo.toml new file mode 100644 index 0000000000..f896bd56b0 --- /dev/null +++ b/vm/starcoin-gas/Cargo.toml @@ -0,0 +1,22 @@ +[dependencies] +starcoin-gas-algebra-ext = { workspace = true } +clap = { version = "3", features = ["derive"] } +move-binary-format = { workspace = true } +move-core-types = { workspace = true } +move-stdlib = { workspace = true } +move-table-extension = { workspace = true } +move-vm-types = { workspace = true } +starcoin-natives = { workspace = true } +starcoin-logger = { workspace = true } + +[package] +authors = { workspace = true } +description = "starcoin Move VM starcoin-gas" +edition = { workspace = true } +license = { workspace = true } +name = "starcoin-gas" +publish = { workspace = true } +version = "1.12.9" +homepage = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } diff --git a/vm/starcoin-gas/src/gas_meter.rs b/vm/starcoin-gas/src/gas_meter.rs new file mode 100644 index 0000000000..ce7d122b91 --- /dev/null +++ b/vm/starcoin-gas/src/gas_meter.rs @@ -0,0 +1,795 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This module contains the official gas meter implementation, along with some top-level gas +//! parameters and traits to help manipulate them. + +use move_binary_format::errors::{Location, PartialVMError, PartialVMResult, VMResult}; +use move_core_types::gas_algebra::{ + AbstractMemorySize, InternalGasPerAbstractMemoryUnit, InternalGasPerArg, InternalGasPerByte, + NumArgs, +}; +use move_core_types::language_storage::ModuleId; +use move_core_types::{ + gas_algebra::{InternalGas, NumBytes}, + vm_status::StatusCode, +}; +use move_vm_types::gas::{GasMeter, SimpleInstruction}; +use move_vm_types::views::{TypeView, ValueView}; +use starcoin_gas_algebra_ext::{ + FromOnChainGasSchedule, Gas, InitialGasSchedule, ToOnChainGasSchedule, +}; +#[cfg(testing)] +use starcoin_logger::prelude::*; +use std::collections::BTreeMap; + +use move_binary_format::file_format_common::Opcodes; +use starcoin_gas_algebra_ext::InstructionGasParameters; +use starcoin_gas_algebra_ext::TransactionGasParameters; + +/// The size in bytes for a reference on the stack +const REFERENCE_SIZE: AbstractMemorySize = AbstractMemorySize::new(8); + +/// For exists checks on data that doesn't exists this is the multiplier that is used. +const MIN_EXISTS_DATA_SIZE: AbstractMemorySize = AbstractMemorySize::new(100); + +/// Gas parameters for all native functions. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct NativeGasParameters { + pub move_stdlib: move_stdlib::natives::GasParameters, + pub nursery: move_stdlib::natives::NurseryGasParameters, + pub starcoin_natives: starcoin_natives::GasParameters, + pub table: move_table_extension::GasParameters, +} + +impl FromOnChainGasSchedule for NativeGasParameters { + fn from_on_chain_gas_schedule(gas_schedule: &BTreeMap) -> Option { + Some(Self { + move_stdlib: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule)?, + nursery: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule)?, + starcoin_natives: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule)?, + table: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule)?, + }) + } +} + +impl ToOnChainGasSchedule for NativeGasParameters { + fn to_on_chain_gas_schedule(&self) -> Vec<(String, u64)> { + let mut entries = self.move_stdlib.to_on_chain_gas_schedule(); + entries.extend(self.nursery.to_on_chain_gas_schedule()); + entries.extend(self.starcoin_natives.to_on_chain_gas_schedule()); + entries.extend(self.table.to_on_chain_gas_schedule()); + entries + } +} + +impl NativeGasParameters { + pub fn zeros() -> Self { + Self { + move_stdlib: move_stdlib::natives::GasParameters::zeros(), + nursery: move_stdlib::natives::NurseryGasParameters::zeros(), + starcoin_natives: starcoin_natives::GasParameters::zeros(), + table: move_table_extension::GasParameters::zeros(), + } + } +} + +impl InitialGasSchedule for NativeGasParameters { + fn initial() -> Self { + Self { + move_stdlib: InitialGasSchedule::initial(), + nursery: InitialGasSchedule::initial(), + starcoin_natives: InitialGasSchedule::initial(), + table: InitialGasSchedule::initial(), + } + } +} + +/// Gas parameters for everything that is needed to run the Starcoin blockchain, including +/// instructions, transactions and native functions from various packages. +#[derive(Debug, Clone)] +pub struct StarcoinGasParameters { + pub instr: InstructionGasParameters, + pub txn: TransactionGasParameters, + pub natives: NativeGasParameters, +} + +impl FromOnChainGasSchedule for StarcoinGasParameters { + fn from_on_chain_gas_schedule(gas_schedule: &BTreeMap) -> Option { + Some(Self { + natives: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule)?, + instr: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule)?, + txn: FromOnChainGasSchedule::from_on_chain_gas_schedule(gas_schedule)?, + }) + } +} + +impl ToOnChainGasSchedule for StarcoinGasParameters { + fn to_on_chain_gas_schedule(&self) -> Vec<(String, u64)> { + let mut entries = self.instr.to_on_chain_gas_schedule(); + entries.extend(self.txn.to_on_chain_gas_schedule()); + entries.extend(self.natives.to_on_chain_gas_schedule()); + entries + } +} + +impl StarcoinGasParameters { + // Only used for genesis and for tests where we need a cost table and + // don't have a genesis storage state. + pub fn zeros() -> Self { + Self { + instr: InstructionGasParameters::zeros(), + txn: TransactionGasParameters::zeros(), + natives: NativeGasParameters::zeros(), + } + } +} + +impl InitialGasSchedule for StarcoinGasParameters { + fn initial() -> Self { + Self { + instr: InitialGasSchedule::initial(), + txn: InitialGasSchedule::initial(), + natives: InitialGasSchedule::initial(), + } + } +} + +/// The official gas meter used inside the Starcoin VM. +/// It maintains an internal gas counter, measured in internal gas units, and carries an environment +/// consisting all the gas parameters, which it can lookup when performing gas calculations. +pub struct StarcoinGasMeter { + gas_params: StarcoinGasParameters, + balance: InternalGas, + charge: bool, +} + +impl StarcoinGasMeter { + pub fn new(gas_params: StarcoinGasParameters, balance: impl Into) -> Self { + let balance = balance.into().to_unit_with_params(&gas_params.txn); + Self { + gas_params, + balance, + charge: true, + } + } + + pub fn balance(&self) -> Gas { + self.balance + .to_unit_round_down_with_params(&self.gas_params.txn) + } + + pub fn deduct_gas(&mut self, amount: InternalGas) -> PartialVMResult<()> { + if !self.charge { + return Ok(()); + } + match self.balance.checked_sub(amount) { + Some(new_balance) => { + self.balance = new_balance; + Ok(()) + } + None => { + self.balance = 0.into(); + Err(PartialVMError::new(StatusCode::OUT_OF_GAS)) + } + } + } + + pub fn set_metering(&mut self, enabled: bool) { + self.charge = enabled; + } + + pub fn get_metering(&self) -> bool { + self.charge + } + + pub fn charge_intrinsic_gas_for_transaction(&mut self, txn_size: NumBytes) -> VMResult<()> { + let cost = self.gas_params.txn.calculate_intrinsic_gas(txn_size); + #[cfg(testing)] + info!( + "charge_intrinsic_gas cost InternalGasUnits({}) {}", + cost, self.charge + ); + self.deduct_gas(cost) + .map_err(|e| e.finish(Location::Undefined)) + } + + pub fn cal_write_set_gas(&self) -> InternalGas { + self.gas_params.txn.cal_write_set_gas() + } +} + +#[inline] +fn cal_instr_with_size( + per_mem: InternalGasPerAbstractMemoryUnit, + size: AbstractMemorySize, +) -> InternalGas { + let size = std::cmp::max(1.into(), size); + per_mem * size +} + +#[inline] +fn cal_instr_with_arg(per_arg: InternalGasPerArg, size: NumArgs) -> InternalGas { + let size = std::cmp::max(1.into(), size); + per_arg * size +} + +#[inline] +fn cal_instr_with_byte(per_arg: InternalGasPerByte, size: NumBytes) -> InternalGas { + let size = std::cmp::max(1.into(), size); + per_arg * size +} + +#[allow(dead_code)] +#[inline] +fn simple_instr_to_opcode(instr: SimpleInstruction) -> Opcodes { + match instr { + SimpleInstruction::Nop => Opcodes::NOP, + SimpleInstruction::Ret => Opcodes::RET, + + SimpleInstruction::BrTrue => Opcodes::BR_TRUE, + SimpleInstruction::BrFalse => Opcodes::BR_FALSE, + SimpleInstruction::Branch => Opcodes::BRANCH, + + SimpleInstruction::LdU8 => Opcodes::LD_U8, + SimpleInstruction::LdU64 => Opcodes::LD_U64, + SimpleInstruction::LdU128 => Opcodes::LD_U128, + SimpleInstruction::LdTrue => Opcodes::LD_TRUE, + SimpleInstruction::LdFalse => Opcodes::LD_FALSE, + + SimpleInstruction::FreezeRef => Opcodes::FREEZE_REF, + SimpleInstruction::MutBorrowLoc => Opcodes::MUT_BORROW_LOC, + SimpleInstruction::ImmBorrowLoc => Opcodes::IMM_BORROW_LOC, + SimpleInstruction::ImmBorrowField => Opcodes::IMM_BORROW_FIELD, + SimpleInstruction::MutBorrowField => Opcodes::MUT_BORROW_FIELD, + SimpleInstruction::ImmBorrowFieldGeneric => Opcodes::IMM_BORROW_FIELD_GENERIC, + SimpleInstruction::MutBorrowFieldGeneric => Opcodes::MUT_BORROW_FIELD_GENERIC, + + SimpleInstruction::CastU8 => Opcodes::CAST_U8, + SimpleInstruction::CastU64 => Opcodes::CAST_U64, + SimpleInstruction::CastU128 => Opcodes::CAST_U128, + + SimpleInstruction::Add => Opcodes::ADD, + SimpleInstruction::Sub => Opcodes::SUB, + SimpleInstruction::Mul => Opcodes::MUL, + SimpleInstruction::Mod => Opcodes::MOD, + SimpleInstruction::Div => Opcodes::DIV, + + SimpleInstruction::BitOr => Opcodes::BIT_OR, + SimpleInstruction::BitAnd => Opcodes::BIT_AND, + SimpleInstruction::Xor => Opcodes::XOR, + SimpleInstruction::Shl => Opcodes::SHL, + SimpleInstruction::Shr => Opcodes::SHR, + + SimpleInstruction::Or => Opcodes::OR, + SimpleInstruction::And => Opcodes::AND, + SimpleInstruction::Not => Opcodes::NOT, + + SimpleInstruction::Lt => Opcodes::LT, + SimpleInstruction::Gt => Opcodes::GT, + SimpleInstruction::Le => Opcodes::LE, + SimpleInstruction::Ge => Opcodes::GE, + + SimpleInstruction::Abort => Opcodes::ABORT, + + SimpleInstruction::LdU16 => Opcodes::LD_U16, + SimpleInstruction::LdU32 => Opcodes::LD_U32, + SimpleInstruction::LdU256 => Opcodes::LD_U256, + + SimpleInstruction::CastU16 => Opcodes::CAST_U16, + SimpleInstruction::CastU32 => Opcodes::CAST_U32, + SimpleInstruction::CastU256 => Opcodes::CAST_U256, + } +} + +impl GasMeter for StarcoinGasMeter { + #[inline] + fn charge_simple_instr(&mut self, instr: SimpleInstruction) -> PartialVMResult<()> { + let cost = self.gas_params.instr.simple_instr_cost(instr)?; + #[cfg(testing)] + info!( + "simple_instr {:#?} cost InternalGasUnits({}) {}", + simple_instr_to_opcode(instr), + cost, + self.charge + ); + self.deduct_gas(cost) + } + + fn charge_pop(&mut self, _popped_val: impl ValueView) -> PartialVMResult<()> { + let params = &self.gas_params.instr; + let cost = params.pop; + #[cfg(testing)] + info!( + "simple_instr pop cost InternalGasUnits({}) {}", + cost, self.charge + ); + self.deduct_gas(cost) + } + + #[inline] + fn charge_call( + &mut self, + _module_id: &ModuleId, + _func_name: &str, + args: impl ExactSizeIterator, + _num_locals: NumArgs, + ) -> PartialVMResult<()> { + let params = &self.gas_params.instr; + // Note args.len() may be zero, can't use args.len() + 1 directly + let cost1 = cal_instr_with_arg(params.call_per_arg, NumArgs::new(1)); + #[cfg(testing)] + info!("CALL cost InternalGasUnits({}) {}", cost1, self.charge); + let cost2 = cal_instr_with_arg(params.call_per_arg, NumArgs::new(args.len() as u64)); + #[cfg(testing)] + info!("CALL cost InternalGasUnits({}) {}", cost2, self.charge); + self.deduct_gas(cost1 + cost2) + } + + #[inline] + fn charge_call_generic( + &mut self, + _module_id: &ModuleId, + _func_name: &str, + ty_args: impl ExactSizeIterator, + args: impl ExactSizeIterator, + _num_locals: NumArgs, + ) -> PartialVMResult<()> { + let params = &self.gas_params.instr; + // Note args.len() may be zero, can't use ty_args.len() + args.len() + 1 directly + let cost1 = cal_instr_with_arg( + params.call_generic_per_arg, + NumArgs::new((ty_args.len() + 1) as u64), + ); + #[cfg(testing)] + info!( + "CALL_GENERIC cost InternalGasUnits({}) {}", + cost1, self.charge + ); + let cost2 = + cal_instr_with_arg(params.call_generic_per_arg, NumArgs::new(args.len() as u64)); + #[cfg(testing)] + info!( + "CALL_GENERIC cost InternalGasUnits({}) {}", + cost2, self.charge + ); + self.deduct_gas(cost1 + cost2) + } + + #[inline] + fn charge_ld_const(&mut self, size: NumBytes) -> PartialVMResult<()> { + let instr = &self.gas_params.instr; + let cost = cal_instr_with_byte(instr.ld_const_per_byte, size); + #[cfg(testing)] + info!("LD_CONST cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + fn charge_ld_const_after_deserialization( + &mut self, + _val: impl ValueView, + ) -> PartialVMResult<()> { + Ok(()) + } + + #[inline] + fn charge_copy_loc(&mut self, val: impl ValueView) -> PartialVMResult<()> { + let instr_params = &self.gas_params.instr; + let cost = cal_instr_with_size( + instr_params.copy_loc_per_abs_mem_unit, + val.legacy_abstract_memory_size(), + ); + #[cfg(testing)] + info!("COPY_LOC cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_move_loc(&mut self, val: impl ValueView) -> PartialVMResult<()> { + let instr_params = &self.gas_params.instr; + let cost = cal_instr_with_size( + instr_params.move_loc_per_abs_mem_unit, + val.legacy_abstract_memory_size(), + ); + #[cfg(testing)] + info!("MOVE_LOC cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_store_loc(&mut self, val: impl ValueView) -> PartialVMResult<()> { + let instr_params = &self.gas_params.instr; + let cost = cal_instr_with_size( + instr_params.st_loc_per_abs_mem_unit, + val.legacy_abstract_memory_size(), + ); + #[cfg(testing)] + info!("ST_LOC cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_pack( + &mut self, + is_generic: bool, + args: impl ExactSizeIterator, + ) -> PartialVMResult<()> { + let field_count = AbstractMemorySize::new(args.len() as u64); + let params = &self.gas_params.instr; + let size = args.fold(field_count, |acc, val| { + acc + val.legacy_abstract_memory_size() + }); + let cost = match is_generic { + false => cal_instr_with_size(params.pack_per_abs_mem_unit, size), + true => cal_instr_with_size(params.pack_generic_per_abs_mem_unit, size), + }; + #[cfg(testing)] + { + if is_generic { + info!( + "PACK_GENERIC cost InternalGasUnits({}) {}", + cost, self.charge + ); + } else { + info!("PACK cost InternalGasUnits({}) {}", cost, self.charge); + } + } + self.deduct_gas(cost) + } + + #[inline] + fn charge_unpack( + &mut self, + is_generic: bool, + args: impl ExactSizeIterator, + ) -> PartialVMResult<()> { + #[cfg(testing)] + let opcode = { + if is_generic { + Opcodes::UNPACK_GENERIC + } else { + Opcodes::UNPACK + } + }; + let params = &self.gas_params.instr; + let param = if is_generic { + params.unpack_generic_per_abs_mem_unit + } else { + params.unpack_per_abs_mem_unit + }; + let field_count = AbstractMemorySize::new(args.len() as u64); + let mut cost = cal_instr_with_size(param, field_count); + #[cfg(testing)] + info!( + "{:#?} cost InternalGasUnits({}) {}", + opcode, cost, self.charge + ); + for val in args { + let cost2 = cal_instr_with_size(param, val.legacy_abstract_memory_size()); + #[cfg(testing)] + info!( + "{:#?} cost InternalGasUnits({}) {}", + opcode, cost2, self.charge + ); + cost += cost2; + } + self.deduct_gas(cost) + } + + #[inline] + fn charge_read_ref(&mut self, val: impl ValueView) -> PartialVMResult<()> { + let cost = cal_instr_with_size( + self.gas_params.instr.read_ref_per_abs_mem_unit, + val.legacy_abstract_memory_size(), + ); + #[cfg(testing)] + info!("READ_REF cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_write_ref( + &mut self, + val: impl ValueView, + _old_val: impl ValueView, + ) -> PartialVMResult<()> { + let cost = cal_instr_with_size( + self.gas_params.instr.write_ref_per_abs_mem_unit, + val.legacy_abstract_memory_size(), + ); + #[cfg(testing)] + info!("WRITE_REF cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_eq(&mut self, lhs: impl ValueView, rhs: impl ValueView) -> PartialVMResult<()> { + let instr_params = &self.gas_params.instr; + let cost = cal_instr_with_size( + instr_params.eq_per_abs_mem_unit, + lhs.legacy_abstract_memory_size() + rhs.legacy_abstract_memory_size(), + ); + #[cfg(testing)] + info!("EQ cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_neq(&mut self, lhs: impl ValueView, rhs: impl ValueView) -> PartialVMResult<()> { + let instr_params = &self.gas_params.instr; + let cost = cal_instr_with_size( + instr_params.eq_per_abs_mem_unit, + lhs.legacy_abstract_memory_size() + rhs.legacy_abstract_memory_size(), + ); + #[cfg(testing)] + info!("NEQ cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_borrow_global( + &mut self, + _is_mut: bool, + is_generic: bool, + _ty: impl TypeView, + is_success: bool, + ) -> PartialVMResult<()> { + let cost = if !is_success { + 0.into() + } else { + let params = &self.gas_params.instr; + // NOTE only use mut see https://github.com/starcoinorg/move/blob/starcoin-main/language/move-vm/runtime/src/interpreter.rs#L1018-L1030 + let param = match is_generic { + false => params.mut_borrow_global_per_abs_mem_unit, + true => params.mut_borrow_global_generic_per_abs_mem_unit, + }; + cal_instr_with_size(param, REFERENCE_SIZE) + }; + #[cfg(testing)] + let opcode = match is_generic { + false => Opcodes::MUT_BORROW_GLOBAL, + true => Opcodes::MUT_BORROW_GLOBAL_GENERIC, + }; + #[cfg(testing)] + info!( + "{:#?} cost InternalGasUnits({}) {}", + opcode, cost, self.charge + ); + self.deduct_gas(cost) + } + + #[inline] + fn charge_exists( + &mut self, + is_generic: bool, + _ty: impl TypeView, + exists: bool, + ) -> PartialVMResult<()> { + let params = &self.gas_params.instr; + let param = match is_generic { + false => params.exists_per_abs_mem_unit, + true => params.exists_generic_per_abs_mem_unit, + }; + let size = match exists { + false => MIN_EXISTS_DATA_SIZE, + true => REFERENCE_SIZE, + }; + let cost = cal_instr_with_size(param, size); + #[cfg(testing)] + let opcode = match is_generic { + false => Opcodes::EXISTS, + true => Opcodes::EXISTS_GENERIC, + }; + #[cfg(testing)] + info!( + "{:#?} cost InternalGasUnits({}) {}", + opcode, cost, self.charge + ); + self.deduct_gas(cost) + } + + #[inline] + fn charge_move_from( + &mut self, + is_generic: bool, + _ty: impl TypeView, + val: Option, + ) -> PartialVMResult<()> { + if let Some(val) = val { + let params = &self.gas_params.instr; + let param = match is_generic { + false => params.move_from_per_abs_mem_unit, + true => params.move_from_generic_per_abs_mem_unit, + }; + let cost = cal_instr_with_size(param, val.legacy_abstract_memory_size()); + #[cfg(testing)] + let opcode = match is_generic { + false => Opcodes::MOVE_FROM, + true => Opcodes::MOVE_FROM_GENERIC, + }; + #[cfg(testing)] + info!( + "MOVE_FROM {:#?} cost InternalGasUnits({}) {}", + opcode, cost, self.charge + ); + return self.deduct_gas(cost); + } + Ok(()) + } + + #[inline] + fn charge_move_to( + &mut self, + is_generic: bool, + _ty: impl TypeView, + val: impl ValueView, + is_success: bool, + ) -> PartialVMResult<()> { + let cost = if !is_success { + 0.into() + } else { + let params = &self.gas_params.instr; + let param = match is_generic { + false => params.move_to_per_abs_mem_unit, + true => params.move_to_generic_per_abs_mem_unit, + }; + cal_instr_with_size(param, val.legacy_abstract_memory_size()) + }; + #[cfg(testing)] + let opcode = match is_generic { + false => Opcodes::MOVE_TO, + true => Opcodes::MOVE_TO_GENERIC, + }; + #[cfg(testing)] + info!( + "charge_MOVE_TO {:#?} cost InternalGasUnits({}) {}", + opcode, cost, self.charge + ); + self.deduct_gas(cost) + } + + #[inline] + fn charge_vec_pack<'a>( + &mut self, + _ty: impl TypeView + 'a, + args: impl ExactSizeIterator, + ) -> PartialVMResult<()> { + let num_args = NumArgs::new(args.len() as u64); + let params = &self.gas_params.instr; + let cost = cal_instr_with_arg(params.vec_pack_per_elem, num_args); + #[cfg(testing)] + info!("VEC_PACK cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_vec_len(&mut self, _ty: impl TypeView) -> PartialVMResult<()> { + let cost = self.gas_params.instr.vec_len_base; + #[cfg(testing)] + info!("VEC_LEN cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_vec_borrow( + &mut self, + is_mut: bool, + _ty: impl TypeView, + is_success: bool, + ) -> PartialVMResult<()> { + let cost = if !is_success { + 0.into() + } else { + let params = &self.gas_params.instr; + match is_mut { + false => params.vec_imm_borrow_base, + true => params.vec_mut_borrow_base, + } + }; + #[cfg(testing)] + let opcode = match is_mut { + false => Opcodes::VEC_MUT_BORROW, + true => Opcodes::VEC_IMM_BORROW, + }; + #[cfg(testing)] + info!( + "{:#?} cost InternalGasUnits({}) {}", + opcode, cost, self.charge + ); + self.deduct_gas(cost) + } + + #[inline] + fn charge_vec_push_back( + &mut self, + _ty: impl TypeView, + val: impl ValueView, + ) -> PartialVMResult<()> { + let cost = cal_instr_with_size( + self.gas_params.instr.vec_push_back_per_abs_mem_unit, + val.legacy_abstract_memory_size(), + ); + #[cfg(testing)] + info!( + "VEC_PUSH_BACK cost InternalGasUnits({}) {}", + cost, self.charge + ); + self.deduct_gas(cost) + } + + #[inline] + fn charge_vec_pop_back( + &mut self, + _ty: impl TypeView, + _val: Option, + ) -> PartialVMResult<()> { + let cost = self.gas_params.instr.vec_pop_back_base; + #[cfg(testing)] + info!( + "VEC_POP_BACK cost InternalGasUnits({}) {}", + cost, self.charge + ); + self.deduct_gas(cost) + } + + #[inline] + fn charge_vec_unpack( + &mut self, + _ty: impl TypeView, + expect_num_elements: NumArgs, + _elems: impl ExactSizeIterator, + ) -> PartialVMResult<()> { + let cost = cal_instr_with_arg( + self.gas_params.instr.vec_unpack_per_expected_elem, + expect_num_elements, + ); + #[cfg(testing)] + info!("VEC_UNPACK cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_vec_swap(&mut self, _ty: impl TypeView) -> PartialVMResult<()> { + let cost = self.gas_params.instr.vec_swap_base; + #[cfg(testing)] + info!("VEC_SWAP cost InternalGasUnits({}) {}", cost, self.charge); + self.deduct_gas(cost) + } + + #[inline] + fn charge_load_resource( + &mut self, + _loaded: Option<(NumBytes, impl ValueView)>, + ) -> PartialVMResult<()> { + Ok(()) + } + + #[inline] + fn charge_native_function( + &mut self, + amount: InternalGas, + _ret_vals: Option>, + ) -> PartialVMResult<()> { + #[cfg(testing)] + info!( + "NATIVE_FUNCTION cost InternalGasUnits({}) {}", + amount, self.charge + ); + self.deduct_gas(amount) + } + + fn charge_native_function_before_execution( + &mut self, + _ty_args: impl ExactSizeIterator, + _args: impl ExactSizeIterator, + ) -> PartialVMResult<()> { + Ok(()) + } + + fn charge_drop_frame( + &mut self, + _locals: impl Iterator, + ) -> PartialVMResult<()> { + Ok(()) + } +} diff --git a/vm/starcoin-gas/src/lib.rs b/vm/starcoin-gas/src/lib.rs new file mode 100644 index 0000000000..cf09d8365e --- /dev/null +++ b/vm/starcoin-gas/src/lib.rs @@ -0,0 +1,28 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +//! This crate is the core of the gas metering system of the Starcoin blockchain. +//! +//! More specifically, it +//! - Is home to the gas meter implementation +//! - Defines the gas parameters and formulae for instructions +//! - Defines the gas parameters for transactions +//! - Sets the initial values for all gas parameters, including the instruction, transaction +//! move-stdlib and starcoin-framework ones. +//! - Defines a bi-directional mapping between the (Rust) gas parameter structs and their +//! corresponding representation on-chain. +//! +//! The reason why we need two different representations is that they serve different purposes: +//! - The Rust structs are used for quick (static) lookups by the gas meter and native functions +//! when calculating gas costs. +//! - The on-chain gas schedule needs to be extensible and unordered so we can upgrate it easily +//! in the future. + +mod gas_meter; + +pub use gas_meter::{NativeGasParameters, StarcoinGasMeter, StarcoinGasParameters}; +pub use move_core_types::gas_algebra::{ + Arg, Byte, GasQuantity, InternalGas, InternalGasPerArg, InternalGasPerByte, InternalGasUnit, + NumArgs, NumBytes, UnitDiv, +}; +pub use starcoin_gas_algebra_ext::InstructionGasParameters; diff --git a/vm/starcoin-transactional-test-harness/Cargo.toml b/vm/starcoin-transactional-test-harness/Cargo.toml index 397c02579e..18a61bf932 100644 --- a/vm/starcoin-transactional-test-harness/Cargo.toml +++ b/vm/starcoin-transactional-test-harness/Cargo.toml @@ -5,28 +5,39 @@ name = "tests" [dependencies] anyhow = { workspace = true } bcs = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } dashmap = { workspace = true } either = { workspace = true } hex = { workspace = true } itertools = { workspace = true } -jsonrpc-client-transports = { features = [ "http", "ipc", "ws", "arbitrary_precision",], workspace = true } -jsonrpc-core-client = { features = [ "http", "ipc", "ws", "arbitrary_precision",], workspace = true } +jsonrpc-client-transports = { features = [ + "http", + "ipc", + "ws", + "arbitrary_precision", +], workspace = true } +jsonrpc-core-client = { features = [ + "http", + "ipc", + "ws", + "arbitrary_precision", +], workspace = true } log = { workspace = true } move-binary-format = { workspace = true } move-command-line-common = { workspace = true } move-compiler = { workspace = true } move-core-types = { workspace = true } move-transactional-test-runner = { workspace = true } +move-table-extension = { workspace = true } once_cell = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } tempfile = { workspace = true } -tokio = { features = [ "full",], workspace = true } +tokio = { features = ["full"], workspace = true } async-trait = { workspace = true } bcs-ext = { workspace = true } futures = { workspace = true } -jsonrpc-core = { features = [ "arbitrary_precision",], workspace = true } +jsonrpc-core = { features = ["arbitrary_precision"], workspace = true } jsonrpc-derive = { workspace = true } jsonrpc-http-server = { workspace = true } move-resource-viewer = { workspace = true } diff --git a/vm/starcoin-transactional-test-harness/src/fork_state.rs b/vm/starcoin-transactional-test-harness/src/fork_state.rs index f2b7bc3693..6266115f3b 100644 --- a/vm/starcoin-transactional-test-harness/src/fork_state.rs +++ b/vm/starcoin-transactional-test-harness/src/fork_state.rs @@ -9,6 +9,7 @@ use anyhow::{anyhow, Result}; use move_core_types::account_address::AccountAddress; use starcoin_state_api::{ ChainStateAsyncService, ChainStateReader, StateNodeStore, StateView, StateWithProof, + StateWithTableItemProof, }; use starcoin_statedb::ChainStateDB; use starcoin_storage::state_node::StateStorage; @@ -19,6 +20,8 @@ use starcoin_state_tree::StateNode; use starcoin_types::access_path::AccessPath; use starcoin_types::account_state::AccountState; use starcoin_types::state_set::AccountStateSet; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::state_store::table::TableHandle; use tokio::runtime::Runtime; pub struct MockStateNodeStore { @@ -91,7 +94,8 @@ impl MockChainStateAsyncService { #[async_trait::async_trait] impl ChainStateAsyncService for MockChainStateAsyncService { async fn get(self, access_path: AccessPath) -> Result>> { - self.state_db().get(&access_path) + self.state_db() + .get_state_value(&StateKey::AccessPath(access_path)) } async fn get_with_proof(self, access_path: AccessPath) -> Result { @@ -135,4 +139,23 @@ impl ChainStateAsyncService for MockChainStateAsyncService { let reader = self.state_db().fork_at(state_root); reader.get_account_state(&account_address) } + + async fn get_with_table_item_proof( + self, + handle: TableHandle, + key: Vec, + ) -> Result { + let reader = self.state_db(); + reader.get_with_table_item_proof(&handle, &key) + } + + async fn get_with_table_item_proof_by_root( + self, + handle: TableHandle, + key: Vec, + state_root: HashValue, + ) -> Result { + let reader = self.state_db().fork_at(state_root); + reader.get_with_table_item_proof(&handle, &key) + } } diff --git a/vm/starcoin-transactional-test-harness/src/lib.rs b/vm/starcoin-transactional-test-harness/src/lib.rs index 406604c300..cb67535614 100644 --- a/vm/starcoin-transactional-test-harness/src/lib.rs +++ b/vm/starcoin-transactional-test-harness/src/lib.rs @@ -5,16 +5,17 @@ use crate::context::ForkContext; use anyhow::{bail, format_err, Result}; use clap::{Args, CommandFactory, Parser}; use move_binary_format::{file_format::CompiledScript, CompiledModule}; +use move_command_line_common::address::ParsedAddress; +use move_command_line_common::files::verify_and_create_named_address_mapping; use move_compiler::compiled_unit::{AnnotatedCompiledUnit, CompiledUnitEnum}; -use move_compiler::shared::{NumberFormat, NumericalAddress}; -use move_compiler::{shared::verify_and_create_named_address_mapping, FullyCompiledProgram}; +use move_compiler::shared::{NumberFormat, NumericalAddress, PackagePaths}; +use move_compiler::{construct_pre_compiled_lib, FullyCompiledProgram}; use move_core_types::language_storage::StructTag; +use move_core_types::value::MoveValue; use move_core_types::{ account_address::AccountAddress, - gas_schedule::GasAlgebra, identifier::{IdentStr, Identifier}, language_storage::{ModuleId, TypeTag}, - transaction_argument::TransactionArgument, }; use move_transactional_test_runner::framework; use move_transactional_test_runner::tasks::{ @@ -22,9 +23,10 @@ use move_transactional_test_runner::tasks::{ }; use move_transactional_test_runner::{ framework::{CompiledState, MoveTestAdapter}, - tasks::{InitCommand, RawAddress, SyntaxChoice, TaskInput}, + tasks::{InitCommand, SyntaxChoice, TaskInput}, vm_test_harness::view_resource_in_move_storage, }; +use once_cell::sync::Lazy; use serde::Deserialize; use serde::Serialize; use serde_json::Value; @@ -48,10 +50,13 @@ use starcoin_types::{ account_config::{genesis_address, AccountResource}, transaction::RawUserTransaction, }; +use starcoin_vm_runtime::session::SerializedReturnValues; use starcoin_vm_runtime::{data_cache::RemoteStorage, starcoin_vm::StarcoinVM}; use starcoin_vm_types::account_config::{ association_address, core_code_address, STC_TOKEN_CODE_STR, }; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::state_view::StateView; use starcoin_vm_types::transaction::authenticator::AccountPrivateKey; use starcoin_vm_types::transaction::SignedUserTransaction; use starcoin_vm_types::write_set::{WriteOp, WriteSetMut}; @@ -62,10 +67,8 @@ use starcoin_vm_types::{ move_resource::MoveResource, on_chain_config::VMConfig, on_chain_resource, - state_view::StateView, token::{stc::stc_type_tag, token_code::TokenCode}, transaction::{Module, Script, ScriptFunction, Transaction, TransactionStatus}, - transaction_argument::convert_txn_args, vm_status::KeptVMStatus, }; use std::collections::HashMap; @@ -74,7 +77,7 @@ use std::io::{Read, Write}; use std::path::PathBuf; use std::sync::Mutex; use std::{collections::BTreeMap, convert::TryInto, path::Path, str::FromStr}; -use stdlib::{starcoin_framework_named_addresses, G_PRECOMPILED_STARCOIN_FRAMEWORK}; +use stdlib::{starcoin_framework_named_addresses, stdlib_files}; use tempfile::{NamedTempFile, TempDir}; pub mod context; @@ -122,9 +125,9 @@ pub struct StarcoinRunArgs {} #[derive(Debug, Parser)] #[clap(name = "faucet")] struct FaucetSub { - #[clap(long="addr", parse(try_from_str=RawAddress::parse))] + #[clap(long="addr", parse(try_from_str=ParsedAddress::parse))] /// faucet target address - address: RawAddress, + address: ParsedAddress, #[clap(long = "amount", default_value = "100000000000")] /// faucet amount initial_balance: u128, @@ -133,8 +136,8 @@ struct FaucetSub { #[derive(Debug, Parser)] #[clap(name = "block")] struct BlockSub { - #[clap(long, parse(try_from_str=RawAddress::parse))] - author: Option, + #[clap(long, parse(try_from_str=ParsedAddress::parse))] + author: Option, #[clap(long)] timestamp: Option, #[clap(long)] @@ -173,13 +176,13 @@ pub struct CallAPISub { #[clap(name = "package")] pub struct PackageSub { #[clap( - long = "signers", - parse(try_from_str = RawAddress::parse), - takes_value(true), - multiple_values(true), - multiple_occurrences(true) + long = "signers", + parse(try_from_str = ParsedAddress::parse), + takes_value(true), + multiple_values(true), + multiple_occurrences(true) )] - signers: Vec, + signers: Vec, #[clap(long = "init-function")] /// module init function. init_function: Option, @@ -196,12 +199,12 @@ pub struct PackageSub { pub struct DeploySub { #[clap( long = "signers", - parse(try_from_str = RawAddress::parse), + parse(try_from_str = ParsedAddress::parse), takes_value(true), multiple_values(true), multiple_occurrences(true) )] - signers: Vec, + signers: Vec, /// max gas for transaction. #[clap(long = "gas-budget")] gas_budget: Option, @@ -214,10 +217,10 @@ pub struct DeploySub { #[clap(name = "var")] pub struct VarSub { #[clap(name="var", - parse(try_from_str = parse_var), - takes_value(true), - multiple_values(true), - multiple_occurrences(true) + parse(try_from_str = parse_var), + takes_value(true), + multiple_values(true), + multiple_occurrences(true) )] /// variables with format =, =,... var: Vec<(String, String)>, @@ -235,16 +238,16 @@ pub struct ReadJsonSub { pub enum StarcoinSubcommands { #[clap(name = "faucet")] Faucet { - #[clap(long="addr", parse(try_from_str=RawAddress::parse))] - address: RawAddress, + #[clap(long="addr", parse(try_from_str=ParsedAddress::parse))] + address: ParsedAddress, #[clap(long = "amount", default_value = "100000000000")] initial_balance: u128, }, #[clap(name = "block")] NewBlock { - #[clap(long, parse(try_from_str=RawAddress::parse))] - author: Option, + #[clap(long, parse(try_from_str=ParsedAddress::parse))] + author: Option, #[clap(long)] timestamp: Option, #[clap(long)] @@ -285,12 +288,12 @@ pub enum StarcoinSubcommands { Deploy { #[clap( long = "signers", - parse(try_from_str = RawAddress::parse), + parse(try_from_str = ParsedAddress::parse), takes_value(true), multiple_values(true), multiple_occurrences(true) )] - signers: Vec, + signers: Vec, #[clap(long = "gas-budget")] gas_budget: Option, #[clap(name = "mv-or-package-file")] @@ -300,10 +303,10 @@ pub enum StarcoinSubcommands { #[clap(name = "var")] Var { #[clap(name="var", - parse(try_from_str = parse_var), - takes_value(true), - multiple_values(true), - multiple_occurrences(true) + parse(try_from_str = parse_var), + takes_value(true), + multiple_values(true), + multiple_occurrences(true) )] var: Vec<(String, String)>, }, @@ -487,7 +490,7 @@ impl<'a> StarcoinTestAdapter<'a> { let account_blob = self .context .storage - .get(&account_access_path)? + .get_state_value(&StateKey::AccessPath(account_access_path))? .ok_or_else(|| { anyhow::anyhow!( "Failed to fetch account resource under address {}. Has the account been created?", @@ -512,7 +515,7 @@ impl<'a> StarcoinTestAdapter<'a> { let balance_blob = self .context .storage - .get(&balance_access_path)? + .get_state_value(&StateKey::AccessPath(balance_access_path))? .ok_or_else(|| { anyhow::anyhow!( "Failed to fetch balance resource under address {}.", @@ -545,7 +548,7 @@ impl<'a> StarcoinTestAdapter<'a> { { let mut writes = WriteSetMut::default(); writes.push(( - AccessPath::resource_access_path( + StateKey::AccessPath(AccessPath::resource_access_path( genesis_address(), StructTag { address: genesis_address(), @@ -553,7 +556,7 @@ impl<'a> StarcoinTestAdapter<'a> { name: Identifier::new("SignerDelegated")?, type_params: vec![], }, - ), + )), WriteOp::Deletion, )); self.context.apply_write_set(writes.freeze().unwrap())?; @@ -606,12 +609,12 @@ impl<'a> StarcoinTestAdapter<'a> { .maximum_number_of_gas_units; let gas_unit_price = 1; let max_gas_amount = if gas_unit_price == 0 { - max_number_of_gas_units.get() + max_number_of_gas_units } else { let account_balance = self.fetch_balance_resource(signer_addr, stc_type_tag().to_string())?; std::cmp::min( - max_number_of_gas_units.get(), + max_number_of_gas_units, (account_balance.token() / gas_unit_price as u128) as u64, ) }; @@ -734,7 +737,7 @@ impl<'a> StarcoinTestAdapter<'a> { fn handle_faucet( &mut self, - addr: RawAddress, + addr: ParsedAddress, initial_balance: u128, ) -> Result<(Option, Option)> { let sender = association_address(); @@ -742,8 +745,12 @@ impl<'a> StarcoinTestAdapter<'a> { let params = self.fetch_default_transaction_parameters(&sender)?; match &addr { - RawAddress::Named(name) => { - if !self.compiled_state.contain_name_address(name.as_str()) { + ParsedAddress::Named(name) => { + if !self + .compiled_state + .named_address_mapping + .contains_key(name.as_str()) + { // make it deterministic. let addr = AccountAddress::from_bytes( @@ -751,19 +758,13 @@ impl<'a> StarcoinTestAdapter<'a> { [0..AccountAddress::LENGTH], )?; - self.compiled_state - .add_named_addresses({ - let mut addrs = BTreeMap::default(); - addrs.insert( - name.as_str(), - NumericalAddress::new(addr.into_bytes(), NumberFormat::Hex), - ); - addrs - }) - .unwrap(); + self.compiled_state.named_address_mapping.insert( + name.clone(), + NumericalAddress::new(addr.into_bytes(), NumberFormat::Hex), + ); } } - RawAddress::Anonymous(_addr) => {} + ParsedAddress::Numerical(_addr) => {} } let addr = self.compiled_state.resolve_address(&addr); @@ -806,7 +807,7 @@ impl<'a> StarcoinTestAdapter<'a> { fn handle_new_block( &mut self, - author: Option, + author: Option, timestamp: Option, number: Option, uncles: Option, @@ -924,11 +925,21 @@ impl<'a> StarcoinTestAdapter<'a> { } }; - self.compiled_state.add(named_addr_opt, module.clone()); + self.compiled_state + .add_precompiled(named_addr_opt, module.clone()); let package = Self::build_package( - vec![module], + vec![module.clone()], init_function.map(|fid| { + let move_args = &args + .unwrap_or_default() + .into_iter() + .map(|v| v.0) + .collect::>(); + let move_args = move_args + .iter() + .map(|arg| MoveValue::from(arg.clone())) + .collect::>(); ScriptFunction::new( fid.0.module, fid.0.function, @@ -937,13 +948,7 @@ impl<'a> StarcoinTestAdapter<'a> { .into_iter() .map(|v| v.0) .collect(), - convert_txn_args( - &args - .unwrap_or_default() - .into_iter() - .map(|v| v.0) - .collect::>(), - ), + convert_txn_args(&move_args), ) }), )?; @@ -965,12 +970,17 @@ impl<'a> StarcoinTestAdapter<'a> { package_hash, hex, }; + self.compiled_state().add_with_source_file( + named_addr_opt, + module, + (data_path.to_owned(), data), + ); Ok((warnings_opt, Some(serde_json::to_value(&package_result)?))) } fn handle_deploy( &mut self, - signers: Vec, + signers: Vec, gas_budget: Option, package_path: &Path, ) -> Result<(Option, Option)> { @@ -1027,6 +1037,7 @@ impl<'a> StarcoinTestAdapter<'a> { impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { type ExtraPublishArgs = StarcoinPublishArgs; + type ExtraValueArgs = (); type ExtraRunArgs = StarcoinRunArgs; type Subcommand = StarcoinSubcommands; type ExtraInitArgs = ExtraInitArgs; @@ -1040,11 +1051,10 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { } fn init( - _test_path: &Path, default_syntax: SyntaxChoice, pre_compiled_deps: Option<&'a FullyCompiledProgram>, task_opt: Option>, - ) -> Self { + ) -> (Self, Option) { let (additional_mapping, extra_arg) = match task_opt.map(|t| t.command) { Some((InitCommand { named_addresses }, extra_arg)) => ( verify_and_create_named_address_mapping(named_addresses).unwrap(), @@ -1130,10 +1140,10 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { } writes.push(( - AccessPath::code_access_path( + StateKey::AccessPath(AccessPath::code_access_path( m.named_module.address.into_inner(), Identifier::new(m.named_module.name.as_str()).unwrap(), - ), + )), WriteOp::Value({ let mut bytes = vec![]; m.named_module.module.serialize(&mut bytes).unwrap(); @@ -1146,7 +1156,7 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { } let mut me = Self { - compiled_state: CompiledState::new(named_address_mapping, pre_compiled_deps), + compiled_state: CompiledState::new(named_address_mapping, pre_compiled_deps, None), default_syntax, context, tempdir: TempDir::new().unwrap(), @@ -1163,7 +1173,7 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { me.handle_new_block(None, None, None, None) .expect("init test adapter failed"); }; - me + (me, None) } fn publish_module( @@ -1172,7 +1182,7 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { named_addr_opt: Option, gas_budget: Option, _extra: Self::ExtraPublishArgs, - ) -> anyhow::Result<(Option, Option)> { + ) -> anyhow::Result<(Option, CompiledModule, Option)> { let module_id = module.self_id(); let signer = match named_addr_opt { Some(name) => self.compiled_state.resolve_named_address(name.as_str()), @@ -1180,7 +1190,7 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { }; let params = self.fetch_default_transaction_parameters(&signer)?; - let package = Self::build_package(vec![module], None)?; + let package = Self::build_package(vec![module.clone()], None)?; let txn = RawUserTransaction::new_package( signer, params.sequence_number, @@ -1194,9 +1204,10 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { let output = self.run_transaction(txn)?; match output.output.status { - TransactionStatusView::Executed => Ok((None, None)), + TransactionStatusView::Executed => Ok((None, module, None)), _ => Ok(( Some(format!("Publish failure: {:?}", output.output.status)), + module, Some(serde_json::to_value(&output)?), )), } @@ -1206,11 +1217,11 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { &mut self, script: CompiledScript, type_args: Vec, - signers: Vec, - args: Vec, + signers: Vec, + args: Vec, gas_budget: Option, _extra_args: Self::ExtraRunArgs, - ) -> anyhow::Result<(Option, Option)> { + ) -> anyhow::Result<(Option, SerializedReturnValues, Option)> { assert!(!signers.is_empty()); if signers.len() != 1 { panic!("Expected 1 signer, got {}.", signers.len()); @@ -1237,8 +1248,13 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { gas_used: output.output.gas_used.0, status: output.output.status.clone(), }; + let value = SerializedReturnValues { + mutable_reference_outputs: vec![], + return_values: vec![], + }; Ok(( Some(serde_json::to_string_pretty(&result)?), + value, Some(serde_json::to_value(&output)?), )) } @@ -1248,11 +1264,11 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { module: &ModuleId, function: &IdentStr, type_args: Vec, - signers: Vec, - args: Vec, + signers: Vec, + args: Vec, gas_budget: Option, _extra_args: Self::ExtraRunArgs, - ) -> anyhow::Result<(Option, Option)> { + ) -> anyhow::Result<(Option, SerializedReturnValues, Option)> { { assert!(!signers.is_empty()); if signers.len() != 1 { @@ -1283,8 +1299,13 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { gas_used: output.output.gas_used.0, status: output.output.status.clone(), }; + let value = SerializedReturnValues { + mutable_reference_outputs: vec![], + return_values: vec![], + }; Ok(( Some(serde_json::to_string_pretty(&result)?), + value, Some(serde_json::to_value(&output)?), )) } @@ -1347,15 +1368,24 @@ impl<'a> MoveTestAdapter<'a> for StarcoinTestAdapter<'a> { } } +fn convert_txn_args(args: &[MoveValue]) -> Vec> { + args.iter() + .map(|arg| { + arg.simple_serialize() + .expect("transaction arguments must serialize") + }) + .collect() +} + /// Run the Starcoin transactional test flow, using the given file as input. -pub fn run_test(path: &Path) -> Result<(), Box> { +pub fn run_test(path: &Path) -> Result<(), Box> { run_test_impl(path, Some(&*G_PRECOMPILED_STARCOIN_FRAMEWORK)) } -pub fn run_test_impl( +pub fn run_test_impl<'a>( path: &Path, - fully_compiled_program_opt: Option<&FullyCompiledProgram>, -) -> Result<(), Box> { + fully_compiled_program_opt: Option<&'a FullyCompiledProgram>, +) -> Result<(), Box> { framework::run_test_impl::(path, fully_compiled_program_opt) } @@ -1370,7 +1400,7 @@ pub fn print_help(task_name: Option) -> Result<()> { PrintBytecodeCommand::command().name("print-bytecode"), ); tasks.insert("publish", PublishCommand::command().name("publish")); - tasks.insert("run", RunCommand::command().name("run")); + tasks.insert("run", RunCommand::<()>::command().name("run")); tasks.insert("view", ViewCommand::command().name("view")); tasks.insert("faucet", FaucetSub::command().name("faucet")); tasks.insert("block", BlockSub::command().name("block")); @@ -1400,3 +1430,24 @@ pub fn print_help(task_name: Option) -> Result<()> { } } } + +pub static G_PRECOMPILED_STARCOIN_FRAMEWORK: Lazy = Lazy::new(|| { + let sources = stdlib_files(); + let program_res = construct_pre_compiled_lib( + vec![PackagePaths { + name: None, + paths: sources, + named_address_map: starcoin_framework_named_addresses(), + }], + None, + move_compiler::Flags::empty(), + ) + .unwrap(); + match program_res { + Ok(df) => df, + Err((files, errors)) => { + eprintln!("!!!Starcoin Framework failed to compile!!!"); + move_compiler::diagnostics::report_diagnostics(&files, errors) + } + } +}); diff --git a/vm/starcoin-transactional-test-harness/src/remote_state.rs b/vm/starcoin-transactional-test-harness/src/remote_state.rs index 59ce03fb73..8066300b06 100644 --- a/vm/starcoin-transactional-test-harness/src/remote_state.rs +++ b/vm/starcoin-transactional-test-harness/src/remote_state.rs @@ -7,9 +7,10 @@ use move_binary_format::errors::VMError; use move_core_types::resolver::{ModuleResolver, ResourceResolver}; use starcoin_crypto::HashValue; +use move_table_extension::{TableHandle, TableResolver}; use starcoin_rpc_api::chain::ChainApiClient; use starcoin_rpc_api::state::StateApiClient; -use starcoin_rpc_api::types::{BlockView, StateWithProofView}; +use starcoin_rpc_api::types::{BlockView, StateWithProofView, StateWithTableItemProofView}; use starcoin_state_api::ChainStateWriter; use starcoin_types::access_path::{AccessPath, DataPath}; use starcoin_types::account_address::AccountAddress; @@ -18,6 +19,8 @@ use starcoin_types::language_storage::{ModuleId, StructTag}; use starcoin_types::state_set::ChainStateSet; use starcoin_types::vm_error::StatusCode; use starcoin_vm_types::errors::{Location, PartialVMError, PartialVMResult, VMResult}; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::state_store::table::TableHandle as StarcoinTableHandle; use starcoin_vm_types::state_view::StateView; use starcoin_vm_types::write_set::WriteSet; use std::collections::BTreeMap; @@ -65,10 +68,10 @@ where A: StateView, B: StateView, { - fn get(&self, access_path: &AccessPath) -> Result>> { + fn get_state_value(&self, state_key: &StateKey) -> Result>> { match self { - SelectableStateView::A(a) => a.get(access_path), - SelectableStateView::B(b) => b.get(access_path), + SelectableStateView::A(a) => a.get_state_value(state_key), + SelectableStateView::B(b) => b.get_state_value(state_key), } } @@ -171,9 +174,9 @@ where A: StateView, B: StateView, { - fn get(&self, access_path: &AccessPath) -> Result>> { - match self.a.get(access_path)? { - None => self.b.get(access_path), + fn get_state_value(&self, state_key: &StateKey) -> Result>> { + match self.a.get_state_value(state_key)? { + None => self.b.get_state_value(state_key), Some(d) => Ok(Some(d)), } } @@ -281,7 +284,19 @@ impl RemoteRpcAsyncClient { .map_err(|_| PartialVMError::new(StatusCode::STORAGE_ERROR))?; Ok(state_with_proof.state.map(|v| v.0)) } - + pub async fn resolve_table_entry_async( + &self, + handle: &TableHandle, + key: &[u8], + ) -> Result>> { + let handle1: StarcoinTableHandle = StarcoinTableHandle(handle.0); + let state_table_item_proof: StateWithTableItemProofView = self + .state_client + .get_with_table_item_proof_by_root(handle1, key.to_vec(), self.state_root) + .await + .map_err(|_| PartialVMError::new(StatusCode::STORAGE_ERROR))?; + Ok(state_table_item_proof.key_proof.0.map(|v| v.0)) + } pub fn get_chain_client(&self) -> &ChainApiClient { &self.chain_client } @@ -362,15 +377,28 @@ impl ResourceResolver for RemoteViewer { } } +impl TableResolver for RemoteViewer { + fn resolve_table_entry(&self, handle: &TableHandle, key: &[u8]) -> Result>> { + let h = self.rt.handle().clone(); + h.block_on(self.svc.resolve_table_entry_async(handle, key)) + } +} + impl StateView for RemoteViewer { - fn get(&self, access_path: &AccessPath) -> Result>> { - match &access_path.path { - DataPath::Code(m) => Ok(self - .get_module(&ModuleId::new(access_path.address, m.clone())) - .map_err(|err| err.into_vm_status())?), - DataPath::Resource(s) => Ok(self - .get_resource(&access_path.address, s) - .map_err(|err| err.finish(Location::Undefined).into_vm_status())?), + fn get_state_value(&self, state_key: &StateKey) -> Result>> { + match state_key { + StateKey::AccessPath(access_path) => match &access_path.path { + DataPath::Code(m) => Ok(self + .get_module(&ModuleId::new(access_path.address, m.clone())) + .map_err(|err| err.into_vm_status())?), + DataPath::Resource(s) => Ok(self + .get_resource(&access_path.address, s) + .map_err(|err| err.finish(Location::Undefined).into_vm_status())?), + }, + StateKey::TableItem(table_item) => Ok(self.resolve_table_entry( + &move_table_extension::TableHandle(table_item.handle.0), + table_item.key.as_slice(), + )?), } } diff --git a/vm/starcoin-transactional-test-harness/tests/cases/arg_variable.exp b/vm/starcoin-transactional-test-harness/tests/cases/arg_variable.exp index 23b6ee1efe..8a5f3e1b4b 100644 --- a/vm/starcoin-transactional-test-harness/tests/cases/arg_variable.exp +++ b/vm/starcoin-transactional-test-harness/tests/cases/arg_variable.exp @@ -40,6 +40,6 @@ key 0x00000000000000000000000000000001::Account::Account { task 5 'run'. lines 11-17: { - "gas_used": 8639, + "gas_used": 8643, "status": "Executed" } diff --git a/vm/starcoin-transactional-test-harness/tests/cases/borrow_field_test.exp b/vm/starcoin-transactional-test-harness/tests/cases/borrow_field_test.exp new file mode 100644 index 0000000000..98991b558f --- /dev/null +++ b/vm/starcoin-transactional-test-harness/tests/cases/borrow_field_test.exp @@ -0,0 +1,7 @@ +processed 4 tasks + +task 3 'run'. lines 25-34: +{ + "gas_used": 22989, + "status": "Executed" +} diff --git a/vm/starcoin-transactional-test-harness/tests/cases/borrow_field_test.move b/vm/starcoin-transactional-test-harness/tests/cases/borrow_field_test.move new file mode 100644 index 0000000000..0bd32d6586 --- /dev/null +++ b/vm/starcoin-transactional-test-harness/tests/cases/borrow_field_test.move @@ -0,0 +1,36 @@ +//# init -n dev + +//# faucet --addr creator --amount 100000000000 + +//# publish +module creator::test { + struct TestObj has store{ + addr: address, + } + + fun use_field(_addr: address){} + + fun borrow_field(obj: &TestObj){ + use_field(obj.addr) + } + + + public fun test_borrow_field(addr: address) { + let obj = TestObj{addr}; + borrow_field(&obj); + let TestObj{addr:_} = obj; + } +} + +//# run --signers creator +script { + use StarcoinFramework::Signer; + use creator::test; + + fun main(s: signer) { + let addr = Signer::address_of(&s); + test::test_borrow_field(addr); + } +} + + diff --git a/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd.exp b/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd.exp index da095c4880..29df95dea7 100644 --- a/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd.exp +++ b/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd.exp @@ -2,12 +2,12 @@ processed 10 tasks task 5 'run'. lines 11-19: { - "gas_used": 15073, + "gas_used": 20673, "status": "Executed" } task 9 'run'. lines 27-33: { - "gas_used": 8697, + "gas_used": 8971, "status": "Executed" } diff --git a/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd.move b/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd.move index 040084404a..a7f558b97a 100644 --- a/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd.move +++ b/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd.move @@ -8,12 +8,12 @@ //# call-api state.get_with_proof_by_root_raw ["0x1/1/0x1::Account::Account","{{$.call-api[0].header.state_root}}"] -//# run --signers creator --args {{$.call-api[0].header.number}}u64 --args {{$.call-api[0].header.block_hash}} --args {{$.call-api[1]}} +//# run --signers creator --args {{$.call-api[0].header.number}}u64 --args b"{{$.call-api[0].header.block_hash}}" --args b"{{$.call-api[1]}}" script{ use StarcoinFramework::Vector; fun main(_sender: signer, block_number: u64, block_hash: vector, state_proof: vector){ assert!(block_number == 1, 1000); - assert!(Vector::length(&block_hash) == 32, 1001); + assert!(Vector::length(&block_hash) > 32, 1001); assert!(Vector::length(&state_proof) > 32, 1002); } } @@ -24,7 +24,7 @@ script{ //# call-api chain.info -//# run --signers creator --args {{$.call-api[2].head.block_hash}} --args {{$.call-api[3].head.parent_hash}} +//# run --signers creator --args b"{{$.call-api[2].head.block_hash}}" --args b"{{$.call-api[3].head.parent_hash}}" script { fun latest(_account: signer, parent_hash: vector, expect_parent_hash: vector) { assert!(parent_hash == expect_parent_hash, 1003) diff --git a/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd_halley.exp b/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd_halley.exp index 74ccceadca..0684e73322 100644 --- a/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd_halley.exp +++ b/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd_halley.exp @@ -2,6 +2,11 @@ processed 4 tasks task 3 'run'. lines 7-14: { - "gas_used": 10457, - "status": "Executed" + "gas_used": 0, + "status": { + "Discard": { + "status_code": "26", + "status_code_name": "FEATURE_UNDER_GATING" + } + } } diff --git a/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd_halley.move b/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd_halley.move index d38fab277a..309b14809e 100644 --- a/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd_halley.move +++ b/vm/starcoin-transactional-test-harness/tests/cases/call_api_cmd_halley.move @@ -4,7 +4,7 @@ //# call-api chain.get_block_by_number [1] -//# run --signers creator --args {{$.call-api[0].header.number}}u64 --args {{$.call-api[0].header.block_hash}} +//# run --signers creator --args {{$.call-api[0].header.number}}u64 --args b"{{$.call-api[0].header.block_hash}}" script{ use StarcoinFramework::Vector; fun main(_sender: signer, block_number: u64, block_hash: vector){ diff --git a/vm/starcoin-transactional-test-harness/tests/cases/publish_cmd.exp b/vm/starcoin-transactional-test-harness/tests/cases/publish_cmd.exp index fc5a4436b2..5a0810406e 100644 --- a/vm/starcoin-transactional-test-harness/tests/cases/publish_cmd.exp +++ b/vm/starcoin-transactional-test-harness/tests/cases/publish_cmd.exp @@ -1 +1,7 @@ -processed 3 tasks +processed 4 tasks + +task 3 'run'. lines 16-23: +{ + "gas_used": 11667, + "status": "Executed" +} diff --git a/vm/starcoin-transactional-test-harness/tests/cases/publish_cmd.move b/vm/starcoin-transactional-test-harness/tests/cases/publish_cmd.move index b25652240f..45144c40c0 100644 --- a/vm/starcoin-transactional-test-harness/tests/cases/publish_cmd.move +++ b/vm/starcoin-transactional-test-harness/tests/cases/publish_cmd.move @@ -3,7 +3,23 @@ //# faucet --addr creator --amount 100000000000 //# publish -module creator::test { +module creator::test { + struct Foo has key { + x: u64, + } + + public fun publish_foo(s: &signer) { + move_to(s, Foo { x: 500 }) + } +} + +//# run --signers creator +script { + use creator::test; + + fun main(s: signer) { + test::publish_foo(&s); + } } diff --git a/vm/starcoin-transactional-test-harness/tests/cases/sign_cmd.exp b/vm/starcoin-transactional-test-harness/tests/cases/sign_cmd.exp new file mode 100644 index 0000000000..72b1b5316e --- /dev/null +++ b/vm/starcoin-transactional-test-harness/tests/cases/sign_cmd.exp @@ -0,0 +1,7 @@ +processed 3 tasks + +task 2 'run'. lines 6-11: +{ + "gas_used": 8439, + "status": "Executed" +} diff --git a/vm/starcoin-transactional-test-harness/tests/cases/sign_cmd.move b/vm/starcoin-transactional-test-harness/tests/cases/sign_cmd.move new file mode 100644 index 0000000000..1d42858dec --- /dev/null +++ b/vm/starcoin-transactional-test-harness/tests/cases/sign_cmd.move @@ -0,0 +1,11 @@ +//# init -n test --public-keys SwapAdmin=0x5510ddb2f172834db92842b0b640db08c2bc3cd986def00229045d78cc528ac5 + +//# faucet --addr alice --amount 10000000000000000 + + +//# run --signers alice +script { + fun hello(_: signer) { + } +} +// check: EXECUTED \ No newline at end of file diff --git a/vm/starcoin-transactional-test-harness/tests/cases/var.exp b/vm/starcoin-transactional-test-harness/tests/cases/var.exp index 605f2835ee..36577ab01b 100644 --- a/vm/starcoin-transactional-test-harness/tests/cases/var.exp +++ b/vm/starcoin-transactional-test-harness/tests/cases/var.exp @@ -2,6 +2,6 @@ processed 5 tasks task 4 'run'. lines 9-16: { - "gas_used": 8769, + "gas_used": 8775, "status": "Executed" } diff --git a/vm/starcoin-transactional-test-harness/tests/cases/var.move b/vm/starcoin-transactional-test-harness/tests/cases/var.move index e99234936e..3ecb6116ed 100644 --- a/vm/starcoin-transactional-test-harness/tests/cases/var.move +++ b/vm/starcoin-transactional-test-harness/tests/cases/var.move @@ -6,7 +6,7 @@ //# var a=123 addr={{$.faucet[0].txn.raw_txn.decoded_payload.ScriptFunction.args[0]}} -//#run --signers creator --args {{$.var[0].a}}u64 --args {{$.var[0].addr}} --args {{$.read-json[0].id}}u64 +//#run --signers creator --args {{$.var[0].a}}u64 --args @{{$.var[0].addr}} --args {{$.read-json[0].id}}u64 script { fun main(_sender: signer, number: u64, addr: address, id: u64) { assert!(number == 123, 101); diff --git a/vm/stdlib/Cargo.toml b/vm/stdlib/Cargo.toml index 46efbd570f..660754126e 100644 --- a/vm/stdlib/Cargo.toml +++ b/vm/stdlib/Cargo.toml @@ -1,7 +1,7 @@ [dependencies] anyhow = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } fs_extra = { workspace = true } include_dir = { workspace = true } itertools = { workspace = true } diff --git a/vm/stdlib/compiled/latest/error_descriptions/error_descriptions.errmap b/vm/stdlib/compiled/latest/error_descriptions/error_descriptions.errmap index 69b33125e1..530aa12f43 100644 Binary files a/vm/stdlib/compiled/latest/error_descriptions/error_descriptions.errmap and b/vm/stdlib/compiled/latest/error_descriptions/error_descriptions.errmap differ diff --git a/vm/stdlib/compiled/latest/stdlib/000_BitOperators.mv b/vm/stdlib/compiled/latest/stdlib/000_BitOperators.mv index d22b483af4..5def61d413 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/000_BitOperators.mv and b/vm/stdlib/compiled/latest/stdlib/000_BitOperators.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/001_Debug.mv b/vm/stdlib/compiled/latest/stdlib/001_Debug.mv index ceb0961bf8..06446cdf8f 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/001_Debug.mv and b/vm/stdlib/compiled/latest/stdlib/001_Debug.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/002_EmptyScripts.mv b/vm/stdlib/compiled/latest/stdlib/002_EmptyScripts.mv index 61c71ee43d..1f874d057c 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/002_EmptyScripts.mv and b/vm/stdlib/compiled/latest/stdlib/002_EmptyScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/003_MintScripts.mv b/vm/stdlib/compiled/latest/stdlib/003_MintScripts.mv index bf26c30fba..e0d82f1a77 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/003_MintScripts.mv and b/vm/stdlib/compiled/latest/stdlib/003_MintScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/004_SIP_2.mv b/vm/stdlib/compiled/latest/stdlib/004_SIP_2.mv index a3f9e8a673..b495fd3d33 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/004_SIP_2.mv and b/vm/stdlib/compiled/latest/stdlib/004_SIP_2.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/005_SIP_3.mv b/vm/stdlib/compiled/latest/stdlib/005_SIP_3.mv index a9d0bbdce3..3885df5848 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/005_SIP_3.mv and b/vm/stdlib/compiled/latest/stdlib/005_SIP_3.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/006_SignedInteger64.mv b/vm/stdlib/compiled/latest/stdlib/006_SignedInteger64.mv index d11b7f7ab2..aaf806024f 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/006_SignedInteger64.mv and b/vm/stdlib/compiled/latest/stdlib/006_SignedInteger64.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/007_Vector.mv b/vm/stdlib/compiled/latest/stdlib/007_Vector.mv index d894886586..2caec61d0b 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/007_Vector.mv and b/vm/stdlib/compiled/latest/stdlib/007_Vector.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/008_Signer.mv b/vm/stdlib/compiled/latest/stdlib/008_Signer.mv index 48fc86fa4c..a84a73d58a 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/008_Signer.mv and b/vm/stdlib/compiled/latest/stdlib/008_Signer.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/009_Math.mv b/vm/stdlib/compiled/latest/stdlib/009_Math.mv index b46162a525..2d856ff651 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/009_Math.mv and b/vm/stdlib/compiled/latest/stdlib/009_Math.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/010_Errors.mv b/vm/stdlib/compiled/latest/stdlib/010_Errors.mv index 74bc6f4ca0..8d51430c07 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/010_Errors.mv and b/vm/stdlib/compiled/latest/stdlib/010_Errors.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/011_BCS.mv b/vm/stdlib/compiled/latest/stdlib/011_BCS.mv index 262389f2cd..6d70b3d7a8 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/011_BCS.mv and b/vm/stdlib/compiled/latest/stdlib/011_BCS.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/012_Event.mv b/vm/stdlib/compiled/latest/stdlib/012_Event.mv index 95c907adbe..471738d288 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/012_Event.mv and b/vm/stdlib/compiled/latest/stdlib/012_Event.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/013_Token.mv b/vm/stdlib/compiled/latest/stdlib/013_Token.mv index 09f0518f65..82d9b31f2b 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/013_Token.mv and b/vm/stdlib/compiled/latest/stdlib/013_Token.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/014_CoreAddresses.mv b/vm/stdlib/compiled/latest/stdlib/014_CoreAddresses.mv index 013b5f11e5..8977cc4410 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/014_CoreAddresses.mv and b/vm/stdlib/compiled/latest/stdlib/014_CoreAddresses.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/015_Timestamp.mv b/vm/stdlib/compiled/latest/stdlib/015_Timestamp.mv index 2e1d13a189..815d990752 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/015_Timestamp.mv and b/vm/stdlib/compiled/latest/stdlib/015_Timestamp.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/016_Option.mv b/vm/stdlib/compiled/latest/stdlib/016_Option.mv index 47244d7096..9a0dae2f25 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/016_Option.mv and b/vm/stdlib/compiled/latest/stdlib/016_Option.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/017_Config.mv b/vm/stdlib/compiled/latest/stdlib/017_Config.mv index df3c899b2b..5107abbab8 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/017_Config.mv and b/vm/stdlib/compiled/latest/stdlib/017_Config.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/018_ChainId.mv b/vm/stdlib/compiled/latest/stdlib/018_ChainId.mv index 6ed0508f74..fb643fe958 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/018_ChainId.mv and b/vm/stdlib/compiled/latest/stdlib/018_ChainId.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/019_VMConfig.mv b/vm/stdlib/compiled/latest/stdlib/019_VMConfig.mv index 8b92375736..f8ac0e7fbf 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/019_VMConfig.mv and b/vm/stdlib/compiled/latest/stdlib/019_VMConfig.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/020_Version.mv b/vm/stdlib/compiled/latest/stdlib/020_Version.mv index ad036a1c49..e08ee09a6e 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/020_Version.mv and b/vm/stdlib/compiled/latest/stdlib/020_Version.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/021_PackageTxnManager.mv b/vm/stdlib/compiled/latest/stdlib/021_PackageTxnManager.mv index 2c4f0246fb..808c7b66c8 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/021_PackageTxnManager.mv and b/vm/stdlib/compiled/latest/stdlib/021_PackageTxnManager.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/022_Treasury.mv b/vm/stdlib/compiled/latest/stdlib/022_Treasury.mv index 2ec6646892..588181223e 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/022_Treasury.mv and b/vm/stdlib/compiled/latest/stdlib/022_Treasury.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/023_Dao.mv b/vm/stdlib/compiled/latest/stdlib/023_Dao.mv index 2039ab5980..6f6bedf1cb 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/023_Dao.mv and b/vm/stdlib/compiled/latest/stdlib/023_Dao.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/024_UpgradeModuleDaoProposal.mv b/vm/stdlib/compiled/latest/stdlib/024_UpgradeModuleDaoProposal.mv index e93b039243..083a94d1c5 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/024_UpgradeModuleDaoProposal.mv and b/vm/stdlib/compiled/latest/stdlib/024_UpgradeModuleDaoProposal.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/025_TransactionTimeoutConfig.mv b/vm/stdlib/compiled/latest/stdlib/025_TransactionTimeoutConfig.mv index 0a0b389099..f54deb348e 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/025_TransactionTimeoutConfig.mv and b/vm/stdlib/compiled/latest/stdlib/025_TransactionTimeoutConfig.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/026_TransactionPublishOption.mv b/vm/stdlib/compiled/latest/stdlib/026_TransactionPublishOption.mv index 751bca3777..814bd5aed1 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/026_TransactionPublishOption.mv and b/vm/stdlib/compiled/latest/stdlib/026_TransactionPublishOption.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/027_RewardConfig.mv b/vm/stdlib/compiled/latest/stdlib/027_RewardConfig.mv index 83a4162af0..9114706079 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/027_RewardConfig.mv and b/vm/stdlib/compiled/latest/stdlib/027_RewardConfig.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/028_OnChainConfigDao.mv b/vm/stdlib/compiled/latest/stdlib/028_OnChainConfigDao.mv index 61110fcf83..cccbe13038 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/028_OnChainConfigDao.mv and b/vm/stdlib/compiled/latest/stdlib/028_OnChainConfigDao.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/029_ModifyDaoConfigProposal.mv b/vm/stdlib/compiled/latest/stdlib/029_ModifyDaoConfigProposal.mv index 5f2ff88ac5..390caae299 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/029_ModifyDaoConfigProposal.mv and b/vm/stdlib/compiled/latest/stdlib/029_ModifyDaoConfigProposal.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/030_ConsensusConfig.mv b/vm/stdlib/compiled/latest/stdlib/030_ConsensusConfig.mv index 6861e14b69..0baf06dc64 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/030_ConsensusConfig.mv and b/vm/stdlib/compiled/latest/stdlib/030_ConsensusConfig.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/031_STC.mv b/vm/stdlib/compiled/latest/stdlib/031_STC.mv index 281eb50f58..b462ed908f 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/031_STC.mv and b/vm/stdlib/compiled/latest/stdlib/031_STC.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/032_TransactionFee.mv b/vm/stdlib/compiled/latest/stdlib/032_TransactionFee.mv index 0e2321477b..f209ddeb58 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/032_TransactionFee.mv and b/vm/stdlib/compiled/latest/stdlib/032_TransactionFee.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/033_Hash.mv b/vm/stdlib/compiled/latest/stdlib/033_Hash.mv index 491ed27e4c..67a4a8bf03 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/033_Hash.mv and b/vm/stdlib/compiled/latest/stdlib/033_Hash.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/034_Authenticator.mv b/vm/stdlib/compiled/latest/stdlib/034_Authenticator.mv index 2c4afcf25c..87df0d3581 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/034_Authenticator.mv and b/vm/stdlib/compiled/latest/stdlib/034_Authenticator.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/035_Account.mv b/vm/stdlib/compiled/latest/stdlib/035_Account.mv index 5351b7a7e6..32af399759 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/035_Account.mv and b/vm/stdlib/compiled/latest/stdlib/035_Account.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/036_AccountScripts.mv b/vm/stdlib/compiled/latest/stdlib/036_AccountScripts.mv index 9bcee9f347..07ec865a8b 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/036_AccountScripts.mv and b/vm/stdlib/compiled/latest/stdlib/036_AccountScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/037_Block.mv b/vm/stdlib/compiled/latest/stdlib/037_Block.mv index c6049e5ec0..fda9674f72 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/037_Block.mv and b/vm/stdlib/compiled/latest/stdlib/037_Block.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/038_TreasuryWithdrawDaoProposal.mv b/vm/stdlib/compiled/latest/stdlib/038_TreasuryWithdrawDaoProposal.mv index d6257ff4fa..9b09f0d009 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/038_TreasuryWithdrawDaoProposal.mv and b/vm/stdlib/compiled/latest/stdlib/038_TreasuryWithdrawDaoProposal.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/039_BlockReward.mv b/vm/stdlib/compiled/latest/stdlib/039_BlockReward.mv index eb9ba50f37..533de2359e 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/039_BlockReward.mv and b/vm/stdlib/compiled/latest/stdlib/039_BlockReward.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/040_Collection.mv b/vm/stdlib/compiled/latest/stdlib/040_Collection.mv index 5235cf8ec4..14cb6885c1 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/040_Collection.mv and b/vm/stdlib/compiled/latest/stdlib/040_Collection.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/041_Collection2.mv b/vm/stdlib/compiled/latest/stdlib/041_Collection2.mv index ddd3600cfe..18a0ceb494 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/041_Collection2.mv and b/vm/stdlib/compiled/latest/stdlib/041_Collection2.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/042_Compare.mv b/vm/stdlib/compiled/latest/stdlib/042_Compare.mv index 670997b1ad..f089e1a6d5 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/042_Compare.mv and b/vm/stdlib/compiled/latest/stdlib/042_Compare.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/043_ConsensusStrategy.mv b/vm/stdlib/compiled/latest/stdlib/043_ConsensusStrategy.mv index d389083de9..911f9d5d76 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/043_ConsensusStrategy.mv and b/vm/stdlib/compiled/latest/stdlib/043_ConsensusStrategy.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/044_DaoVoteScripts.mv b/vm/stdlib/compiled/latest/stdlib/044_DaoVoteScripts.mv index 6c1a2c9fb6..1ad7b59e76 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/044_DaoVoteScripts.mv and b/vm/stdlib/compiled/latest/stdlib/044_DaoVoteScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/045_DummyToken.mv b/vm/stdlib/compiled/latest/stdlib/045_DummyToken.mv index 49ee4840b8..27c9e6f5a2 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/045_DummyToken.mv and b/vm/stdlib/compiled/latest/stdlib/045_DummyToken.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/046_DummyTokenScripts.mv b/vm/stdlib/compiled/latest/stdlib/046_DummyTokenScripts.mv index 87a67c1e13..cc64f15f0b 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/046_DummyTokenScripts.mv and b/vm/stdlib/compiled/latest/stdlib/046_DummyTokenScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/047_EVMAddress.mv b/vm/stdlib/compiled/latest/stdlib/047_EVMAddress.mv index b1f33ef7ef..553e5c0c59 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/047_EVMAddress.mv and b/vm/stdlib/compiled/latest/stdlib/047_EVMAddress.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/048_Epoch.mv b/vm/stdlib/compiled/latest/stdlib/048_Epoch.mv index 5f98d6a9d9..2aa602ac28 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/048_Epoch.mv and b/vm/stdlib/compiled/latest/stdlib/048_Epoch.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/049_FixedPoint32.mv b/vm/stdlib/compiled/latest/stdlib/049_FixedPoint32.mv index 06b87dd728..2ecc1abb82 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/049_FixedPoint32.mv and b/vm/stdlib/compiled/latest/stdlib/049_FixedPoint32.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/050_GenesisSignerCapability.mv b/vm/stdlib/compiled/latest/stdlib/050_GenesisSignerCapability.mv index d2321ed4e7..c7e787b2b2 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/050_GenesisSignerCapability.mv and b/vm/stdlib/compiled/latest/stdlib/050_GenesisSignerCapability.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/051_Oracle.mv b/vm/stdlib/compiled/latest/stdlib/051_Oracle.mv index fac74536ff..7e71bf7c21 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/051_Oracle.mv and b/vm/stdlib/compiled/latest/stdlib/051_Oracle.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/052_PriceOracle.mv b/vm/stdlib/compiled/latest/stdlib/052_PriceOracle.mv index ce5b5f7bdc..e70a19c6aa 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/052_PriceOracle.mv and b/vm/stdlib/compiled/latest/stdlib/052_PriceOracle.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/053_STCUSDOracle.mv b/vm/stdlib/compiled/latest/stdlib/053_STCUSDOracle.mv index 26592edcb4..2a49c59909 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/053_STCUSDOracle.mv and b/vm/stdlib/compiled/latest/stdlib/053_STCUSDOracle.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/054_Offer.mv b/vm/stdlib/compiled/latest/stdlib/054_Offer.mv index 69425dab4b..297fc8eb9b 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/054_Offer.mv and b/vm/stdlib/compiled/latest/stdlib/054_Offer.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/055_NFT.mv b/vm/stdlib/compiled/latest/stdlib/055_NFT.mv index 3d86127a17..8434b0f529 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/055_NFT.mv and b/vm/stdlib/compiled/latest/stdlib/055_NFT.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/056_LanguageVersion.mv b/vm/stdlib/compiled/latest/stdlib/056_LanguageVersion.mv index 19a36818f0..0c130d7222 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/056_LanguageVersion.mv and b/vm/stdlib/compiled/latest/stdlib/056_LanguageVersion.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/057_MerkleProof.mv b/vm/stdlib/compiled/latest/stdlib/057_MerkleProof.mv index 7d1334219b..078282555e 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/057_MerkleProof.mv and b/vm/stdlib/compiled/latest/stdlib/057_MerkleProof.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/058_MerkleNFTDistributor.mv b/vm/stdlib/compiled/latest/stdlib/058_MerkleNFTDistributor.mv index c384493ff1..4f145afcea 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/058_MerkleNFTDistributor.mv and b/vm/stdlib/compiled/latest/stdlib/058_MerkleNFTDistributor.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/059_IdentifierNFT.mv b/vm/stdlib/compiled/latest/stdlib/059_IdentifierNFT.mv index bb53a0ebe9..0b7ad460ec 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/059_IdentifierNFT.mv and b/vm/stdlib/compiled/latest/stdlib/059_IdentifierNFT.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/060_GenesisNFT.mv b/vm/stdlib/compiled/latest/stdlib/060_GenesisNFT.mv index 76dd0b7a90..59de3f76bb 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/060_GenesisNFT.mv and b/vm/stdlib/compiled/latest/stdlib/060_GenesisNFT.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/061_StdlibUpgradeScripts.mv b/vm/stdlib/compiled/latest/stdlib/061_StdlibUpgradeScripts.mv index 55b53b9dff..a5fbd028e6 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/061_StdlibUpgradeScripts.mv and b/vm/stdlib/compiled/latest/stdlib/061_StdlibUpgradeScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/062_Genesis.mv b/vm/stdlib/compiled/latest/stdlib/062_Genesis.mv index ac1c22e95b..c923532ab1 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/062_Genesis.mv and b/vm/stdlib/compiled/latest/stdlib/062_Genesis.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/063_GenesisNFTScripts.mv b/vm/stdlib/compiled/latest/stdlib/063_GenesisNFTScripts.mv index 7ee755ddfd..b7c919154c 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/063_GenesisNFTScripts.mv and b/vm/stdlib/compiled/latest/stdlib/063_GenesisNFTScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/064_IdentifierNFTScripts.mv b/vm/stdlib/compiled/latest/stdlib/064_IdentifierNFTScripts.mv index 5a4879c715..d8b0ad3b91 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/064_IdentifierNFTScripts.mv and b/vm/stdlib/compiled/latest/stdlib/064_IdentifierNFTScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/065_MintDaoProposal.mv b/vm/stdlib/compiled/latest/stdlib/065_MintDaoProposal.mv index 6ace4b21e1..2f4e07a5c9 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/065_MintDaoProposal.mv and b/vm/stdlib/compiled/latest/stdlib/065_MintDaoProposal.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/066_ModuleUpgradeScripts.mv b/vm/stdlib/compiled/latest/stdlib/066_ModuleUpgradeScripts.mv index 58cd57f123..4c03908ff0 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/066_ModuleUpgradeScripts.mv and b/vm/stdlib/compiled/latest/stdlib/066_ModuleUpgradeScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/067_NFTGallery.mv b/vm/stdlib/compiled/latest/stdlib/067_NFTGallery.mv index d1e3cb7e60..96fadf2a9d 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/067_NFTGallery.mv and b/vm/stdlib/compiled/latest/stdlib/067_NFTGallery.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/068_NFTGalleryScripts.mv b/vm/stdlib/compiled/latest/stdlib/068_NFTGalleryScripts.mv index 4e52141b88..b3b1bc6616 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/068_NFTGalleryScripts.mv and b/vm/stdlib/compiled/latest/stdlib/068_NFTGalleryScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/069_OnChainConfigScripts.mv b/vm/stdlib/compiled/latest/stdlib/069_OnChainConfigScripts.mv index dfb3123e47..0f740c0f6d 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/069_OnChainConfigScripts.mv and b/vm/stdlib/compiled/latest/stdlib/069_OnChainConfigScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/070_PriceOracleAggregator.mv b/vm/stdlib/compiled/latest/stdlib/070_PriceOracleAggregator.mv index 2e2440e4cb..2dbc3133f6 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/070_PriceOracleAggregator.mv and b/vm/stdlib/compiled/latest/stdlib/070_PriceOracleAggregator.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/071_PriceOracleScripts.mv b/vm/stdlib/compiled/latest/stdlib/071_PriceOracleScripts.mv index ead679c020..1e1b4c6822 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/071_PriceOracleScripts.mv and b/vm/stdlib/compiled/latest/stdlib/071_PriceOracleScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/072_Signature.mv b/vm/stdlib/compiled/latest/stdlib/072_Signature.mv index b28c15e41b..2d57b33358 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/072_Signature.mv and b/vm/stdlib/compiled/latest/stdlib/072_Signature.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/073_SharedEd25519PublicKey.mv b/vm/stdlib/compiled/latest/stdlib/073_SharedEd25519PublicKey.mv index b3cdc82a26..aa92ddbcab 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/073_SharedEd25519PublicKey.mv and b/vm/stdlib/compiled/latest/stdlib/073_SharedEd25519PublicKey.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/074_TransactionTimeout.mv b/vm/stdlib/compiled/latest/stdlib/074_TransactionTimeout.mv index a7f1bea007..0e53dcbf46 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/074_TransactionTimeout.mv and b/vm/stdlib/compiled/latest/stdlib/074_TransactionTimeout.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/075_TransactionManager.mv b/vm/stdlib/compiled/latest/stdlib/075_TransactionManager.mv index 6c44b85ee8..6f1c313bfa 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/075_TransactionManager.mv and b/vm/stdlib/compiled/latest/stdlib/075_TransactionManager.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/076_TransferScripts.mv b/vm/stdlib/compiled/latest/stdlib/076_TransferScripts.mv index f6f727bfd3..dca83ebaca 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/076_TransferScripts.mv and b/vm/stdlib/compiled/latest/stdlib/076_TransferScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/077_TreasuryScripts.mv b/vm/stdlib/compiled/latest/stdlib/077_TreasuryScripts.mv index ac20feb9c2..23b7501a57 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/077_TreasuryScripts.mv and b/vm/stdlib/compiled/latest/stdlib/077_TreasuryScripts.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/078_Arith.mv b/vm/stdlib/compiled/latest/stdlib/078_Arith.mv index ab9a3fe638..5a0bdc47ad 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/078_Arith.mv and b/vm/stdlib/compiled/latest/stdlib/078_Arith.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/079_U256.mv b/vm/stdlib/compiled/latest/stdlib/079_U256.mv index f1cf9559b8..85e94525dd 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/079_U256.mv and b/vm/stdlib/compiled/latest/stdlib/079_U256.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/080_YieldFarming.mv b/vm/stdlib/compiled/latest/stdlib/080_YieldFarming.mv index 605da4c957..5095009085 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/080_YieldFarming.mv and b/vm/stdlib/compiled/latest/stdlib/080_YieldFarming.mv differ diff --git a/vm/stdlib/compiled/latest/stdlib/081_YieldFarmingV2.mv b/vm/stdlib/compiled/latest/stdlib/081_YieldFarmingV2.mv index 11f4cc655d..e0e4f01ae5 100644 Binary files a/vm/stdlib/compiled/latest/stdlib/081_YieldFarmingV2.mv and b/vm/stdlib/compiled/latest/stdlib/081_YieldFarmingV2.mv differ diff --git a/vm/stdlib/src/compat.rs b/vm/stdlib/src/compat.rs index b2fe83cdef..5d6a0c9920 100644 --- a/vm/stdlib/src/compat.rs +++ b/vm/stdlib/src/compat.rs @@ -45,12 +45,12 @@ impl StdlibCompat for StdlibVersion { } else { "UpgradeModule" }; - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("UpgradeModuleDaoProposal").unwrap(), name: Identifier::new(struct_name).unwrap(), type_params: vec![], - }) + })) } fn propose_module_upgrade_function( diff --git a/vm/stdlib/src/lib.rs b/vm/stdlib/src/lib.rs index 617f77eaa5..2fdbb21259 100644 --- a/vm/stdlib/src/lib.rs +++ b/vm/stdlib/src/lib.rs @@ -7,8 +7,6 @@ use anyhow::{bail, ensure, format_err, Result}; use include_dir::{include_dir, Dir}; use log::{debug, info, LevelFilter}; use move_bytecode_verifier::{dependencies, verify_module}; -use move_compiler::command_line::compiler::construct_pre_compiled_lib_from_compiler; -use move_compiler::FullyCompiledProgram; use once_cell::sync::Lazy; use sha2::{Digest, Sha256}; use starcoin_crypto::hash::PlainCryptoHash; @@ -17,7 +15,6 @@ use starcoin_move_compiler::compiled_unit::{CompiledUnit, NamedCompiledModule}; use starcoin_move_compiler::diagnostics::{ report_diagnostics_to_color_buffer, unwrap_or_report_diagnostics, }; -use starcoin_move_compiler::shared::Flags; pub use starcoin_move_compiler::{starcoin_framework_named_addresses, Compiler}; use starcoin_vm_types::file_format::CompiledModule; pub use starcoin_vm_types::genesis_config::StdlibVersion; @@ -105,33 +102,6 @@ pub static G_COMPILED_STDLIB: Lazy>>> = Lazy: pub const SCRIPT_HASH_LENGTH: usize = HashValue::LENGTH; -pub static G_PRECOMPILED_STARCOIN_FRAMEWORK: Lazy = Lazy::new(|| { - let sources = stdlib_files(); - let compiler = Compiler::new(&sources, &[]) - .set_flags(Flags::empty().set_sources_shadow_deps(false)) - .set_named_address_values(starcoin_framework_named_addresses()); - let program_res = construct_pre_compiled_lib_from_compiler(compiler).unwrap(); - match program_res { - Ok(df) => { - let compiled = df.compiled; - { - let compiler = Compiler::new(&[], &sources) - .set_flags(Flags::empty().set_sources_shadow_deps(false)) - .set_named_address_values(starcoin_framework_named_addresses()); - let mut program_as_lib = construct_pre_compiled_lib_from_compiler(compiler) - .unwrap() - .unwrap(); - program_as_lib.compiled = compiled; - program_as_lib - } - } - Err((files, errors)) => { - eprintln!("!!!Starcoin Framework failed to compile!!!"); - move_compiler::diagnostics::report_diagnostics(&files, errors) - } - } -}); - pub use starcoin_framework::STARCOIN_FRAMEWORK_SOURCES; /// Return all versions of stdlib, include latest. @@ -196,10 +166,13 @@ pub fn stdlib_files() -> Vec { pub fn build_stdlib(targets: &[String]) -> BTreeMap { let compiled_units = { - let (files, units_res) = Compiler::new(targets, &[]) - .set_named_address_values(starcoin_framework_named_addresses()) - .build() - .unwrap(); + let (files, units_res) = Compiler::from_files( + targets.to_vec(), + vec![], + starcoin_framework_named_addresses(), + ) + .build() + .unwrap(); let (units, warnings) = unwrap_or_report_diagnostics(&files, units_res); println!( "{}", diff --git a/vm/stdlib/src/main.rs b/vm/stdlib/src/main.rs index d795de898c..3f9f05f829 100644 --- a/vm/stdlib/src/main.rs +++ b/vm/stdlib/src/main.rs @@ -330,9 +330,8 @@ fn main() { .filter_map(|module| { let module_id = module.self_id(); if let Some(old_module) = pre_stable_modules.get(&module_id) { - let compatibility = - check_compiled_module_compat(old_module, module).is_fully_compatible(); - if !compatibility { + let compatibility = check_compiled_module_compat(old_module, module); + if compatibility.is_err() { Some(module_id) } else { None diff --git a/vm/stdlib/tests/generated_files.rs b/vm/stdlib/tests/generated_files.rs index d9e1d0a297..f2e00159d1 100644 --- a/vm/stdlib/tests/generated_files.rs +++ b/vm/stdlib/tests/generated_files.rs @@ -1,8 +1,12 @@ // Copyright (c) The Diem Core Contributors // SPDX-License-Identifier: Apache-2.0 +use move_compiler::construct_pre_compiled_lib; +use move_compiler::shared::PackagePaths; +use starcoin_move_compiler::starcoin_framework_named_addresses; use std::path::PathBuf; use std::process::Command; +use stdlib::stdlib_files; fn assert_that_version_control_has_no_unstaged_changes() { let output = Command::new("git") @@ -42,3 +46,19 @@ fn test_that_generated_file_are_up_to_date_in_git() { // Running the stdlib tool should not create unstaged changes. assert_that_version_control_has_no_unstaged_changes(); } + +#[test] +fn test_stdlib_pre_compiled() { + let sources = stdlib_files(); + let program_res = construct_pre_compiled_lib( + vec![PackagePaths { + name: None, + paths: sources, + named_address_map: starcoin_framework_named_addresses(), + }], + None, + move_compiler::Flags::empty(), + ) + .unwrap(); + assert!(program_res.is_ok()); +} diff --git a/vm/transaction-builder-generator/Cargo.toml b/vm/transaction-builder-generator/Cargo.toml index 023b79ecf2..10599c2ab2 100644 --- a/vm/transaction-builder-generator/Cargo.toml +++ b/vm/transaction-builder-generator/Cargo.toml @@ -5,7 +5,7 @@ test = false [dependencies] anyhow = { workspace = true } -clap = { features = [ "derive",], workspace = true } +clap = { features = ["derive"], workspace = true } heck = { workspace = true } regex = { workspace = true } serde-generate = { workspace = true } diff --git a/vm/transaction-builder-generator/src/common.rs b/vm/transaction-builder-generator/src/common.rs index bb3d7b1984..6792da3d8c 100644 --- a/vm/transaction-builder-generator/src/common.rs +++ b/vm/transaction-builder-generator/src/common.rs @@ -36,6 +36,9 @@ fn quote_type_as_format(type_tag: &TypeTag) -> Format { }, Struct(_) | Signer => type_not_allowed(type_tag), + U16 => Format::U16, + U32 => Format::U32, + U256 => todo!("XXX FIXME YSG"), } } @@ -89,6 +92,9 @@ pub(crate) fn mangle_type(type_tag: &TypeTag) -> String { }, Struct(_) | Signer => type_not_allowed(type_tag), + U16 => "st.uint16".into(), + U32 => "st.uint32".into(), + U256 => "st.uint256".into(), } } diff --git a/vm/transaction-builder-generator/src/cpp.rs b/vm/transaction-builder-generator/src/cpp.rs index 82d78f3793..f7c7deb9ab 100644 --- a/vm/transaction-builder-generator/src/cpp.rs +++ b/vm/transaction-builder-generator/src/cpp.rs @@ -314,6 +314,9 @@ using namespace diem_types; _ => common::type_not_allowed(type_tag), }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => "uint16_t".into(), + U32 => "uint32_t".into(), + U256 => "u256_t".into(), } } @@ -332,6 +335,9 @@ using namespace diem_types; }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => format!("{{TransactionArgument::U16 {{{}}} }}", name), + U32 => format!("{{TransactionArgument::U32 {{{}}} }}", name), + U256 => format!("{{TransactionArgument::U256 {{{}}} }}", name), } } } diff --git a/vm/transaction-builder-generator/src/dart.rs b/vm/transaction-builder-generator/src/dart.rs index 33ac844664..4ef84c9b9b 100644 --- a/vm/transaction-builder-generator/src/dart.rs +++ b/vm/transaction-builder-generator/src/dart.rs @@ -675,6 +675,9 @@ typedef ScriptEncodingHelper = Script Function( _ => common::type_not_allowed(type_tag), }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => ("U16", String::new()), + U32 => ("U32", String::new()), + U256 => ("U256", String::new()), }; writeln!( self.out, @@ -775,6 +778,9 @@ static {} decode_{}_argument(TransactionArgument arg) {{ }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => "int".into(), + U32 => "int".into(), + U256 => "Int256".into(), } } @@ -792,6 +798,9 @@ static {} decode_{}_argument(TransactionArgument arg) {{ }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => format!("new TransactionArgumentU16Item({})", name), + U32 => format!("new TransactionArgumentU32Item({})", name), + U256 => format!("new TransactionArgumentU256Item({})", name), } } } diff --git a/vm/transaction-builder-generator/src/golang.rs b/vm/transaction-builder-generator/src/golang.rs index a9dcb2bb46..028283f847 100644 --- a/vm/transaction-builder-generator/src/golang.rs +++ b/vm/transaction-builder-generator/src/golang.rs @@ -518,6 +518,7 @@ var script_function_decoder_map = map[string]func(diemtypes.TransactionPayload) _ => common::type_not_allowed(type_tag), }, Struct(_) | Signer => common::type_not_allowed(type_tag), + &U16 | &U32 | &U256 => todo!(), }; writeln!( self.out, @@ -625,6 +626,9 @@ func decode_{0}_argument(arg diemtypes.TransactionArgument) (value {1}, err erro }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => "uint16".into(), + U32 => "uint32".into(), + U256 => "serde.Uint256".into(), } } @@ -642,6 +646,7 @@ func decode_{0}_argument(arg diemtypes.TransactionArgument) (value {1}, err erro }, Struct(_) | Signer => common::type_not_allowed(type_tag), + &U16 | &U32 | &U256 => todo!(), } } } diff --git a/vm/transaction-builder-generator/src/java.rs b/vm/transaction-builder-generator/src/java.rs index d94931df3b..fb77b1c442 100644 --- a/vm/transaction-builder-generator/src/java.rs +++ b/vm/transaction-builder-generator/src/java.rs @@ -660,6 +660,9 @@ private static java.util.Map initDecoderMa _ => common::type_not_allowed(type_tag), }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => ("U16", String::new()), + U32 => ("U32", String::new()), + U256 => ("U256", String::new()), }; writeln!( self.out, @@ -760,6 +763,9 @@ private static {} decode_{}_argument(TransactionArgument arg) {{ }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => "@Unsigned Char".into(), + U32 => "@Unsigned Int".into(), + U256 => "@Unsigned @Int256 BigInteger".into(), } } @@ -777,6 +783,9 @@ private static {} decode_{}_argument(TransactionArgument arg) {{ }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => format!("new TransactionArgument.U16({})", name), + U32 => format!("new TransactionArgument.U32({})", name), + U256 => format!("new TransactionArgument.U256({})", name), } } } diff --git a/vm/transaction-builder-generator/src/python3.rs b/vm/transaction-builder-generator/src/python3.rs index f642855a6e..8c4cbcda8f 100644 --- a/vm/transaction-builder-generator/src/python3.rs +++ b/vm/transaction-builder-generator/src/python3.rs @@ -527,6 +527,9 @@ SCRIPT_FUNCTION_ENCODER_MAP: typing.Dict[typing.Type[ScriptFunctionCall], typing }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => "st.uint16".into(), + U32 => "st.uint32".into(), + U256 => "st.uint256".into(), } } @@ -544,6 +547,9 @@ SCRIPT_FUNCTION_ENCODER_MAP: typing.Dict[typing.Type[ScriptFunctionCall], typing }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => format!("bcs.serialize({}, st.uint16)", name), + U32 => format!("bcs.serialize({}, st.uint32)", name), + U256 => format!("bcs.serialize({}, st.uint256)", name), } } } diff --git a/vm/transaction-builder-generator/src/rust.rs b/vm/transaction-builder-generator/src/rust.rs index a1c17e7802..fd826695d7 100644 --- a/vm/transaction-builder-generator/src/rust.rs +++ b/vm/transaction-builder-generator/src/rust.rs @@ -647,6 +647,7 @@ static G_SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy common::type_not_allowed(type_tag), }, Struct(_) | Signer => common::type_not_allowed(type_tag), + &U16 | &U32 | &U256 => todo!(), }; writeln!( self.out, @@ -780,6 +781,9 @@ fn decode_{}_argument(arg: TransactionArgument) -> Option<{}> {{ }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => "u16".into(), + U32 => "u32".into(), + U256 => "u256".into(), } } @@ -797,6 +801,9 @@ fn decode_{}_argument(arg: TransactionArgument) -> Option<{}> {{ }, Struct(_) | Signer => common::type_not_allowed(type_tag), + U16 => format!("TransactionArgument::U16({})", name), + U32 => format!("TransactionArgument::U32({})", name), + U256 => format!("TransactionArgument::U256({})", name), } } } diff --git a/vm/transaction-builder/src/lib.rs b/vm/transaction-builder/src/lib.rs index 957849a5ca..1d33699a88 100644 --- a/vm/transaction-builder/src/lib.rs +++ b/vm/transaction-builder/src/lib.rs @@ -10,7 +10,6 @@ use starcoin_vm_types::account_address::AccountAddress; use starcoin_vm_types::account_config; use starcoin_vm_types::account_config::{core_code_address, genesis_address}; use starcoin_vm_types::file_format::CompiledModule; -use starcoin_vm_types::gas_schedule::GasAlgebra; use starcoin_vm_types::genesis_config::ChainId; use starcoin_vm_types::identifier::Identifier; use starcoin_vm_types::language_storage::ModuleId; @@ -206,7 +205,7 @@ pub fn raw_accept_token_txn( let payload = TransactionPayload::ScriptFunction(ScriptFunction::new( ModuleId::new(core_code_address(), Identifier::new("Account").unwrap()), Identifier::new("accept_token").unwrap(), - vec![TypeTag::Struct(token_code.try_into().unwrap())], + vec![TypeTag::Struct(Box::new(token_code.try_into().unwrap()))], vec![], )); @@ -255,7 +254,7 @@ pub fn encode_transfer_script_by_token_code( Identifier::new("TransferScripts").unwrap(), ), Identifier::new("peer_to_peer_v2").unwrap(), - vec![TypeTag::Struct(token_code.try_into().unwrap())], + vec![TypeTag::Struct(Box::new(token_code.try_into().unwrap()))], vec![ bcs_ext::to_bytes(&recipient).unwrap(), bcs_ext::to_bytes(&amount).unwrap(), @@ -406,8 +405,7 @@ pub fn build_init_script_v1(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .global_memory_per_byte_cost - .get(), + .global_memory_per_byte_cost, ) .unwrap(), bcs_ext::to_bytes( @@ -415,8 +413,7 @@ pub fn build_init_script_v1(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .global_memory_per_byte_write_cost - .get(), + .global_memory_per_byte_write_cost, ) .unwrap(), bcs_ext::to_bytes( @@ -424,8 +421,7 @@ pub fn build_init_script_v1(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .min_transaction_gas_units - .get(), + .min_transaction_gas_units, ) .unwrap(), bcs_ext::to_bytes( @@ -433,8 +429,7 @@ pub fn build_init_script_v1(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .large_transaction_cutoff - .get(), + .large_transaction_cutoff, ) .unwrap(), bcs_ext::to_bytes( @@ -442,8 +437,7 @@ pub fn build_init_script_v1(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .intrinsic_gas_per_byte - .get(), + .intrinsic_gas_per_byte, ) .unwrap(), bcs_ext::to_bytes( @@ -451,8 +445,7 @@ pub fn build_init_script_v1(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .maximum_number_of_gas_units - .get(), + .maximum_number_of_gas_units, ) .unwrap(), bcs_ext::to_bytes( @@ -460,8 +453,7 @@ pub fn build_init_script_v1(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .min_price_per_gas_unit - .get(), + .min_price_per_gas_unit, ) .unwrap(), bcs_ext::to_bytes( @@ -469,8 +461,7 @@ pub fn build_init_script_v1(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .max_price_per_gas_unit - .get(), + .max_price_per_gas_unit, ) .unwrap(), bcs_ext::to_bytes( @@ -494,8 +485,7 @@ pub fn build_init_script_v1(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .default_account_size - .get(), + .default_account_size, ) .unwrap(), // dao config params @@ -579,8 +569,7 @@ pub fn build_init_script_v2(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .global_memory_per_byte_cost - .get(), + .global_memory_per_byte_cost, ) .unwrap(), bcs_ext::to_bytes( @@ -588,8 +577,7 @@ pub fn build_init_script_v2(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .global_memory_per_byte_write_cost - .get(), + .global_memory_per_byte_write_cost, ) .unwrap(), bcs_ext::to_bytes( @@ -597,8 +585,7 @@ pub fn build_init_script_v2(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .min_transaction_gas_units - .get(), + .min_transaction_gas_units, ) .unwrap(), bcs_ext::to_bytes( @@ -606,8 +593,7 @@ pub fn build_init_script_v2(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .large_transaction_cutoff - .get(), + .large_transaction_cutoff, ) .unwrap(), bcs_ext::to_bytes( @@ -615,8 +601,7 @@ pub fn build_init_script_v2(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .intrinsic_gas_per_byte - .get(), + .intrinsic_gas_per_byte, ) .unwrap(), bcs_ext::to_bytes( @@ -624,8 +609,7 @@ pub fn build_init_script_v2(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .maximum_number_of_gas_units - .get(), + .maximum_number_of_gas_units, ) .unwrap(), bcs_ext::to_bytes( @@ -633,8 +617,7 @@ pub fn build_init_script_v2(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .min_price_per_gas_unit - .get(), + .min_price_per_gas_unit, ) .unwrap(), bcs_ext::to_bytes( @@ -642,8 +625,7 @@ pub fn build_init_script_v2(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .max_price_per_gas_unit - .get(), + .max_price_per_gas_unit, ) .unwrap(), bcs_ext::to_bytes( @@ -667,8 +649,7 @@ pub fn build_init_script_v2(net: &ChainNetwork) -> ScriptFunction { .vm_config .gas_schedule .gas_constants - .default_account_size - .get(), + .default_account_size, ) .unwrap(), // dao config params @@ -800,19 +781,19 @@ pub fn build_module_upgrade_queue( stdlib_version: StdlibVersion, ) -> ScriptFunction { let upgrade_module = if stdlib_version >= StdlibVersion::Version(2) { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("UpgradeModuleDaoProposal").unwrap(), name: Identifier::new("UpgradeModuleV2").unwrap(), type_params: vec![], - }) + })) } else { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: genesis_address(), module: Identifier::new("UpgradeModuleDaoProposal").unwrap(), name: Identifier::new("UpgradeModule").unwrap(), type_params: vec![], - }) + })) }; ScriptFunction::new( @@ -847,17 +828,17 @@ pub fn build_vm_config_upgrade_proposal(vm_config: VMConfig, exec_delay: u64) -> .unwrap(), bcs_ext::to_bytes(&bcs_ext::to_bytes(&vm_config.gas_schedule.native_table).unwrap()) .unwrap(), - bcs_ext::to_bytes(&gas_constants.global_memory_per_byte_cost.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.global_memory_per_byte_write_cost.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.min_transaction_gas_units.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.large_transaction_cutoff.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.intrinsic_gas_per_byte.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.maximum_number_of_gas_units.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.min_price_per_gas_unit.get()).unwrap(), - bcs_ext::to_bytes(&gas_constants.max_price_per_gas_unit.get()).unwrap(), + bcs_ext::to_bytes(&gas_constants.global_memory_per_byte_cost).unwrap(), + bcs_ext::to_bytes(&gas_constants.global_memory_per_byte_write_cost).unwrap(), + bcs_ext::to_bytes(&gas_constants.min_transaction_gas_units).unwrap(), + bcs_ext::to_bytes(&gas_constants.large_transaction_cutoff).unwrap(), + bcs_ext::to_bytes(&gas_constants.intrinsic_gas_per_byte).unwrap(), + bcs_ext::to_bytes(&gas_constants.maximum_number_of_gas_units).unwrap(), + bcs_ext::to_bytes(&gas_constants.min_price_per_gas_unit).unwrap(), + bcs_ext::to_bytes(&gas_constants.max_price_per_gas_unit).unwrap(), bcs_ext::to_bytes(&gas_constants.max_transaction_size_in_bytes).unwrap(), bcs_ext::to_bytes(&gas_constants.gas_unit_scaling_factor).unwrap(), - bcs_ext::to_bytes(&gas_constants.default_account_size.get()).unwrap(), + bcs_ext::to_bytes(&gas_constants.default_account_size).unwrap(), bcs_ext::to_bytes(&exec_delay).unwrap(), ], ) diff --git a/vm/types/Cargo.toml b/vm/types/Cargo.toml index ca69082d42..6254ae8e04 100644 --- a/vm/types/Cargo.toml +++ b/vm/types/Cargo.toml @@ -1,7 +1,7 @@ [dependencies] anyhow = { workspace = true } bech32 = { workspace = true } -chrono = { default-features = false, features = [ "clock",], workspace = true } +chrono = { default-features = false, features = ["clock"], workspace = true } hex = { workspace = true } log = { workspace = true } mirai-annotations = { workspace = true } @@ -10,15 +10,17 @@ once_cell = { workspace = true } rand = { workspace = true } serde = { default-features = false, workspace = true } serde_bytes = { workspace = true } -serde_json = { features = [ "arbitrary_precision",], workspace = true } +serde_json = { features = ["arbitrary_precision"], workspace = true } move-bytecode-verifier = { workspace = true } move-core-types = { workspace = true } move-ir-types = { workspace = true } move-vm-types = { workspace = true } +move-table-extension = { workspace = true } proptest = { default-features = false, optional = true, workspace = true } proptest-derive = { default-features = false, optional = true, workspace = true } starcoin-time-service = { optional = true, workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } +starcoin-gas-algebra-ext = { workspace = true } forkable-jellyfish-merkle = { workspace = true } schemars = { workspace = true } starcoin-accumulator = { workspace = true } @@ -34,7 +36,14 @@ vm = { workspace = true } [features] default = [] -fuzzing = [ "proptest", "proptest-derive", "vm/fuzzing", "starcoin-time-service", "starcoin-crypto/fuzzing", "move-core-types/fuzzing",] +fuzzing = [ + "proptest", + "proptest-derive", + "vm/fuzzing", + "starcoin-time-service", + "starcoin-crypto/fuzzing", + "move-core-types/fuzzing", +] [package] authors = { workspace = true } diff --git a/vm/types/src/account_config/constants/addresses.rs b/vm/types/src/account_config/constants/addresses.rs index 518640016c..a2cff2c7c8 100644 --- a/vm/types/src/account_config/constants/addresses.rs +++ b/vm/types/src/account_config/constants/addresses.rs @@ -16,3 +16,8 @@ pub fn core_code_address() -> AccountAddress { pub fn genesis_address() -> AccountAddress { CORE_CODE_ADDRESS } + +pub fn table_handle_address() -> AccountAddress { + AccountAddress::from_hex_literal("0xA550C68") + .expect("Parsing valid hex literal should always succeed") +} diff --git a/vm/types/src/account_config/events/config_change.rs b/vm/types/src/account_config/events/config_change.rs index d6967e3c73..265da9b1f1 100644 --- a/vm/types/src/account_config/events/config_change.rs +++ b/vm/types/src/account_config/events/config_change.rs @@ -24,6 +24,6 @@ where const STRUCT_NAME: &'static str = "ConfigChangeEvent"; fn type_params() -> Vec { - vec![TypeTag::Struct(V::config_id().struct_tag())] + vec![TypeTag::Struct(Box::new(V::config_id().struct_tag()))] } } diff --git a/vm/types/src/account_config/resources/auto_accept_token.rs b/vm/types/src/account_config/resources/auto_accept_token.rs index 80bff10856..c49bae97a7 100644 --- a/vm/types/src/account_config/resources/auto_accept_token.rs +++ b/vm/types/src/account_config/resources/auto_accept_token.rs @@ -27,7 +27,7 @@ impl AutoAcceptToken { && struct_tag.name.as_str() == Self::STRUCT_NAME { if let Some(TypeTag::Struct(token_tag)) = struct_tag.type_params.get(0) { - Some(token_tag.clone().into()) + Some((*(token_tag.clone())).into()) } else { None } diff --git a/vm/types/src/account_config/resources/balance.rs b/vm/types/src/account_config/resources/balance.rs index 06108266c9..d4e8561f8c 100644 --- a/vm/types/src/account_config/resources/balance.rs +++ b/vm/types/src/account_config/resources/balance.rs @@ -32,7 +32,7 @@ impl BalanceResource { address: CORE_CODE_ADDRESS, name: BalanceResource::struct_identifier(), module: BalanceResource::module_identifier(), - type_params: vec![TypeTag::Struct(token_type_tag)], + type_params: vec![TypeTag::Struct(Box::new(token_type_tag))], } } @@ -48,7 +48,7 @@ impl BalanceResource { && struct_tag.name.as_str() == Self::STRUCT_NAME { if let Some(TypeTag::Struct(token_tag)) = struct_tag.type_params.get(0) { - Some(token_tag.clone().into()) + Some((*(token_tag.clone())).into()) } else { None } diff --git a/vm/types/src/contract_event.rs b/vm/types/src/contract_event.rs index 314f1b9e4c..476014cbd1 100644 --- a/vm/types/src/contract_event.rs +++ b/vm/types/src/contract_event.rs @@ -102,7 +102,7 @@ impl ContractEventV0 { } pub fn is(&self) -> bool { - self.type_tag == TypeTag::Struct(EventType::struct_tag()) + self.type_tag == TypeTag::Struct(Box::new(EventType::struct_tag())) } } diff --git a/vm/types/src/gas_schedule.rs b/vm/types/src/gas_schedule.rs index a73951253b..579f49427b 100644 --- a/vm/types/src/gas_schedule.rs +++ b/vm/types/src/gas_schedule.rs @@ -1,8 +1,5 @@ -pub use move_core_types::gas_schedule::*; -pub use move_vm_types::gas_schedule::{ - calculate_intrinsic_gas, new_from_instructions, zero_cost_schedule, GasStatus, -}; use once_cell::sync::Lazy; +use starcoin_gas_algebra_ext::{CostTable, GasConstants}; #[allow(non_camel_case_types)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] @@ -41,85 +38,94 @@ pub enum NativeCostIndex { VEC_APPEND = 30, VEC_REMOVE = 31, VEC_REVERSE = 32, + TABLE_NEW = 33, + TABLE_INSERT = 34, + TABLE_BORROW = 35, + TABLE_REMOVE = 36, + TABLE_CONTAINS = 37, + TABLE_DESTROY = 38, + TABLE_DROP = 39, + STRING_CHECK_UT8 = 40, + STRING_SUB_STR = 41, + SRING_CHAR_BOUNDARY = 42, + STRING_INDEX_OF = 43, } impl NativeCostIndex { //note: should change this value when add new native function. - pub const NUMBER_OF_NATIVE_FUNCTIONS: usize = 33; + pub const NUMBER_OF_NATIVE_FUNCTIONS: usize = 44; } -static G_MAX_TRANSACTION_SIZE_IN_BYTES_V1: u64 = 4096 * 10; -static G_MAX_TRANSACTION_SIZE_IN_BYTES_V2: u64 = 60000; -static G_MAX_TRANSACTION_SIZE_IN_BYTES_V3: u64 = 128 * 1024; +pub static G_MAX_TRANSACTION_SIZE_IN_BYTES_V1: u64 = 4096 * 10; +pub static G_MAX_TRANSACTION_SIZE_IN_BYTES_V2: u64 = 60000; +pub static G_MAX_TRANSACTION_SIZE_IN_BYTES_V3: u64 = 128 * 1024; /// For V1 all accounts will be ~800 bytes -pub static G_DEFAULT_ACCOUNT_SIZE: Lazy> = - Lazy::new(|| AbstractMemorySize::new(800)); +pub static G_DEFAULT_ACCOUNT_SIZE: u64 = 800; /// Any transaction over this size will be charged `INTRINSIC_GAS_PER_BYTE` per byte -pub static G_LARGE_TRANSACTION_CUTOFF: Lazy> = - Lazy::new(|| AbstractMemorySize::new(600)); +pub static G_LARGE_TRANSACTION_CUTOFF: u64 = 600; pub static G_GAS_CONSTANTS_V1: Lazy = Lazy::new(|| { GasConstants { - global_memory_per_byte_cost: InternalGasUnits::new(4), - global_memory_per_byte_write_cost: InternalGasUnits::new(9), - min_transaction_gas_units: InternalGasUnits::new(600), - large_transaction_cutoff: *G_LARGE_TRANSACTION_CUTOFF, - intrinsic_gas_per_byte: InternalGasUnits::new(8), - maximum_number_of_gas_units: GasUnits::new(40_000_000), //must less than base_block_gas_limit - min_price_per_gas_unit: GasPrice::new(1), - max_price_per_gas_unit: GasPrice::new(10_000), + global_memory_per_byte_cost: 4, + global_memory_per_byte_write_cost: 9, + min_transaction_gas_units: 600, + large_transaction_cutoff: G_LARGE_TRANSACTION_CUTOFF, + intrinsic_gas_per_byte: 8, + maximum_number_of_gas_units: 40_000_000, //must less than base_block_gas_limit + min_price_per_gas_unit: 1, + max_price_per_gas_unit: 10_000, max_transaction_size_in_bytes: G_MAX_TRANSACTION_SIZE_IN_BYTES_V1, // to pass stdlib_upgrade gas_unit_scaling_factor: 1, - default_account_size: *G_DEFAULT_ACCOUNT_SIZE, + default_account_size: G_DEFAULT_ACCOUNT_SIZE, } }); pub static G_GAS_CONSTANTS_V2: Lazy = Lazy::new(|| { GasConstants { - global_memory_per_byte_cost: InternalGasUnits::new(4), - global_memory_per_byte_write_cost: InternalGasUnits::new(9), - min_transaction_gas_units: InternalGasUnits::new(600), - large_transaction_cutoff: *G_LARGE_TRANSACTION_CUTOFF, - intrinsic_gas_per_byte: InternalGasUnits::new(8), - maximum_number_of_gas_units: GasUnits::new(40_000_000), //must less than base_block_gas_limit - min_price_per_gas_unit: GasPrice::new(1), - max_price_per_gas_unit: GasPrice::new(10_000), + global_memory_per_byte_cost: 4, + global_memory_per_byte_write_cost: 9, + min_transaction_gas_units: 600, + large_transaction_cutoff: G_LARGE_TRANSACTION_CUTOFF, + intrinsic_gas_per_byte: 8, + maximum_number_of_gas_units: 40_000_000, //must less than base_block_gas_limit + min_price_per_gas_unit: 1, + max_price_per_gas_unit: 10_000, max_transaction_size_in_bytes: G_MAX_TRANSACTION_SIZE_IN_BYTES_V2, // to pass stdlib_upgrade gas_unit_scaling_factor: 1, - default_account_size: *G_DEFAULT_ACCOUNT_SIZE, + default_account_size: G_DEFAULT_ACCOUNT_SIZE, } }); pub static G_GAS_CONSTANTS_V3: Lazy = Lazy::new(|| { GasConstants { - global_memory_per_byte_cost: InternalGasUnits::new(4), - global_memory_per_byte_write_cost: InternalGasUnits::new(9), - min_transaction_gas_units: InternalGasUnits::new(600), - large_transaction_cutoff: *G_LARGE_TRANSACTION_CUTOFF, - intrinsic_gas_per_byte: InternalGasUnits::new(8), - maximum_number_of_gas_units: GasUnits::new(40_000_000), //must less than base_block_gas_limit - min_price_per_gas_unit: GasPrice::new(1), - max_price_per_gas_unit: GasPrice::new(10_000), + global_memory_per_byte_cost: 4, + global_memory_per_byte_write_cost: 9, + min_transaction_gas_units: 600, + large_transaction_cutoff: G_LARGE_TRANSACTION_CUTOFF, + intrinsic_gas_per_byte: 8, + maximum_number_of_gas_units: 40_000_000, //must less than base_block_gas_limit + min_price_per_gas_unit: 1, + max_price_per_gas_unit: 10_000, max_transaction_size_in_bytes: G_MAX_TRANSACTION_SIZE_IN_BYTES_V3, gas_unit_scaling_factor: 1, - default_account_size: *G_DEFAULT_ACCOUNT_SIZE, + default_account_size: G_DEFAULT_ACCOUNT_SIZE, } }); pub static G_TEST_GAS_CONSTANTS: Lazy = Lazy::new(|| { GasConstants { - global_memory_per_byte_cost: InternalGasUnits::new(4), - global_memory_per_byte_write_cost: InternalGasUnits::new(9), - min_transaction_gas_units: InternalGasUnits::new(600), - large_transaction_cutoff: *G_LARGE_TRANSACTION_CUTOFF, - intrinsic_gas_per_byte: InternalGasUnits::new(8), - maximum_number_of_gas_units: GasUnits::new(40_000_000), //must less than base_block_gas_limit - min_price_per_gas_unit: GasPrice::new(0), - max_price_per_gas_unit: GasPrice::new(10_000), + global_memory_per_byte_cost: 4, + global_memory_per_byte_write_cost: 9, + min_transaction_gas_units: 600, + large_transaction_cutoff: G_LARGE_TRANSACTION_CUTOFF, + intrinsic_gas_per_byte: 8, + maximum_number_of_gas_units: (40_000_000 * 10), //must less than base_block_gas_limit + min_price_per_gas_unit: 0, + max_price_per_gas_unit: 10_000, max_transaction_size_in_bytes: G_MAX_TRANSACTION_SIZE_IN_BYTES_V3, gas_unit_scaling_factor: 1, - default_account_size: *G_DEFAULT_ACCOUNT_SIZE, + default_account_size: G_DEFAULT_ACCOUNT_SIZE, } }); diff --git a/vm/types/src/lib.rs b/vm/types/src/lib.rs index 16040ddd2c..5d884364f4 100644 --- a/vm/types/src/lib.rs +++ b/vm/types/src/lib.rs @@ -5,9 +5,7 @@ mod language_storage_ext; pub mod account_address; - pub mod gas_schedule; - pub mod location { pub use move_ir_types::location::Loc; } @@ -161,7 +159,7 @@ pub mod parser { pub fn parse_struct_tag(s: &str) -> Result { let type_tag = parse_type_tag(s)?; match type_tag { - TypeTag::Struct(st) => Ok(st), + TypeTag::Struct(st) => Ok(*st), t => bail!("expect a struct tag, found: {:?}", t), } } @@ -250,6 +248,8 @@ pub mod on_chain_resource; pub mod serde_helper; pub mod sign_message; pub mod sips; +pub mod state_store; +pub mod time; pub mod token; #[cfg(test)] mod unit_tests; diff --git a/vm/types/src/move_resource.rs b/vm/types/src/move_resource.rs index 8216562ef3..ac7ddcd3f2 100644 --- a/vm/types/src/move_resource.rs +++ b/vm/types/src/move_resource.rs @@ -37,7 +37,7 @@ pub trait MoveResource { } fn type_tag() -> TypeTag { - TypeTag::Struct(Self::struct_tag()) + TypeTag::Struct(Box::new(Self::struct_tag())) } fn resource_path() -> DataPath { diff --git a/vm/types/src/on_chain_config/consensus_config.rs b/vm/types/src/on_chain_config/consensus_config.rs index 0f61aa8bc2..c7a30cb793 100644 --- a/vm/types/src/on_chain_config/consensus_config.rs +++ b/vm/types/src/on_chain_config/consensus_config.rs @@ -36,12 +36,12 @@ impl OnChainConfig for ConsensusConfig { impl ConsensusConfig { pub fn type_tag() -> TypeTag { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: CORE_CODE_ADDRESS, module: G_CONSENSUS_CONFIG_IDENTIFIER.clone(), name: G_CONSENSUS_CONFIG_IDENTIFIER.clone(), type_params: vec![], - }) + })) } } pub fn consensus_config_type_tag() -> TypeTag { diff --git a/vm/types/src/on_chain_config/gas_schedule.rs b/vm/types/src/on_chain_config/gas_schedule.rs new file mode 100644 index 0000000000..7cb3343bf6 --- /dev/null +++ b/vm/types/src/on_chain_config/gas_schedule.rs @@ -0,0 +1,680 @@ +use crate::gas_schedule::{ + G_MAX_TRANSACTION_SIZE_IN_BYTES_V1, G_MAX_TRANSACTION_SIZE_IN_BYTES_V2, + G_MAX_TRANSACTION_SIZE_IN_BYTES_V3, +}; +use crate::on_chain_config::{OnChainConfig, VMConfig}; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +pub struct GasSchedule { + pub entries: Vec<(String, u64)>, +} + +impl GasSchedule { + pub fn to_btree_map(self) -> BTreeMap { + // TODO: what if the gas schedule contains duplicated entries? + self.entries.into_iter().collect() + } +} + +// instruction_table_v1 +pub fn instruction_gas_schedule_v1() -> Vec<(String, u64)> { + let gas_total = |x: u64, y: u64| -> u64 { x + y }; + vec![ + ("instr.pop".to_string(), gas_total(1, 1)), + ("instr.ret".to_string(), gas_total(638, 1)), + ("instr.br_true".to_string(), gas_total(1, 1)), + ("instr.br_false".to_string(), gas_total(1, 1)), + ("instr.branch".to_string(), gas_total(1, 1)), + ("instr.ld_u64".to_string(), gas_total(1, 1)), + ("instr.ld_const.per_byte".to_string(), gas_total(1, 1)), + ("instr.ld_true".to_string(), gas_total(1, 1)), + ("instr.ld_false".to_string(), gas_total(1, 1)), + ( + "instr.copy_loc.per_abs_mem_unit".to_string(), + gas_total(1, 1), + ), + ( + "instr.move_loc.per_abs_mem_unit".to_string(), + gas_total(1, 1), + ), + ("instr.st_loc.per_abs_mem_unit".to_string(), gas_total(1, 1)), + ("instr.mut_borrow_loc".to_string(), gas_total(2, 1)), + ("instr.imm_borrow_loc".to_string(), gas_total(1, 1)), + ("instr.mut_borrow_field".to_string(), gas_total(1, 1)), + ("instr.imm_borrow_field".to_string(), gas_total(1, 1)), + ("instr.call.per_arg".to_string(), gas_total(1132, 1)), + ("instr.pack.per_abs_mem_unit".to_string(), gas_total(2, 1)), + ("instr.unpack.per_abs_mem_unit".to_string(), gas_total(2, 1)), + ( + "instr.read_ref.per_abs_mem_unit".to_string(), + gas_total(1, 1), + ), + ( + "instr.write_ref.per_abs_mem_unit".to_string(), + gas_total(1, 1), + ), + ("instr.add".to_string(), gas_total(1, 1)), + ("instr.sub".to_string(), gas_total(1, 1)), + ("instr.mul".to_string(), gas_total(1, 1)), + ("instr.mod".to_string(), gas_total(1, 1)), + ("instr.div".to_string(), gas_total(3, 1)), + ("instr.bit_or".to_string(), gas_total(2, 1)), + ("instr.bit_and".to_string(), gas_total(2, 1)), + ("instr.xor".to_string(), gas_total(1, 1)), + ("instr.or".to_string(), gas_total(2, 1)), + ("instr.and".to_string(), gas_total(1, 1)), + ("instr.not".to_string(), gas_total(1, 1)), + ("instr.eq.per_abs_mem_unit".to_string(), gas_total(1, 1)), + ("instr.neq.per_abs_mem_unit".to_string(), gas_total(1, 1)), + ("instr.lt".to_string(), gas_total(1, 1)), + ("instr.gt".to_string(), gas_total(1, 1)), + ("instr.le".to_string(), gas_total(2, 1)), + ("instr.ge".to_string(), gas_total(1, 1)), + ("instr.abort".to_string(), gas_total(1, 1)), + ("instr.nop".to_string(), gas_total(1, 1)), + ( + "instr.exists.per_abs_mem_unit".to_string(), + gas_total(41, 1), + ), + ( + "instr.mut_borrow_global.per_abs_mem_unit".to_string(), + gas_total(21, 1), + ), + ( + "instr.imm_borrow_global.per_abs_mem_unit".to_string(), + gas_total(23, 1), + ), + ( + "instr.move_from.per_abs_mem_unit".to_string(), + gas_total(459, 1), + ), + ( + "instr.move_to.per_abs_mem_unit".to_string(), + gas_total(13, 1), + ), + ("instr.freeze_ref".to_string(), gas_total(1, 1)), + ("instr.shl".to_string(), gas_total(2, 1)), + ("instr.shr".to_string(), gas_total(1, 1)), + ("instr.ld_u8".to_string(), gas_total(1, 1)), + ("instr.ld_u128".to_string(), gas_total(1, 1)), + ("instr.cast_u8".to_string(), gas_total(2, 1)), + ("instr.cast_u64".to_string(), gas_total(1, 1)), + ("instr.cast_u128".to_string(), gas_total(1, 1)), + ( + "instr.mut_borrow_field_generic.base".to_string(), + gas_total(1, 1), + ), + ( + "instr.imm_borrow_field_generic.base".to_string(), + gas_total(1, 1), + ), + ("instr.call_generic.per_arg".to_string(), gas_total(582, 1)), + ( + "instr.pack_generic.per_abs_mem_unit".to_string(), + gas_total(2, 1), + ), + ( + "instr.unpack_generic.per_abs_mem_unit".to_string(), + gas_total(2, 1), + ), + ( + "instr.exists_generic.per_abs_mem_unit".to_string(), + gas_total(34, 1), + ), + ( + "instr.mut_borrow_global_generic.per_abs_mem_unit".to_string(), + gas_total(15, 1), + ), + ( + "instr.imm_borrow_global_generic.per_abs_mem_unit".to_string(), + gas_total(14, 1), + ), + ( + "instr.move_from_generic.per_abs_mem_unit".to_string(), + gas_total(13, 1), + ), + ( + "instr.move_to_generic.per_abs_mem_unit".to_string(), + gas_total(27, 1), + ), + ] +} + +// instruction_table_v2 +pub fn instruction_gas_schedule_v2() -> Vec<(String, u64)> { + let gas_total = |x: u64, y: u64| -> u64 { x + y }; + let mut instrs = instruction_gas_schedule_v1(); + let mut instrs_delta = vec![ + ("instr.vec_pack.per_elem".to_string(), gas_total(84, 1)), + ("instr.vec_len.base".to_string(), gas_total(98, 1)), + ("instr.vec_imm_borrow.base".to_string(), gas_total(1334, 1)), + ("instr.vec_mut_borrow.base".to_string(), gas_total(1902, 1)), + ( + "instr.vec_push_back.per_abs_mem_unit".to_string(), + gas_total(53, 1), + ), + ("instr.vec_pop_back.base".to_string(), gas_total(227, 1)), + ( + "instr.vec_unpack.per_expected_elem".to_string(), + gas_total(572, 1), + ), + ("instr.vec_swap.base".to_string(), gas_total(1436, 1)), + ]; + instrs.append(&mut instrs_delta); + instrs +} + +// native_table_v1 +pub fn native_gas_schedule_v1() -> Vec<(String, u64)> { + let gas_total = |x: u64, y: u64| -> u64 { x + y }; + vec![ + ( + "move_stdlib.hash.sha2_256.per_byte".to_string(), + gas_total(21, 1), + ), + ( + "move_stdlib.hash.sha3_256.per_byte".to_string(), + gas_total(64, 1), + ), + ( + "starcoin_natives.signature.ed25519_verify.per_byte".to_string(), + gas_total(61, 1), + ), + // ED25519_THRESHOLD_VERIFY 3 this native funciton is deprecated + ( + "move_stdlib.bcs.to_bytes.per_byte_serialized".to_string(), + gas_total(181, 1), + ), + ( + "move_stdlib.vector.length.base".to_string(), + gas_total(98, 1), + ), + ( + "move_stdlib.vector.empty.base".to_string(), + gas_total(84, 1), + ), + ( + "move_stdlib.vector.borrow.base".to_string(), + gas_total(1334, 1), + ), + // Vector::borrow_mut is same as Vector::borrow + ( + "move_stdlib.vector.push_back.legacy_per_abstract_memory_unit".to_string(), + gas_total(53, 1), + ), + ( + "move_stdlib.vector.pop_back.base".to_string(), + gas_total(227, 1), + ), + ( + "move_stdlib.vector.destroy_empty.base".to_string(), + gas_total(572, 1), + ), + ( + "move_stdlib.vector.swap.base".to_string(), + gas_total(1436, 1), + ), + ( + "starcoin_natives.signature.ed25519_validate_key.per_byte".to_string(), + gas_total(26, 1), + ), + ( + "move_stdlib.signer.borrow_address.base".to_string(), + gas_total(353, 1), + ), + ( + "starcoin_natives.account.create_signer.base".to_string(), + gas_total(24, 1), + ), + ( + "starcoin_natives.account.destroy_signer.base".to_string(), + gas_total(212, 1), + ), + ( + "nursery.event.write_to_event_store.unit_cost".to_string(), + gas_total(52, 1), + ), + ( + "move_stdlib.bcs.to_address.per_byte".to_string(), + gas_total(26, 1), + ), + ( + "starcoin_natives.token.name_of.base".to_string(), + gas_total(2002, 1), + ), + ] +} + +// native_table_v2 +pub fn native_gas_schedule_v2() -> Vec<(String, u64)> { + let gas_total = |x: u64, y: u64| -> u64 { x + y }; + let mut natives = native_gas_schedule_v1(); + let mut natives_delta = vec![( + "starcoin_natives.hash.keccak256.per_byte".to_string(), + gas_total(64, 1), + )]; + natives.append(&mut natives_delta); + natives +} + +// v3_native_table +pub fn native_gas_schedule_v3() -> Vec<(String, u64)> { + let gas_total = |x: u64, y: u64| -> u64 { x + y }; + let mut natives = native_gas_schedule_v2(); + let mut natives_delta = vec![ + ( + "starcoin_natives.hash.ripemd160.per_byte".to_string(), + gas_total(64, 1), + ), + ( + "starcoin_natives.signature.ec_recover.per_byte".to_string(), + gas_total(128, 1), + ), + ( + "starcoin_natives.u256.from_bytes.per_byte".to_string(), + gas_total(2, 1), + ), + ( + "starcoin_natives.u256.add.base".to_string(), + gas_total(4, 1), + ), + ( + "starcoin_natives.u256.sub.base".to_string(), + gas_total(4, 1), + ), + ( + "starcoin_natives.u256.mul.base".to_string(), + gas_total(4, 1), + ), + ( + "starcoin_natives.u256.div.base".to_string(), + gas_total(10, 1), + ), + ( + "starcoin_natives.u256.rem.base".to_string(), + gas_total(4, 1), + ), + ( + "starcoin_natives.u256.pow.base".to_string(), + gas_total(8, 1), + ), + ( + "move_stdlib.vector.append.legacy_per_abstract_memory_unit".to_string(), + gas_total(40, 1), + ), + ( + "move_stdlib.vector.remove.legacy_per_abstract_memory_unit".to_string(), + gas_total(20, 1), + ), + ( + "move_stdlib.vector.reverse.legacy_per_abstract_memory_unit".to_string(), + gas_total(10, 1), + ), + ]; + natives.append(&mut natives_delta); + natives +} + +// v4_native_table +pub fn native_gas_schedule_v4() -> Vec<(String, u64)> { + let gas_total = |x: u64, y: u64| -> u64 { x + y }; + let mut natives = native_gas_schedule_v3(); + let mut natives_delta = vec![ + ("table.new_table_handle.base".to_string(), gas_total(4, 1)), + ( + "table.add_box.per_byte_serialized".to_string(), + gas_total(4, 1), + ), + ( + "table.borrow_box.per_byte_serialized".to_string(), + gas_total(10, 1), + ), + ( + "table.remove_box.per_byte_serialized".to_string(), + gas_total(8, 1), + ), + ( + "table.contains_box.per_byte_serialized".to_string(), + gas_total(40, 1), + ), + ("table.destroy_empty_box.base".to_string(), gas_total(20, 1)), + ( + "table.drop_unchecked_box.base".to_string(), + gas_total(73, 1), + ), + ( + "move_stdlib.string.check_utf8.per_byte".to_string(), + gas_total(4, 1), + ), + ( + "move_stdlib.string.sub_string.per_byte".to_string(), + gas_total(4, 1), + ), + ( + "move_stdlib.string.is_char_boundary.base".to_string(), + gas_total(4, 1), + ), + ( + "move_stdlib.string.index_of.per_byte_searched".to_string(), + gas_total(4, 1), + ), + ]; + natives.append(&mut natives_delta); + natives +} + +// G_GAS_CONSTANTS_V1 +pub fn txn_gas_schedule_v1() -> Vec<(String, u64)> { + vec![ + ("txn.global_memory_per_byte_cost".to_string(), 4), + ("txn.global_memory_per_byte_write_cost".to_string(), 9), + ("txn.min_transaction_gas_units".to_string(), 600), + ("txn.large_transaction_cutoff".to_string(), 600), + ("txn.intrinsic_gas_per_byte".to_string(), 8), + ("txn.maximum_number_of_gas_units".to_string(), 40_000_000), + ("txn.min_price_per_gas_unit".to_string(), 1), + ("txn.max_price_per_gas_unit".to_string(), 10_000), + ( + "txn.max_transaction_size_in_bytes".to_string(), + G_MAX_TRANSACTION_SIZE_IN_BYTES_V1, + ), + ("txn.gas_unit_scaling_factor".to_string(), 1), + ("txn.default_account_size".to_string(), 800), + ] +} + +// G_GAS_CONSTANTS_V2 +pub fn txn_gas_schedule_v2() -> Vec<(String, u64)> { + vec![ + ("txn.global_memory_per_byte_cost".to_string(), 4), + ("txn.global_memory_per_byte_write_cost".to_string(), 9), + ("txn.min_transaction_gas_units".to_string(), 600), + ("txn.large_transaction_cutoff".to_string(), 600), + ("txn.intrinsic_gas_per_byte".to_string(), 8), + ("txn.maximum_number_of_gas_units".to_string(), 40_000_000), + ("txn.min_price_per_gas_unit".to_string(), 1), + ("txn.max_price_per_gas_unit".to_string(), 10_000), + ( + "txn.max_transaction_size_in_bytes".to_string(), + G_MAX_TRANSACTION_SIZE_IN_BYTES_V2, + ), + ("txn.gas_unit_scaling_factor".to_string(), 1), + ("txn.default_account_size".to_string(), 800), + ] +} + +// G_GAS_CONSTANTS_V3 +pub fn txn_gas_schedule_v3() -> Vec<(String, u64)> { + vec![ + ("txn.global_memory_per_byte_cost".to_string(), 4), + ("txn.global_memory_per_byte_write_cost".to_string(), 9), + ("txn.min_transaction_gas_units".to_string(), 600), + ("txn.large_transaction_cutoff".to_string(), 600), + ("txn.intrinsic_gas_per_byte".to_string(), 8), + ("txn.maximum_number_of_gas_units".to_string(), 40_000_000), + ("txn.min_price_per_gas_unit".to_string(), 1), + ("txn.max_price_per_gas_unit".to_string(), 10_000), + ( + "txn.max_transaction_size_in_bytes".to_string(), + G_MAX_TRANSACTION_SIZE_IN_BYTES_V3, + ), + ("txn.gas_unit_scaling_factor".to_string(), 1), + ("txn.default_account_size".to_string(), 800), + ] +} + +// G_GAS_CONSTANTS_TEST +pub fn txn_gas_schedule_test() -> Vec<(String, u64)> { + vec![ + ("txn.global_memory_per_byte_cost".to_string(), 4), + ("txn.global_memory_per_byte_write_cost".to_string(), 9), + ("txn.min_transaction_gas_units".to_string(), 600), + ("txn.large_transaction_cutoff".to_string(), 600), + ("txn.intrinsic_gas_per_byte".to_string(), 8), + ( + "txn.maximum_number_of_gas_units".to_string(), + 40_000_000 * 10, + ), + ("txn.min_price_per_gas_unit".to_string(), 0), + ("txn.max_price_per_gas_unit".to_string(), 10_000), + ( + "txn.max_transaction_size_in_bytes".to_string(), + G_MAX_TRANSACTION_SIZE_IN_BYTES_V3, + ), + ("txn.gas_unit_scaling_factor".to_string(), 1), + ("txn.default_account_size".to_string(), 800), + ] +} + +// XXX FIXME YSG, check wether we need add gas_schedule in storage +impl OnChainConfig for GasSchedule { + const MODULE_IDENTIFIER: &'static str = "gas_schedule"; + const CONF_IDENTIFIER: &'static str = "GasScheduleConfig"; +} + +static G_INSTR_STRS: Lazy> = Lazy::new(|| { + vec![ + "instr.pop", + "instr.ret", + "instr.br_true", + "instr.br_false", + "instr.branch", + "instr.ld_u64", + "instr.ld_const.per_byte", + "instr.ld_true", + "instr.ld_false", + "instr.copy_loc.per_abs_mem_unit", + "instr.move_loc.per_abs_mem_unit", + "instr.st_loc.per_abs_mem_unit", + "instr.mut_borrow_loc", + "instr.imm_borrow_loc", + "instr.mut_borrow_field", + "instr.imm_borrow_field", + "instr.call.per_arg", + "instr.pack.per_abs_mem_unit", + "instr.unpack.per_abs_mem_unit", + "instr.read_ref.per_abs_mem_unit", + "instr.write_ref.per_abs_mem_unit", + "instr.add", + "instr.sub", + "instr.mul", + "instr.mod", + "instr.div", + "instr.bit_or", + "instr.bit_and", + "instr.xor", + "instr.or", + "instr.and", + "instr.not", + "instr.eq.per_abs_mem_unit", + "instr.neq.per_abs_mem_unit", + "instr.lt", + "instr.gt", + "instr.le", + "instr.ge", + "instr.abort", + "instr.nop", + "instr.exists.per_abs_mem_unit", + "instr.mut_borrow_global.per_abs_mem_unit", + "instr.imm_borrow_global.per_abs_mem_unit", + "instr.move_from.per_abs_mem_unit", + "instr.move_to.per_abs_mem_unit", + "instr.freeze_ref", + "instr.shl", + "instr.shr", + "instr.ld_u8", + "instr.ld_u128", + "instr.cast_u8", + "instr.cast_u64", + "instr.cast_u128", + "instr.mut_borrow_field_generic.base", + "instr.imm_borrow_field_generic.base", + "instr.call_generic.per_arg", + "instr.pack_generic.per_abs_mem_unit", + "instr.unpack_generic.per_abs_mem_unit", + "instr.exists_generic.per_abs_mem_unit", + "instr.mut_borrow_global_generic.per_abs_mem_unit", + "instr.imm_borrow_global_generic.per_abs_mem_unit", + "instr.move_from_generic.per_abs_mem_unit", + "instr.move_to_generic.per_abs_mem_unit", + "instr.vec_pack.per_elem", + "instr.vec_len.base", + "instr.vec_imm_borrow.base", + "instr.vec_mut_borrow.base", + "instr.vec_push_back.per_abs_mem_unit", + "instr.vec_pop_back.base", + "instr.vec_unpack.per_expected_elem", + "instr.vec_swap.base", + ] +}); + +static G_NATIVE_STRS: Lazy> = Lazy::new(|| { + vec![ + "move_stdlib.hash.sha2_256.per_byte", + "move_stdlib.hash.sha3_256.per_byte", + "starcoin_natives.signature.ed25519_verify.per_byte", + // ED25519_THRESHOLD_VERIFY 3 this native funciton is deprecated, ignore, use "" + "", + "move_stdlib.bcs.to_bytes.per_byte_serialized", + "move_stdlib.vector.length.base", + "move_stdlib.vector.empty.base", + "move_stdlib.vector.borrow.base", + // Vector::borrow_mut is same Vector::borrow ignore "" + "", + "move_stdlib.vector.push_back.legacy_per_abstract_memory_unit", + "move_stdlib.vector.pop_back.base", + "move_stdlib.vector.destroy_empty.base", + "move_stdlib.vector.swap.base", + "starcoin_natives.signature.ed25519_validate_key.per_byte", + "move_stdlib.signer.borrow_address.base", + "starcoin_natives.account.create_signer.base", + "starcoin_natives.account.destroy_signer.base", + "nursery.event.write_to_event_store.unit_cost", + "move_stdlib.bcs.to_address.per_byte", + "starcoin_natives.token.name_of.base", + "starcoin_natives.hash.keccak256.per_byte", + "starcoin_natives.hash.ripemd160.per_byte", + "starcoin_natives.signature.ec_recover.per_byte", + "starcoin_natives.u256.from_bytes.per_byte", + "starcoin_natives.u256.add.base", + "starcoin_natives.u256.sub.base", + "starcoin_natives.u256.mul.base", + "starcoin_natives.u256.div.base", + "starcoin_natives.u256.rem.base", + "starcoin_natives.u256.pow.base", + "move_stdlib.vector.append.legacy_per_abstract_memory_unit", + "move_stdlib.vector.remove.legacy_per_abstract_memory_unit", + "move_stdlib.vector.reverse.legacy_per_abstract_memory_unit", + "table.new_table_handle.base", + "table.add_box.per_byte_serialized", + "table.borrow_box.per_byte_serialized", + "table.remove_box.per_byte_serialized", + "table.contains_box.per_byte_serialized", + "table.destroy_empty_box.base", + "table.drop_unchecked_box.base", + "move_stdlib.string.check_utf8.per_byte", + "move_stdlib.string.sub_string.per_byte", + "move_stdlib.string.is_char_boundary.base", + "move_stdlib.string.index_of.per_byte_searched", + ] +}); + +// https://github.com/starcoinorg/starcoin-framework/blob/main/sources/VMConfig.move +impl From<&VMConfig> for GasSchedule { + fn from(vm_config: &VMConfig) -> Self { + let mut entries = vec![]; + + // see vm/gas_algebra-ext/src/instr.rs + // see https://github.com/starcoinorg/starcoin-framework/blob/main/sources/VMConfig.move#instruction_schedule + let instrs = vm_config.gas_schedule.instruction_table.clone(); + for (idx, cost) in instrs.into_iter().enumerate() { + entries.push((G_INSTR_STRS[idx].to_string(), cost.total())); + } + entries.push(("instr.ld_u16".to_string(), 3)); + entries.push(("instr.ld_u32".to_string(), 2)); + entries.push(("instr.ld_u256".to_string(), 3)); + entries.push(("instr.cast_u16".to_string(), 3)); + entries.push(("instr.cast_u32".to_string(), 2)); + entries.push(("instr.cast_u256".to_string(), 3)); + + // see vm/gas_algebra-ext/src/{move_stdlib.rs starcoin_framework.rs nursery.rs table.rs} + // see https://github.com/starcoinorg/starcoin-framework/blob/main/sources/VMConfig.move#native_schedule + let natives = vm_config.gas_schedule.native_table.clone(); + for (idx, cost) in natives.into_iter().enumerate() { + if G_NATIVE_STRS[idx].is_empty() { + continue; + } + entries.push((G_NATIVE_STRS[idx].to_string(), cost.total())); + } + + // native_table don't have these + entries.push(("nursery.debug.print.base_cost".to_string(), 1)); + entries.push(("nursery.debug.print_stack_trace.base_cost".to_string(), 1)); + + entries.push(( + "move_stdlib.hash.sha2_256.legacy_min_input_len".to_string(), + 1, + )); + entries.push(( + "move_stdlib.hash.sha3_256.legacy_min_input_len".to_string(), + 1, + )); + entries.push(("move_stdlib.bcs.to_bytes.failure".to_string(), 182)); + entries.push(( + "move_stdlib.bcs.to_bytes.legacy_min_output_size".to_string(), + 1, + )); + + // see vm/gas_algebra-ext/src/transaction.rs + let txn = &vm_config.gas_schedule.gas_constants; + entries.push(( + "txn.global_memory_per_byte_cost".to_string(), + txn.global_memory_per_byte_cost, + )); + entries.push(( + "txn.global_memory_per_byte_write_cost".to_string(), + txn.global_memory_per_byte_write_cost, + )); + entries.push(( + "txn.min_transaction_gas_units".to_string(), + txn.min_transaction_gas_units, + )); + entries.push(( + "txn.large_transaction_cutoff".to_string(), + txn.large_transaction_cutoff, + )); + entries.push(( + "txn.intrinsic_gas_per_byte".to_string(), + txn.intrinsic_gas_per_byte, + )); + entries.push(( + "txn.maximum_number_of_gas_units".to_string(), + txn.maximum_number_of_gas_units, + )); + entries.push(( + "txn.min_price_per_gas_unit".to_string(), + txn.min_price_per_gas_unit, + )); + entries.push(( + "txn.max_price_per_gas_unit".to_string(), + txn.max_price_per_gas_unit, + )); + entries.push(( + "txn.max_transaction_size_in_bytes".to_string(), + txn.max_transaction_size_in_bytes, + )); + entries.push(( + "txn.gas_unit_scaling_factor".to_string(), + txn.gas_unit_scaling_factor, + )); + entries.push(( + "txn.default_account_size".to_string(), + txn.default_account_size, + )); + + Self { entries } + } +} diff --git a/vm/types/src/on_chain_config/genesis_gas_schedule.rs b/vm/types/src/on_chain_config/genesis_gas_schedule.rs index c5d501c315..2eb4a2fd9f 100644 --- a/vm/types/src/on_chain_config/genesis_gas_schedule.rs +++ b/vm/types/src/on_chain_config/genesis_gas_schedule.rs @@ -3,8 +3,9 @@ //! This file contains the starting gas schedule published at genesis. -use crate::gas_schedule::{GasCost, NativeCostIndex as N}; +use crate::gas_schedule::NativeCostIndex as N; use once_cell::sync::Lazy; +use starcoin_gas_algebra_ext::GasCost; use vm::file_format::SignatureIndex; use vm::{ file_format::{ @@ -260,14 +261,7 @@ pub fn instruction_table_v2() -> Vec { } /// return latest instruction table, as `initial_instruction_table` function should not be modified. -pub static G_LATEST_INSTRUCTION_TABLE: Lazy> = Lazy::new(|| { - let latest_ins = instruction_table_v2(); - debug_assert!( - latest_ins.len() == Bytecode::VARIANT_COUNT, - "all instructions must be in the cost table" - ); - latest_ins -}); +pub static G_LATEST_INSTRUCTION_TABLE: Lazy> = Lazy::new(instruction_table_v2); pub fn native_table_v1() -> Vec { let mut raw_native_table = vec![ @@ -330,6 +324,7 @@ pub fn native_table_v2() -> Vec { .collect::>() } +#[allow(dead_code)] pub fn v3_native_table() -> Vec { let mut raw_native_table = vec![ (N::SHA2_256, GasCost::new(21, 1)), @@ -373,8 +368,64 @@ pub fn v3_native_table() -> Vec { .collect::>() } +pub fn v4_native_table() -> Vec { + let mut raw_native_table = vec![ + (N::SHA2_256, GasCost::new(21, 1)), + (N::SHA3_256, GasCost::new(64, 1)), + (N::ED25519_VERIFY, GasCost::new(61, 1)), + (N::ED25519_THRESHOLD_VERIFY, GasCost::new(3351, 1)), + (N::BCS_TO_BYTES, GasCost::new(181, 1)), + (N::LENGTH, GasCost::new(98, 1)), + (N::EMPTY, GasCost::new(84, 1)), + (N::BORROW, GasCost::new(1334, 1)), + (N::BORROW_MUT, GasCost::new(1902, 1)), + (N::PUSH_BACK, GasCost::new(53, 1)), + (N::POP_BACK, GasCost::new(227, 1)), + (N::DESTROY_EMPTY, GasCost::new(572, 1)), + (N::SWAP, GasCost::new(1436, 1)), + (N::ED25519_VALIDATE_KEY, GasCost::new(26, 1)), + (N::SIGNER_BORROW, GasCost::new(353, 1)), + (N::CREATE_SIGNER, GasCost::new(24, 1)), + (N::DESTROY_SIGNER, GasCost::new(212, 1)), + (N::EMIT_EVENT, GasCost::new(52, 1)), + (N::BCS_TO_ADDRESS, GasCost::new(26, 1)), + (N::TOKEN_NAME_OF, GasCost::new(2002, 1)), + (N::KECCAK_256, GasCost::new(64, 1)), + (N::RIPEMD160, GasCost::new(64, 1)), + (N::ECRECOVER, GasCost::new(128, 1)), + (N::U256_FROM_BYTES, GasCost::new(2, 1)), + (N::U256_ADD, GasCost::new(4, 1)), + (N::U256_SUB, GasCost::new(4, 1)), + (N::U256_MUL, GasCost::new(4, 1)), + (N::U256_DIV, GasCost::new(10, 1)), + (N::U256_REM, GasCost::new(4, 1)), + (N::U256_POW, GasCost::new(8, 1)), + (N::VEC_APPEND, GasCost::new(40, 1)), + (N::VEC_REMOVE, GasCost::new(20, 1)), + (N::VEC_REVERSE, GasCost::new(10, 1)), + // XXX FIXME YSG instr_gas + (N::TABLE_NEW, GasCost::new(4, 1)), + (N::TABLE_INSERT, GasCost::new(4, 1)), + (N::TABLE_BORROW, GasCost::new(10, 1)), + (N::TABLE_REMOVE, GasCost::new(8, 1)), + (N::TABLE_CONTAINS, GasCost::new(40, 1)), + (N::TABLE_DESTROY, GasCost::new(20, 1)), + (N::TABLE_DROP, GasCost::new(73, 1)), + //TODO WGB inst_gas + (N::STRING_CHECK_UT8, GasCost::new(4, 1)), + (N::STRING_SUB_STR, GasCost::new(4, 1)), + (N::SRING_CHAR_BOUNDARY, GasCost::new(4, 1)), + (N::STRING_INDEX_OF, GasCost::new(4, 1)), + ]; + raw_native_table.sort_by_key(|cost| cost.0 as u64); + raw_native_table + .into_iter() + .map(|(_, cost)| cost) + .collect::>() +} + pub static G_LATEST_NATIVE_TABLE: Lazy> = Lazy::new(|| { - let native_table = v3_native_table(); + let native_table = v4_native_table(); debug_assert!( native_table.len() == N::NUMBER_OF_NATIVE_FUNCTIONS, diff --git a/vm/types/src/on_chain_config/mod.rs b/vm/types/src/on_chain_config/mod.rs index c8cad32ee8..53eb9d3446 100644 --- a/vm/types/src/on_chain_config/mod.rs +++ b/vm/types/src/on_chain_config/mod.rs @@ -18,19 +18,31 @@ use std::{collections::HashMap, sync::Arc}; mod consensus_config; mod dao_config; +mod gas_schedule; mod genesis_gas_schedule; mod move_lang_version; mod version; mod vm_config; + pub use self::{ consensus_config::{consensus_config_type_tag, ConsensusConfig, G_CONSENSUS_CONFIG_IDENTIFIER}, dao_config::DaoConfig, - genesis_gas_schedule::*, + gas_schedule::{ + instruction_gas_schedule_v1, instruction_gas_schedule_v2, native_gas_schedule_v1, + native_gas_schedule_v2, native_gas_schedule_v3, native_gas_schedule_v4, + txn_gas_schedule_test, txn_gas_schedule_v1, txn_gas_schedule_v2, txn_gas_schedule_v3, + GasSchedule, + }, + genesis_gas_schedule::{ + instruction_table_v1, instruction_table_v2, native_table_v1, native_table_v2, + G_LATEST_INSTRUCTION_TABLE, G_LATEST_NATIVE_TABLE, + }, move_lang_version::MoveLanguageVersion, version::{version_config_type_tag, Version, G_VERSION_CONFIG_IDENTIFIER}, vm_config::*, }; pub use crate::on_chain_resource::GlobalTimeOnChain; +use crate::state_store::state_key::StateKey; /// To register an on-chain config in Rust: /// 1. Implement the `OnChainConfig` trait for the Rust representation of the config @@ -106,7 +118,9 @@ where V: StateView, { fn fetch_config(&self, access_path: AccessPath) -> Option> { - self.get(&access_path).ok().flatten() + self.get_state_value(&StateKey::AccessPath(access_path)) + .ok() + .flatten() } } @@ -177,12 +191,12 @@ pub fn access_path_for_config( address: CORE_CODE_ADDRESS, module: Identifier::new("Config").unwrap(), name: Identifier::new("Config").unwrap(), - type_params: vec![TypeTag::Struct(StructTag { + type_params: vec![TypeTag::Struct(Box::new(StructTag { address: CORE_CODE_ADDRESS, module: module_name, name: config_name, type_params: params, - })], + }))], }, ) } diff --git a/vm/types/src/on_chain_config/version.rs b/vm/types/src/on_chain_config/version.rs index 958a509bc5..114ff4217d 100644 --- a/vm/types/src/on_chain_config/version.rs +++ b/vm/types/src/on_chain_config/version.rs @@ -38,10 +38,10 @@ impl MoveResource for Version { const STRUCT_NAME: &'static str = "Version"; } pub fn version_config_type_tag() -> TypeTag { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: CORE_CODE_ADDRESS, module: G_VERSION_CONFIG_IDENTIFIER.clone(), name: G_VERSION_CONFIG_IDENTIFIER.clone(), type_params: vec![], - }) + })) } diff --git a/vm/types/src/on_chain_config/vm_config.rs b/vm/types/src/on_chain_config/vm_config.rs index 997e147844..e0ce7f679e 100644 --- a/vm/types/src/on_chain_config/vm_config.rs +++ b/vm/types/src/on_chain_config/vm_config.rs @@ -1,16 +1,14 @@ // Copyright (c) The Diem Core Contributors // SPDX-License-Identifier: Apache-2.0 -use crate::{ - gas_schedule::{CostTable, GasConstants}, - on_chain_config::OnChainConfig, -}; +use crate::on_chain_config::OnChainConfig; use anyhow::{format_err, Result}; use move_core_types::identifier::Identifier; use move_core_types::language_storage::{StructTag, TypeTag, CORE_CODE_ADDRESS}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use starcoin_crypto::HashValue; +use starcoin_gas_algebra_ext::{CostTable, GasConstants}; pub const SCRIPT_HASH_LENGTH: usize = HashValue::LENGTH; const VM_CONFIG_MODULE_NAME: &str = "VMConfig"; @@ -83,7 +81,7 @@ impl OnChainConfig for TransactionPublishOption { } /// Defines all the on chain configuration data needed by VM. -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] #[allow(clippy::upper_case_acronyms)] pub struct VMConfig { pub gas_schedule: CostTable, @@ -131,10 +129,10 @@ impl OnChainConfig for VMConfig { } pub fn vm_config_type_tag() -> TypeTag { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: CORE_CODE_ADDRESS, module: G_VM_CONFIG_IDENTIFIER.clone(), name: G_VM_CONFIG_IDENTIFIER.clone(), type_params: vec![], - }) + })) } diff --git a/vm/types/src/on_chain_resource/dao/mod.rs b/vm/types/src/on_chain_resource/dao/mod.rs index 68254ff861..ff2baadd2b 100644 --- a/vm/types/src/on_chain_resource/dao/mod.rs +++ b/vm/types/src/on_chain_resource/dao/mod.rs @@ -33,7 +33,7 @@ impl DaoGlobalInfo { address: CORE_CODE_ADDRESS, module: DaoGlobalInfo::module_identifier(), name: DaoGlobalInfo::struct_identifier(), - type_params: vec![TypeTag::Struct(token_type_tag)], + type_params: vec![TypeTag::Struct(Box::new(token_type_tag))], } } @@ -89,7 +89,7 @@ where address: CORE_CODE_ADDRESS, module: Self::module_identifier(), name: Self::struct_identifier(), - type_params: vec![TypeTag::Struct(token_type_tag), A::type_tag()], + type_params: vec![TypeTag::Struct(Box::new(token_type_tag)), A::type_tag()], } } diff --git a/vm/types/src/on_chain_resource/treasury.rs b/vm/types/src/on_chain_resource/treasury.rs index 0415a474f3..f84f6200bc 100644 --- a/vm/types/src/on_chain_resource/treasury.rs +++ b/vm/types/src/on_chain_resource/treasury.rs @@ -30,7 +30,7 @@ impl Treasury { address: CORE_CODE_ADDRESS, module: Self::module_identifier(), name: Self::struct_identifier(), - type_params: vec![TypeTag::Struct(token_type_tag)], + type_params: vec![TypeTag::Struct(Box::new(token_type_tag))], } } @@ -61,7 +61,7 @@ impl LinearWithdrawCapability { address: CORE_CODE_ADDRESS, module: Self::module_identifier(), name: Self::struct_identifier(), - type_params: vec![TypeTag::Struct(token_type_tag)], + type_params: vec![TypeTag::Struct(Box::new(token_type_tag))], } } diff --git a/vm/types/src/state_store/mod.rs b/vm/types/src/state_store/mod.rs new file mode 100644 index 0000000000..e339e363a1 --- /dev/null +++ b/vm/types/src/state_store/mod.rs @@ -0,0 +1,4 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 +pub mod state_key; +pub mod table; diff --git a/vm/types/src/state_store/state_key.rs b/vm/types/src/state_store/state_key.rs new file mode 100644 index 0000000000..ef5ad5ac62 --- /dev/null +++ b/vm/types/src/state_store/state_key.rs @@ -0,0 +1,36 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +// Copyright (c) Aptos +// SPDX-License-Identifier: Apache-2.0 + +use crate::access_path::AccessPath; +use crate::state_store::table::TableHandle; +use schemars::{self, JsonSchema}; +use serde::{Deserialize, Serialize}; + +#[derive( + Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Ord, PartialOrd, Hash, JsonSchema, +)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(proptest_derive::Arbitrary))] +pub struct TableItem { + pub handle: TableHandle, + #[serde(with = "serde_bytes")] + #[schemars(with = "String")] + pub key: Vec, +} + +#[derive( + Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Ord, PartialOrd, Hash, JsonSchema, +)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(proptest_derive::Arbitrary))] +pub enum StateKey { + AccessPath(AccessPath), + TableItem(TableItem), +} + +impl StateKey { + pub fn table_item(handle: TableHandle, key: Vec) -> Self { + StateKey::TableItem(TableItem { handle, key }) + } +} diff --git a/vm/types/src/state_store/table.rs b/vm/types/src/state_store/table.rs new file mode 100644 index 0000000000..ec1871586d --- /dev/null +++ b/vm/types/src/state_store/table.rs @@ -0,0 +1,55 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +// Copyright (c) Aptos +// SPDX-License-Identifier: Apache-2.0 + +use move_core_types::{ + account_address::{AccountAddress, AccountAddressParseError}, + language_storage::TypeTag, +}; +use schemars::{self, JsonSchema}; +use serde::{Deserialize, Serialize}; +use std::str::FromStr; + +#[derive( + Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, JsonSchema, +)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(proptest_derive::Arbitrary))] +pub struct TableHandle(pub AccountAddress); + +impl TableHandle { + pub fn size(&self) -> usize { + std::mem::size_of_val(&self.0) + } +} + +impl FromStr for TableHandle { + type Err = AccountAddressParseError; + + fn from_str(s: &str) -> Result { + let handle = AccountAddress::from_str(s)?; + Ok(Self(handle)) + } +} + +impl From for TableHandle { + fn from(hdl: move_table_extension::TableHandle) -> Self { + Self(hdl.0) + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +pub struct TableInfo { + pub key_type: TypeTag, + pub value_type: TypeTag, +} + +impl TableInfo { + pub fn new(key_type: TypeTag, value_type: TypeTag) -> Self { + Self { + key_type, + value_type, + } + } +} diff --git a/vm/types/src/state_view.rs b/vm/types/src/state_view.rs index 1a59aa801f..a799648ae1 100644 --- a/vm/types/src/state_view.rs +++ b/vm/types/src/state_view.rs @@ -8,6 +8,7 @@ //! This crate defines [`trait StateView`](StateView). +use crate::state_store::state_key::StateKey; use crate::{ access_path::AccessPath, account_config::{ @@ -34,8 +35,8 @@ use serde::de::DeserializeOwned; /// the VM for transaction execution, during which the VM is guaranteed to read anything at the /// given state. pub trait StateView { - /// Gets the state for a single access path. - fn get(&self, access_path: &AccessPath) -> Result>>; + /// Gets the state value for a given state key. + fn get_state_value(&self, state_key: &StateKey) -> Result>>; /// VM needs this method to know whether the current state view is for genesis state creation. /// Currently TransactionPayload::WriteSet is only valid for genesis state creation. @@ -63,10 +64,12 @@ pub trait StateReaderExt: StateView { where R: MoveResource + DeserializeOwned, { - let r = self.get(&access_path).and_then(|state| match state { - Some(state) => Ok(Some(bcs_ext::from_bytes::(state.as_slice())?)), - None => Ok(None), - })?; + let r = self + .get_state_value(&StateKey::AccessPath(access_path)) + .and_then(|state| match state { + Some(state) => Ok(Some(bcs_ext::from_bytes::(state.as_slice())?)), + None => Ok(None), + })?; Ok(r) } @@ -95,10 +98,10 @@ pub trait StateReaderExt: StateView { type_tag: StructTag, ) -> Result> { Ok(self - .get(&AccessPath::new( + .get_state_value(&StateKey::AccessPath(AccessPath::new( address, BalanceResource::access_path_for(type_tag), - )) + ))) .and_then(|bytes| match bytes { Some(bytes) => Ok(Some(bcs_ext::from_bytes::( bytes.as_slice(), @@ -150,7 +153,7 @@ pub trait StateReaderExt: StateView { } fn get_code(&self, module_id: ModuleId) -> Result>> { - self.get(&AccessPath::from(&module_id)) + self.get_state_value(&StateKey::AccessPath(AccessPath::from(&module_id))) } /// Check the sip is activated. if the sip module exist, think it is activated. diff --git a/vm/types/src/token/stc.rs b/vm/types/src/token/stc.rs index 67a291ba3b..82989e85b1 100644 --- a/vm/types/src/token/stc.rs +++ b/vm/types/src/token/stc.rs @@ -22,12 +22,12 @@ pub static G_STC_TOKEN_CODE: Lazy = Lazy::new(|| { static G_STC_IDENTIFIER: Lazy = Lazy::new(|| Identifier::new(STC_NAME).unwrap()); pub fn stc_type_tag() -> TypeTag { - TypeTag::Struct(StructTag { + TypeTag::Struct(Box::new(StructTag { address: CORE_CODE_ADDRESS, module: G_STC_IDENTIFIER.clone(), name: G_STC_IDENTIFIER.clone(), type_params: vec![], - }) + })) } pub const SYMBOL_NANOSTC: &str = "nanoSTC"; diff --git a/vm/types/src/token/token_code.rs b/vm/types/src/token/token_code.rs index ae5213df4f..02ec55af8c 100644 --- a/vm/types/src/token/token_code.rs +++ b/vm/types/src/token/token_code.rs @@ -53,7 +53,7 @@ impl TryFrom for TokenCode { fn try_from(value: TypeTag) -> Result { match value { - TypeTag::Struct(struct_tag) => Ok(TokenCode::from(struct_tag)), + TypeTag::Struct(struct_tag) => Ok(TokenCode::from(*struct_tag)), type_tag => bail!("{:?} is not a Token's type tag", type_tag), } } @@ -86,7 +86,7 @@ impl TryInto for TokenCode { fn try_into(self) -> Result { match parse_type_tag(self.to_string().as_str())? { - TypeTag::Struct(s) => Ok(s), + TypeTag::Struct(s) => Ok(*s), t => bail!("expect token code to be a struct tag, but receive {}", t), } } @@ -96,7 +96,7 @@ impl TryInto for TokenCode { type Error = anyhow::Error; fn try_into(self) -> Result { - Ok(TypeTag::Struct(self.try_into()?)) + Ok(TypeTag::Struct(Box::new(self.try_into()?))) } } @@ -161,7 +161,7 @@ mod test { assert_eq!(token.to_string(), tc.to_string()); assert_eq!( parse_type_tag(token).unwrap(), - TypeTag::Struct(type_tag.clone()) + TypeTag::Struct(Box::new(type_tag.clone())) ); assert_eq!(tc, type_tag.try_into().unwrap()); } diff --git a/vm/types/src/token/token_info.rs b/vm/types/src/token/token_info.rs index a3ac1aa423..5dfc8eaea4 100644 --- a/vm/types/src/token/token_info.rs +++ b/vm/types/src/token/token_info.rs @@ -37,7 +37,7 @@ impl TokenInfo { address: CORE_CODE_ADDRESS, module: TokenInfo::module_identifier(), name: TokenInfo::struct_identifier(), - type_params: vec![TypeTag::Struct(token_type_tag)], + type_params: vec![TypeTag::Struct(Box::new(token_type_tag))], } } diff --git a/vm/types/src/transaction/mod.rs b/vm/types/src/transaction/mod.rs index 99cf9c89e8..34de8b6ec4 100644 --- a/vm/types/src/transaction/mod.rs +++ b/vm/types/src/transaction/mod.rs @@ -29,6 +29,8 @@ use starcoin_crypto::{ use std::ops::Deref; use std::{convert::TryFrom, fmt}; +use crate::state_store::state_key::StateKey; +use crate::write_set::WriteOp; pub use error::CallError; pub use error::Error as TransactionError; pub use module::Module; @@ -690,6 +692,16 @@ impl TransactionOutput { pub fn into_inner(self) -> (WriteSet, Vec, u64, TransactionStatus) { (self.write_set, self.events, self.gas_used, self.status) } + + pub fn table_items(&self) -> Vec<(StateKey, WriteOp)> { + let mut table_items = vec![]; + for (state_key, op) in &self.write_set { + if let StateKey::TableItem(table_item) = state_key { + table_items.push((StateKey::TableItem(table_item.clone()), op.clone())); + } + } + table_items + } } /// `TransactionInfo` is the object we store in the transaction accumulator. It consists of the diff --git a/vm/types/src/transaction_metadata.rs b/vm/types/src/transaction_metadata.rs index 17bd6a1dc3..d8fc9b9955 100644 --- a/vm/types/src/transaction_metadata.rs +++ b/vm/types/src/transaction_metadata.rs @@ -12,11 +12,10 @@ use crate::{ transaction::{TransactionPayload, TransactionPayloadType}, }; use anyhow::Result; -use move_core_types::gas_schedule::{ - AbstractMemorySize, GasAlgebra, GasCarrier, GasPrice, GasUnits, -}; +use move_core_types::gas_algebra::NumBytes; use starcoin_crypto::hash::PlainCryptoHash; use starcoin_crypto::HashValue; +use starcoin_gas_algebra_ext::{FeePerGasUnit, Gas}; use std::str::FromStr; pub enum TransactionPayloadMetadata { @@ -39,10 +38,10 @@ pub struct TransactionMetadata { pub sender: AccountAddress, pub authentication_key_preimage: Vec, pub sequence_number: u64, - pub max_gas_amount: GasUnits, - pub gas_unit_price: GasPrice, + pub max_gas_amount: Gas, + pub gas_unit_price: FeePerGasUnit, pub gas_token_code: TokenCode, - pub transaction_size: AbstractMemorySize, + pub transaction_size: NumBytes, pub expiration_timestamp_secs: u64, pub chain_id: ChainId, pub payload: TransactionPayloadMetadata, @@ -64,11 +63,11 @@ impl TransactionMetadata { sender: txn.sender(), authentication_key_preimage: auth_preimage.into_vec(), sequence_number: txn.sequence_number(), - max_gas_amount: GasUnits::new(txn.max_gas_amount()), - gas_unit_price: GasPrice::new(txn.gas_unit_price()), + max_gas_amount: txn.max_gas_amount().into(), + gas_unit_price: txn.gas_unit_price().into(), gas_token_code: TokenCode::from_str(txn.gas_token_code().as_str()) .map_err(|_e| VMStatus::Error(StatusCode::BAD_TRANSACTION_FEE_CURRENCY))?, - transaction_size: AbstractMemorySize::new(txn.txn_size() as u64), + transaction_size: (txn.txn_size() as u64).into(), expiration_timestamp_secs: txn.expiration_timestamp_secs(), chain_id: txn.chain_id(), payload: match txn.payload() { @@ -83,11 +82,11 @@ impl TransactionMetadata { }, }) } - pub fn max_gas_amount(&self) -> GasUnits { + pub fn max_gas_amount(&self) -> Gas { self.max_gas_amount } - pub fn gas_unit_price(&self) -> GasPrice { + pub fn gas_unit_price(&self) -> FeePerGasUnit { self.gas_unit_price } @@ -107,7 +106,7 @@ impl TransactionMetadata { self.sequence_number } - pub fn transaction_size(&self) -> AbstractMemorySize { + pub fn transaction_size(&self) -> NumBytes { self.transaction_size } diff --git a/vm/types/src/write_set.rs b/vm/types/src/write_set.rs index bb457af3b3..e37993c855 100644 --- a/vm/types/src/write_set.rs +++ b/vm/types/src/write_set.rs @@ -4,7 +4,7 @@ //! For each transaction the VM executes, the VM will output a `WriteSet` that contains each access //! path it updates. For each access path, the VM can either give its new value or delete it. -use crate::access_path::AccessPath; +use crate::state_store::state_key::StateKey; use anyhow::Result; use serde::{Deserialize, Serialize}; @@ -40,7 +40,7 @@ impl std::fmt::Debug for WriteOp { } } -/// `WriteSet` contains all access paths that one transaction modifies. Each of them is a `WriteOp` +/// `WriteSet` contains all StateKey that one transaction modifies. Each of them is a `WriteOp` /// where `Value(val)` means that serialized representation should be updated to `val`, and /// `Deletion` means that we are going to delete this access path. #[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Serialize, Deserialize)] @@ -53,7 +53,7 @@ impl WriteSet { } #[inline] - pub fn iter(&self) -> ::std::slice::Iter<'_, (AccessPath, WriteOp)> { + pub fn iter(&self) -> ::std::slice::Iter<'_, (StateKey, WriteOp)> { self.into_iter() } @@ -68,15 +68,15 @@ impl WriteSet { /// This is separate because it goes through validation before becoming an immutable `WriteSet`. #[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Serialize, Deserialize)] pub struct WriteSetMut { - write_set: Vec<(AccessPath, WriteOp)>, + write_set: Vec<(StateKey, WriteOp)>, } impl WriteSetMut { - pub fn new(write_set: Vec<(AccessPath, WriteOp)>) -> Self { + pub fn new(write_set: Vec<(StateKey, WriteOp)>) -> Self { Self { write_set } } - pub fn push(&mut self, item: (AccessPath, WriteOp)) { + pub fn push(&mut self, item: (StateKey, WriteOp)) { self.write_set.push(item); } @@ -91,19 +91,9 @@ impl WriteSetMut { } } -impl ::std::iter::FromIterator<(AccessPath, WriteOp)> for WriteSetMut { - fn from_iter>(iter: I) -> Self { - let mut ws = WriteSetMut::default(); - for write in iter { - ws.push((write.0, write.1)); - } - ws - } -} - impl<'a> IntoIterator for &'a WriteSet { - type Item = &'a (AccessPath, WriteOp); - type IntoIter = ::std::slice::Iter<'a, (AccessPath, WriteOp)>; + type Item = &'a (StateKey, WriteOp); + type IntoIter = ::std::slice::Iter<'a, (StateKey, WriteOp)>; fn into_iter(self) -> Self::IntoIter { self.0.write_set.iter() @@ -111,8 +101,8 @@ impl<'a> IntoIterator for &'a WriteSet { } impl ::std::iter::IntoIterator for WriteSet { - type Item = (AccessPath, WriteOp); - type IntoIter = ::std::vec::IntoIter<(AccessPath, WriteOp)>; + type Item = (StateKey, WriteOp); + type IntoIter = ::std::vec::IntoIter<(StateKey, WriteOp)>; fn into_iter(self) -> Self::IntoIter { self.0.write_set.into_iter() diff --git a/vm/vm-runtime/Cargo.toml b/vm/vm-runtime/Cargo.toml index 477d109451..71773c11f6 100644 --- a/vm/vm-runtime/Cargo.toml +++ b/vm/vm-runtime/Cargo.toml @@ -2,6 +2,7 @@ anyhow = { workspace = true } bcs-ext = { package = "bcs-ext", workspace = true } starcoin-crypto = { package = "starcoin-crypto", workspace = true } +starcoin-config = { workspace = true } move-core-types = { workspace = true } once_cell = { workspace = true } tracing = { workspace = true } @@ -13,16 +14,20 @@ starcoin-logger = { workspace = true } starcoin-natives = { workspace = true } starcoin-types = { workspace = true } starcoin-vm-types = { workspace = true } -move-stdlib = { optional = true, workspace = true } +move-stdlib = { workspace = true } +move-table-extension = { workspace = true } starcoin-metrics = { optional = true, workspace = true } +starcoin-gas = { workspace = true } +starcoin-gas-algebra-ext = { workspace = true } +serde = { features = ["derive"], workspace = true } [dev-dependencies] stdlib = { package = "stdlib", workspace = true } [features] -default = [ "metrics",] -metrics = [ "starcoin-metrics",] -testing = [ "move-stdlib/testing", "starcoin-natives/testing",] +default = ["metrics"] +metrics = ["starcoin-metrics"] +testing = ["move-stdlib/testing", "starcoin-natives/testing"] [package] authors = { workspace = true } diff --git a/vm/vm-runtime/src/data_cache.rs b/vm/vm-runtime/src/data_cache.rs index 71cd8be165..00ea636155 100644 --- a/vm/vm-runtime/src/data_cache.rs +++ b/vm/vm-runtime/src/data_cache.rs @@ -3,9 +3,12 @@ //! Scratchpad for on chain values during the execution. use crate::create_access_path; +use anyhow::Error; use move_core_types::resolver::{ModuleResolver, ResourceResolver}; +use move_table_extension::{TableHandle, TableResolver}; use starcoin_logger::prelude::*; use starcoin_types::account_address::AccountAddress; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::{ access_path::AccessPath, errors::*, @@ -16,7 +19,7 @@ use starcoin_vm_types::{ write_set::{WriteOp, WriteSet}, }; use std::collections::btree_map::BTreeMap; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; /// A local cache for a given a `StateView`. The cache is private to the Diem layer /// but can be used as a one shot cache for systems that need a simple `RemoteCache` @@ -33,7 +36,7 @@ use std::ops::Deref; /// track of incremental changes is vital to the consistency of the data store and the system. pub struct StateViewCache<'a, S> { data_view: &'a S, - data_map: BTreeMap>>, + data_map: BTreeMap>>, } impl<'a, S: StateView> StateViewCache<'a, S> { @@ -66,14 +69,14 @@ impl<'a, S: StateView> StateViewCache<'a, S> { impl<'block, S: StateView> StateView for StateViewCache<'block, S> { // Get some data either through the cache or the `StateView` on a cache miss. - fn get(&self, access_path: &AccessPath) -> anyhow::Result>> { - match self.data_map.get(access_path) { + fn get_state_value(&self, state_key: &StateKey) -> anyhow::Result>> { + match self.data_map.get(state_key) { Some(opt_data) => Ok(opt_data.clone()), - None => match self.data_view.get(access_path) { + None => match self.data_view.get_state_value(state_key) { Ok(remote_data) => Ok(remote_data), // TODO: should we forward some error info? Err(e) => { - error!("[VM] Error getting data from storage for {:?}", access_path); + error!("[VM] Error getting data from storage for {:?}", state_key); Err(e) } }, @@ -109,7 +112,7 @@ impl<'a, S: StateView> RemoteStorage<'a, S> { pub fn get(&self, access_path: &AccessPath) -> PartialVMResult>> { self.0 - .get(access_path) + .get_state_value(&StateKey::AccessPath(access_path.clone())) .map_err(|_| PartialVMError::new(StatusCode::STORAGE_ERROR)) } } @@ -147,3 +150,88 @@ impl<'a, S> Deref for RemoteStorage<'a, S> { self.0 } } + +impl<'a, S: StateView> TableResolver for RemoteStorage<'a, S> { + fn resolve_table_entry( + &self, + handle: &TableHandle, + key: &[u8], + ) -> Result>, Error> { + self.0 + .get_state_value(&StateKey::table_item((*handle).into(), key.to_vec())) + } +} + +pub trait AsMoveResolver { + fn as_move_resolver(&self) -> RemoteStorage; +} + +impl AsMoveResolver for S { + fn as_move_resolver(&self) -> RemoteStorage { + RemoteStorage::new(self) + } +} + +pub struct RemoteStorageOwned { + state_view: S, +} + +impl Deref for RemoteStorageOwned { + type Target = S; + + fn deref(&self) -> &Self::Target { + &self.state_view + } +} + +impl DerefMut for RemoteStorageOwned { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.state_view + } +} + +impl ModuleResolver for RemoteStorageOwned { + type Error = VMError; + + fn get_module(&self, module_id: &ModuleId) -> Result>, Self::Error> { + self.as_move_resolver().get_module(module_id) + } +} + +impl ResourceResolver for RemoteStorageOwned { + type Error = VMError; + + fn get_resource( + &self, + address: &AccountAddress, + struct_tag: &StructTag, + ) -> Result>, Self::Error> { + self.as_move_resolver().get_resource(address, struct_tag) + } +} + +impl TableResolver for RemoteStorageOwned { + fn resolve_table_entry( + &self, + handle: &TableHandle, + key: &[u8], + ) -> Result>, Error> { + self.as_move_resolver().resolve_table_entry(handle, key) + } +} + +impl ConfigStorage for RemoteStorageOwned { + fn fetch_config(&self, access_path: AccessPath) -> Option> { + self.as_move_resolver().fetch_config(access_path) + } +} + +pub trait IntoMoveResolver { + fn into_move_resolver(self) -> RemoteStorageOwned; +} + +impl IntoMoveResolver for S { + fn into_move_resolver(self) -> RemoteStorageOwned { + RemoteStorageOwned { state_view: self } + } +} diff --git a/vm/vm-runtime/src/lib.rs b/vm/vm-runtime/src/lib.rs index 7d95786299..7b3bcc534d 100644 --- a/vm/vm-runtime/src/lib.rs +++ b/vm/vm-runtime/src/lib.rs @@ -7,8 +7,10 @@ pub mod metrics; pub mod natives; pub mod starcoin_vm; pub use move_vm_runtime::move_vm; +pub use move_vm_runtime::session; mod access_path_cache; mod errors; +pub mod move_vm_ext; use starcoin_vm_types::access_path::AccessPath; use starcoin_vm_types::account_address::AccountAddress; use starcoin_vm_types::language_storage::StructTag; diff --git a/vm/vm-runtime/src/move_vm_ext/mod.rs b/vm/vm-runtime/src/move_vm_ext/mod.rs new file mode 100644 index 0000000000..f3acf98181 --- /dev/null +++ b/vm/vm-runtime/src/move_vm_ext/mod.rs @@ -0,0 +1,12 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +///! MoveVM and Session wrapped, to make sure Starcoin natives and extensions are always installed and +///! taken care of after session finish. +mod resolver; +mod session; +mod vm; + +pub use crate::move_vm_ext::{ + resolver::MoveResolverExt, session::SessionId, session::SessionOutput, vm::MoveVmExt, +}; diff --git a/vm/vm-runtime/src/move_vm_ext/resolver.rs b/vm/vm-runtime/src/move_vm_ext/resolver.rs new file mode 100644 index 0000000000..ac573ee96d --- /dev/null +++ b/vm/vm-runtime/src/move_vm_ext/resolver.rs @@ -0,0 +1,14 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use move_core_types::resolver::MoveResolver; +use move_table_extension::TableResolver; +use std::fmt::Debug; + +pub trait MoveResolverExt: MoveResolver + TableResolver { + type ExtError: Debug; +} + +impl + TableResolver + ?Sized> MoveResolverExt for T { + type ExtError = E; +} diff --git a/vm/vm-runtime/src/move_vm_ext/session.rs b/vm/vm-runtime/src/move_vm_ext/session.rs new file mode 100644 index 0000000000..c427d4c188 --- /dev/null +++ b/vm/vm-runtime/src/move_vm_ext/session.rs @@ -0,0 +1,145 @@ +use crate::access_path_cache::AccessPathCache; +use move_core_types::account_address::AccountAddress; +use move_core_types::effects::{ + ChangeSet as MoveChangeSet, Event as MoveEvent, Op as MoveStorageOp, +}; +use move_core_types::language_storage::ModuleId; +use move_core_types::vm_status::{StatusCode, VMStatus}; +use move_table_extension::TableChangeSet; +use serde::{Deserialize, Serialize}; +use starcoin_crypto::hash::{CryptoHash, CryptoHasher, PlainCryptoHash}; +use starcoin_crypto::HashValue; +use starcoin_vm_types::block_metadata::BlockMetadata; +use starcoin_vm_types::contract_event::ContractEvent; +use starcoin_vm_types::event::EventKey; +use starcoin_vm_types::state_store::state_key::StateKey; +use starcoin_vm_types::transaction::SignatureCheckedTransaction; +use starcoin_vm_types::transaction_metadata::TransactionMetadata; +use starcoin_vm_types::write_set::{WriteOp, WriteSet, WriteSetMut}; +use std::convert::TryFrom; + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, CryptoHasher, CryptoHash)] +pub enum SessionId { + Txn { + sender: AccountAddress, + sequence_number: u64, + }, + BlockMeta { + id: HashValue, + }, + Void, +} + +impl SessionId { + pub fn txn(txn: &SignatureCheckedTransaction) -> Self { + Self::Txn { + sender: txn.sender(), + sequence_number: txn.sequence_number(), + } + } + + pub fn txn_meta(txn_data: &TransactionMetadata) -> Self { + Self::Txn { + sender: txn_data.sender, + sequence_number: txn_data.sequence_number, + } + } + + pub fn block_meta(block_meta: &BlockMetadata) -> Self { + Self::BlockMeta { + id: block_meta.id(), + } + } + + pub fn void() -> Self { + Self::Void + } + + pub fn hash(&self) -> HashValue { + match self { + Self::BlockMeta { id } => *id, + _ => self.crypto_hash(), + } + } + + pub fn as_uuid(&self) -> HashValue { + self.hash() + } +} + +pub struct SessionOutput { + pub change_set: MoveChangeSet, + pub events: Vec, + pub table_change_set: TableChangeSet, +} + +impl SessionOutput { + pub fn into_change_set( + self, + ap_cache: &mut C, + ) -> Result<(WriteSet, Vec), VMStatus> { + let Self { + change_set, + events, + table_change_set, + } = self; + + // XXX FIXME YSG check write_set need upgrade? why aptos no need MoveStorageOp + let mut write_set_mut = WriteSetMut::new(Vec::new()); + for (addr, account_changeset) in change_set.into_inner() { + let (modules, resources) = account_changeset.into_inner(); + for (struct_tag, blob_opt) in resources { + let ap = ap_cache.get_resource_path(addr, struct_tag); + let op = match blob_opt { + MoveStorageOp::Delete => WriteOp::Deletion, + MoveStorageOp::New(blob) => WriteOp::Value(blob), + MoveStorageOp::Modify(blob) => WriteOp::Value(blob), + }; + write_set_mut.push((StateKey::AccessPath(ap), op)) + } + + // XXX FIXME YSG check write_set need upgrade? why aptos no need MoveStorageOp + for (name, blob_opt) in modules { + let ap = ap_cache.get_module_path(ModuleId::new(addr, name)); + let op = match blob_opt { + MoveStorageOp::Delete => WriteOp::Deletion, + MoveStorageOp::New(blob) => WriteOp::Value(blob), + MoveStorageOp::Modify(blob) => WriteOp::Value(blob), + }; + + write_set_mut.push((StateKey::AccessPath(ap), op)) + } + } + + for (handle, change) in table_change_set.changes { + for (key, value_op) in change.entries { + let state_key = StateKey::table_item(handle.into(), key); + // XXX FIXME YSG check write_set need upgrade? why aptos no need MoveStorageOp + match value_op { + MoveStorageOp::Delete => write_set_mut.push((state_key, WriteOp::Deletion)), + MoveStorageOp::New(bytes) => { + write_set_mut.push((state_key, WriteOp::Value(bytes))) + } + MoveStorageOp::Modify(bytes) => { + write_set_mut.push((state_key, WriteOp::Value(bytes))) + } + } + } + } + + let write_set = write_set_mut + .freeze() + .map_err(|_| VMStatus::Error(StatusCode::DATA_FORMAT_ERROR))?; + + let events = events + .into_iter() + .map(|(guid, seq_num, ty_tag, blob)| { + let key = EventKey::try_from(guid.as_slice()) + .map_err(|_| VMStatus::Error(StatusCode::EVENT_KEY_MISMATCH))?; + Ok(ContractEvent::new(key, seq_num, ty_tag, blob)) + }) + .collect::, VMStatus>>()?; + + Ok((write_set, events)) + } +} diff --git a/vm/vm-runtime/src/move_vm_ext/vm.rs b/vm/vm-runtime/src/move_vm_ext/vm.rs new file mode 100644 index 0000000000..bfa8b38b3b --- /dev/null +++ b/vm/vm-runtime/src/move_vm_ext/vm.rs @@ -0,0 +1,52 @@ +// Copyright (c) The Starcoin Core Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::move_vm_ext::session::SessionId; +use crate::move_vm_ext::MoveResolverExt; +use crate::natives; +use move_table_extension::NativeTableContext; +use move_vm_runtime::move_vm::MoveVM; +use move_vm_runtime::native_extensions::NativeContextExtensions; +use move_vm_runtime::session::Session; +use starcoin_gas::NativeGasParameters; +use starcoin_vm_types::errors::{PartialVMResult, VMResult}; +use std::ops::Deref; + +pub struct MoveVmExt { + inner: MoveVM, +} + +impl MoveVmExt { + // XXX FIXME YSG need add treat_friend_as_private? + pub fn new(native_gas_params: NativeGasParameters) -> VMResult { + Ok(Self { + inner: MoveVM::new(natives::starcoin_natives(native_gas_params))?, + }) + } + + pub fn new_session<'r, S: MoveResolverExt>( + &self, + remote: &'r S, + session_id: SessionId, + ) -> Session<'r, '_, S> { + let mut extensions = NativeContextExtensions::default(); + extensions.add(NativeTableContext::new(*session_id.as_uuid(), remote)); + self.inner.new_session_with_extensions(remote, extensions) + } + + pub fn update_native_functions( + &mut self, + native_gas_params: NativeGasParameters, + ) -> PartialVMResult<()> { + let native_functions = natives::starcoin_natives(native_gas_params); + self.inner.update_native_functions(native_functions) + } +} + +impl Deref for MoveVmExt { + type Target = MoveVM; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} diff --git a/vm/vm-runtime/src/natives.rs b/vm/vm-runtime/src/natives.rs index e2fa9cc1c5..56dbcadbb9 100644 --- a/vm/vm-runtime/src/natives.rs +++ b/vm/vm-runtime/src/natives.rs @@ -1,4 +1,149 @@ +use move_core_types::account_address::AccountAddress; // Copyright (c) The Starcoin Core Contributors // SPDX-License-Identifier: Apache-2.0 +use move_core_types::language_storage::CORE_CODE_ADDRESS; +use move_vm_runtime::native_functions; +use move_vm_runtime::native_functions::{ + make_table_from_iter, NativeFunction, NativeFunctionTable, +}; +use starcoin_gas::NativeGasParameters; -pub use starcoin_natives::starcoin_natives; +/// The function returns all native functions supported by Starcoin. +/// NOTICE: +/// - mostly re-use natives defined in move-stdlib. +/// - be careful with the native cost table index used in the implementation +pub fn starcoin_natives(gas_params: NativeGasParameters) -> NativeFunctionTable { + let mut natives = vec![]; + + macro_rules! add_natives_from_module { + ($module_name: expr, $natives: expr) => { + natives.extend( + $natives.map(|(func_name, func)| ($module_name.to_string(), func_name, func)), + ); + }; + } + + add_natives_from_module!( + "Hash", + move_stdlib::natives::hash::make_all(gas_params.move_stdlib.hash) + ); + add_natives_from_module!( + "Hash", + starcoin_natives::hash::make_all(gas_params.starcoin_natives.hash) + ); + add_natives_from_module!( + "BCS", + move_stdlib::natives::bcs::make_all(gas_params.move_stdlib.bcs) + ); + add_natives_from_module!( + "Signature", + starcoin_natives::signature::make_all(gas_params.starcoin_natives.signature) + ); + add_natives_from_module!( + "Vector", + move_stdlib::natives::vector::make_all(gas_params.move_stdlib.vector) + ); + add_natives_from_module!( + "Event", + move_stdlib::natives::event::make_all(gas_params.nursery.clone().event) + ); + add_natives_from_module!( + "Account", + starcoin_natives::account::make_all(gas_params.starcoin_natives.account) + ); + add_natives_from_module!( + "Signer", + move_stdlib::natives::signer::make_all(gas_params.move_stdlib.signer) + ); + add_natives_from_module!( + "Token", + starcoin_natives::token::make_all(gas_params.starcoin_natives.token) + ); + add_natives_from_module!( + "U256", + starcoin_natives::u256::make_all(gas_params.starcoin_natives.u256) + ); + #[cfg(feature = "testing")] + add_natives_from_module!( + "UnitTest", + move_stdlib::natives::unit_test::make_all(gas_params.move_stdlib.unit_test) + ); + add_natives_from_module!( + "String", + move_stdlib::natives::string::make_all(gas_params.move_stdlib.string) + ); + add_natives_from_module!( + "Debug", + move_stdlib::natives::debug::make_all(gas_params.nursery.debug, CORE_CODE_ADDRESS) + ); + let natives = make_table_from_iter(CORE_CODE_ADDRESS, natives); + natives + .into_iter() + .chain(table_natives(CORE_CODE_ADDRESS, gas_params.table)) + .collect() +} + +fn table_natives( + table_addr: AccountAddress, + gas_params: move_table_extension::GasParameters, +) -> NativeFunctionTable { + let natives: [(&str, &str, NativeFunction); 8] = [ + ( + "Table", + "new_table_handle", + move_table_extension::make_native_new_table_handle(gas_params.new_table_handle), + ), + ( + "Table", + "add_box", + move_table_extension::make_native_add_box( + gas_params.common.clone(), + gas_params.add_box, + ), + ), + ( + "Table", + "borrow_box", + move_table_extension::make_native_borrow_box( + gas_params.common.clone(), + gas_params.borrow_box.clone(), + ), + ), + ( + "Table", + "borrow_box_mut", + move_table_extension::make_native_borrow_box( + gas_params.common.clone(), + gas_params.borrow_box, + ), + ), + ( + "Table", + "remove_box", + move_table_extension::make_native_remove_box( + gas_params.common.clone(), + gas_params.remove_box, + ), + ), + ( + "Table", + "contains_box", + move_table_extension::make_native_contains_box( + gas_params.common, + gas_params.contains_box, + ), + ), + ( + "Table", + "destroy_empty_box", + move_table_extension::make_native_destroy_empty_box(gas_params.destroy_empty_box), + ), + ( + "Table", + "drop_unchecked_box", + move_table_extension::make_native_drop_unchecked_box(gas_params.drop_unchecked_box), + ), + ]; + + native_functions::make_table_from_iter(table_addr, natives) +} diff --git a/vm/vm-runtime/src/starcoin_vm.rs b/vm/vm-runtime/src/starcoin_vm.rs index e90a23b57b..c31c401dec 100644 --- a/vm/vm-runtime/src/starcoin_vm.rs +++ b/vm/vm-runtime/src/starcoin_vm.rs @@ -2,17 +2,22 @@ // SPDX-License-Identifier: Apache-2.0 use crate::access_path_cache::AccessPathCache; -use crate::data_cache::{RemoteStorage, StateViewCache}; +use crate::data_cache::{AsMoveResolver, RemoteStorage, StateViewCache}; use crate::errors::{ convert_normal_success_epilogue_error, convert_prologue_runtime_error, error_split, }; +use crate::move_vm_ext::{MoveResolverExt, MoveVmExt, SessionId, SessionOutput}; use anyhow::{format_err, Error, Result}; -use move_core_types::resolver::MoveResolver; -use move_vm_runtime::move_vm::MoveVM; +use move_core_types::gas_algebra::{InternalGasPerByte, NumBytes}; +use move_table_extension::NativeTableContext; use move_vm_runtime::move_vm_adapter::{PublishModuleBundleOption, SessionAdapter}; use move_vm_runtime::session::Session; -use once_cell::sync::Lazy; +use starcoin_config::genesis_config::G_LATEST_GAS_PARAMS; use starcoin_crypto::HashValue; +use starcoin_gas::{NativeGasParameters, StarcoinGasMeter, StarcoinGasParameters}; +use starcoin_gas_algebra_ext::{ + CostTable, FromOnChainGasSchedule, Gas, GasConstants, GasCost, InitialGasSchedule, +}; use starcoin_logger::prelude::*; use starcoin_types::account_config::config_change::ConfigChangeEvent; use starcoin_types::account_config::{ @@ -34,29 +39,23 @@ use starcoin_vm_types::account_config::{ core_code_address, genesis_address, ModuleUpgradeStrategy, TwoPhaseUpgradeV2Resource, G_EPILOGUE_NAME, G_EPILOGUE_V2_NAME, G_PROLOGUE_NAME, }; -use starcoin_vm_types::contract_event::ContractEvent; use starcoin_vm_types::file_format::{CompiledModule, CompiledScript}; -use starcoin_vm_types::gas_schedule::NativeCostIndex; use starcoin_vm_types::gas_schedule::G_LATEST_GAS_SCHEDULE; -use starcoin_vm_types::gas_schedule::{zero_cost_schedule, GasConstants, GasCost, GasStatus}; use starcoin_vm_types::genesis_config::StdlibVersion; use starcoin_vm_types::identifier::IdentStr; use starcoin_vm_types::language_storage::ModuleId; use starcoin_vm_types::on_chain_config::{ - MoveLanguageVersion, G_GAS_CONSTANTS_IDENTIFIER, G_INSTRUCTION_SCHEDULE_IDENTIFIER, - G_NATIVE_SCHEDULE_IDENTIFIER, G_VM_CONFIG_IDENTIFIER, + GasSchedule, MoveLanguageVersion, G_GAS_CONSTANTS_IDENTIFIER, + G_INSTRUCTION_SCHEDULE_IDENTIFIER, G_NATIVE_SCHEDULE_IDENTIFIER, G_VM_CONFIG_IDENTIFIER, }; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::state_view::StateReaderExt; use starcoin_vm_types::transaction::{DryRunTransaction, Package, TransactionPayloadType}; use starcoin_vm_types::transaction_metadata::TransactionPayloadMetadata; use starcoin_vm_types::value::{serialize_values, MoveValue}; use starcoin_vm_types::vm_status::KeptVMStatus; -use starcoin_vm_types::write_set::{WriteOp, WriteSetMut}; use starcoin_vm_types::{ - effects::{ChangeSet as MoveChangeSet, Event as MoveEvent}, errors::Location, - event::EventKey, - gas_schedule::{self, CostTable, GasAlgebra, GasCarrier, GasUnits, InternalGasUnits}, language_storage::TypeTag, on_chain_config::{OnChainConfig, VMConfig, Version}, state_view::StateView, @@ -64,23 +63,21 @@ use starcoin_vm_types::{ values::Value, vm_status::{StatusCode, VMStatus}, }; -use std::convert::{TryFrom, TryInto}; use std::sync::Arc; #[cfg(feature = "metrics")] use crate::metrics::VMMetrics; -static G_ZERO_COST_SCHEDULE: Lazy = - Lazy::new(|| zero_cost_schedule(NativeCostIndex::NUMBER_OF_NATIVE_FUNCTIONS)); - #[derive(Clone)] #[allow(clippy::upper_case_acronyms)] /// Wrapper of MoveVM pub struct StarcoinVM { - move_vm: Arc, + move_vm: Arc, vm_config: Option, version: Option, move_version: Option, + native_params: NativeGasParameters, + gas_params: Option, #[cfg(feature = "metrics")] metrics: Option, } @@ -91,25 +88,33 @@ const VMCONFIG_UPGRADE_VERSION_MARK: u64 = 10; impl StarcoinVM { #[cfg(feature = "metrics")] pub fn new(metrics: Option) -> Self { - let inner = MoveVM::new(super::natives::starcoin_natives()) + let gas_params = StarcoinGasParameters::initial(); + let native_params = gas_params.natives.clone(); + let inner = MoveVmExt::new(native_params.clone()) .expect("should be able to create Move VM; check if there are duplicated natives"); Self { move_vm: Arc::new(inner), vm_config: None, version: None, move_version: None, + native_params, + gas_params: Some(gas_params), metrics, } } #[cfg(not(feature = "metrics"))] pub fn new() -> Self { - let inner = MoveVM::new(super::natives::starcoin_natives()) + let gas_params = StarcoinGasParameters::initial(); + let native_params = gas_params.natives.clone(); + let inner = MoveVmExt::new(native_params.clone()) .expect("should be able to create Move VM; check if there are duplicated natives"); Self { move_vm: Arc::new(inner), vm_config: None, version: None, move_version: None, + native_params, + gas_params: Some(gas_params), } } @@ -119,10 +124,25 @@ impl StarcoinVM { gas_schedule: G_LATEST_GAS_SCHEDULE.clone(), }); self.version = Some(Version { major: 1 }); - Ok(()) } else { - self.load_configs_impl(state) + self.load_configs_impl(state)?; + } + if let Some(ref vm_config) = self.vm_config { + let gas_schedule = GasSchedule::from(vm_config); + let gas_params = + StarcoinGasParameters::from_on_chain_gas_schedule(&gas_schedule.to_btree_map()); + if let Some(ref params) = gas_params { + if params.natives != self.native_params { + debug!("update native_params"); + Arc::get_mut(&mut self.move_vm) + .unwrap() + .update_native_functions(params.clone().natives)?; + self.native_params = params.natives.clone(); + } + self.gas_params = gas_params; + } } + Ok(()) } fn load_configs_impl(&mut self, state: &S) -> Result<(), Error> { @@ -244,14 +264,13 @@ impl StarcoinVM { } fn check_gas(&self, txn_data: &TransactionMetadata) -> Result<(), VMStatus> { - let gas_constants = &self.get_gas_schedule()?.gas_constants; + let txn_gas_params = &self.get_gas_parameters()?.txn; let raw_bytes_len = txn_data.transaction_size; // The transaction is too large. - if raw_bytes_len.get() > gas_constants.max_transaction_size_in_bytes { + if raw_bytes_len > txn_gas_params.max_transaction_size_in_bytes { warn!( "[VM] Transaction size too big {} (max {})", - raw_bytes_len.get(), - gas_constants.max_transaction_size_in_bytes + raw_bytes_len, txn_gas_params.max_transaction_size_in_bytes ); return Err(VMStatus::Error(StatusCode::EXCEEDED_MAX_TRANSACTION_SIZE)); } @@ -259,12 +278,12 @@ impl StarcoinVM { // The submitted max gas units that the transaction can consume is greater than the // maximum number of gas units bound that we have set for any // transaction. - if txn_data.max_gas_amount().get() > gas_constants.maximum_number_of_gas_units.get() { + if txn_data.max_gas_amount() > txn_gas_params.maximum_number_of_gas_units { warn!( "[VM] Gas unit error; max {}, submitted {}, with scaling_factor {}", - gas_constants.maximum_number_of_gas_units.get(), - txn_data.max_gas_amount().get(), - gas_constants.gas_unit_scaling_factor + txn_gas_params.maximum_number_of_gas_units, + txn_data.max_gas_amount(), + txn_gas_params.gas_unit_scaling_factor ); return Err(VMStatus::Error( StatusCode::MAX_GAS_UNITS_EXCEEDS_MAX_GAS_UNITS_BOUND, @@ -274,17 +293,15 @@ impl StarcoinVM { // The submitted transactions max gas units needs to be at least enough to cover the // intrinsic cost of the transaction as calculated against the size of the // underlying `RawTransaction` - let min_txn_fee = gas_schedule::calculate_intrinsic_gas(raw_bytes_len, gas_constants); - if gas_constants - .to_internal_units(txn_data.max_gas_amount()) - .get() - < min_txn_fee.get() - { + let intrinsic_gas = txn_gas_params + .calculate_intrinsic_gas(raw_bytes_len) + .to_unit_round_up_with_params(txn_gas_params); + if txn_data.max_gas_amount() < intrinsic_gas { warn!( "[VM] Gas unit error; min {}, submitted {}, with scaling_factor {}", - min_txn_fee.get(), - txn_data.max_gas_amount().get(), - gas_constants.gas_unit_scaling_factor + intrinsic_gas, + txn_data.max_gas_amount(), + txn_gas_params.gas_unit_scaling_factor ); return Err(VMStatus::Error( StatusCode::MAX_GAS_UNITS_BELOW_MIN_TRANSACTION_GAS_UNITS, @@ -295,23 +312,22 @@ impl StarcoinVM { // NB: MIN_PRICE_PER_GAS_UNIT may equal zero, but need not in the future. Hence why // we turn off the clippy warning. #[allow(clippy::absurd_extreme_comparisons)] - let below_min_bound = - txn_data.gas_unit_price().get() < gas_constants.min_price_per_gas_unit.get(); + let below_min_bound = txn_data.gas_unit_price() < txn_gas_params.min_price_per_gas_unit; if below_min_bound { warn!( "[VM] Gas unit error; min {}, submitted {}", - gas_constants.min_price_per_gas_unit.get(), - txn_data.gas_unit_price().get() + txn_gas_params.min_price_per_gas_unit, + txn_data.gas_unit_price() ); return Err(VMStatus::Error(StatusCode::GAS_UNIT_PRICE_BELOW_MIN_BOUND)); } // The submitted gas price is greater than the maximum gas unit price set by the VM. - if txn_data.gas_unit_price().get() > gas_constants.max_price_per_gas_unit.get() { + if txn_data.gas_unit_price() > txn_gas_params.max_price_per_gas_unit { warn!( "[VM] Gas unit error; min {}, submitted {}", - gas_constants.max_price_per_gas_unit.get(), - txn_data.gas_unit_price().get() + txn_gas_params.max_price_per_gas_unit, + txn_data.gas_unit_price() ); return Err(VMStatus::Error(StatusCode::GAS_UNIT_PRICE_ABOVE_MAX_BOUND)); } @@ -324,13 +340,14 @@ impl StarcoinVM { remote_cache: &StateViewCache, ) -> Result<(), VMStatus> { let txn_data = TransactionMetadata::new(transaction)?; - let mut session: SessionAdapter<_> = self.move_vm.new_session(remote_cache).into(); - let mut gas_status = { - let mut gas_status = GasStatus::new(self.get_gas_schedule()?, GasUnits::new(0)); - gas_status.set_metering(false); - gas_status - }; - + let data_cache = remote_cache.as_move_resolver(); + let mut session: SessionAdapter<_> = self + .move_vm + .new_session(&data_cache, SessionId::txn(transaction)) + .into(); + let gas_params = self.get_gas_parameters()?; + let mut gas_meter = StarcoinGasMeter::new(gas_params.clone(), txn_data.max_gas_amount()); + gas_meter.set_metering(false); self.check_gas(&txn_data)?; match transaction.payload() { TransactionPayload::Package(package) => { @@ -362,7 +379,7 @@ impl StarcoinVM { .map(|m| m.code().to_vec()) .collect(), package.package_address(), - &mut gas_status, + &mut gas_meter, PublishModuleBundleOption { force_publish: enforced, only_new_module, @@ -379,7 +396,7 @@ impl StarcoinVM { s.code().to_vec(), s.ty_args().to_vec(), s.args().to_vec(), - vec![txn_data.sender()], + txn_data.sender(), ) .map_err(|e| e.into_vm_status())?; } @@ -390,12 +407,12 @@ impl StarcoinVM { s.function(), s.ty_args().to_vec(), s.args().to_vec(), - vec![txn_data.sender()], + txn_data.sender(), ) .map_err(|e| e.into_vm_status())?; } } - self.run_prologue(&mut session, &mut gas_status, &txn_data) + self.run_prologue(&mut session, &mut gas_meter, &txn_data) } pub fn verify_transaction( @@ -436,7 +453,9 @@ impl StarcoinVM { package_address: AccountAddress, ) -> Result { let strategy_access_path = access_path_for_module_upgrade_strategy(package_address); - if let Some(data) = remote_cache.get(&strategy_access_path)? { + if let Some(data) = + remote_cache.get_state_value(&StateKey::AccessPath(strategy_access_path))? + { Ok(bcs_ext::from_bytes::(&data)?.only_new_module()) } else { Ok(false) @@ -455,7 +474,9 @@ impl StarcoinVM { || (chain_id.is_barnard() && block_meta.number < 8311392) { let two_phase_upgrade_v2_path = access_path_for_two_phase_upgrade_v2(package_address); - if let Some(data) = remote_cache.get(&two_phase_upgrade_v2_path)? { + if let Some(data) = + remote_cache.get_state_value(&StateKey::AccessPath(two_phase_upgrade_v2_path))? + { let enforced = bcs_ext::from_bytes::(&data)?.enforced(); Ok(enforced) } else { @@ -469,32 +490,34 @@ impl StarcoinVM { fn execute_package( &self, remote_cache: &StateViewCache<'_, S>, - gas_schedule: &CostTable, - cost_strategy: &mut GasStatus, + gas_meter: &mut StarcoinGasMeter, txn_data: &TransactionMetadata, package: &Package, ) -> Result<(VMStatus, TransactionOutput), VMStatus> { - let mut session: SessionAdapter<_> = self.move_vm.new_session(remote_cache).into(); + let data_cache = remote_cache.as_move_resolver(); + let mut session: SessionAdapter<_> = self + .move_vm + .new_session(&data_cache, SessionId::txn_meta(txn_data)) + .into(); { // Run the validation logic - cost_strategy.set_metering(false); + gas_meter.set_metering(false); // genesis txn skip check gas and txn prologue. if !remote_cache.is_genesis() { //let _timer = TXN_VERIFICATION_SECONDS.start_timer(); self.check_gas(txn_data)?; - self.run_prologue(&mut session, cost_strategy, txn_data)?; + self.run_prologue(&mut session, gas_meter, txn_data)?; } } { // Genesis txn not enable gas charge. if !remote_cache.is_genesis() { - cost_strategy.set_metering(true); + gas_meter.set_metering(true); } - cost_strategy - .charge_intrinsic_gas(txn_data.transaction_size()) + gas_meter + .charge_intrinsic_gas_for_transaction(txn_data.transaction_size()) .map_err(|e| e.into_vm_status())?; - let package_address = package.package_address(); for module in package.modules() { if let Ok(compiled_module) = CompiledModule::deserialize(module.code()) { @@ -514,7 +537,6 @@ impl StarcoinVM { } Ok(only_new_module) => only_new_module, }; - session .publish_module_bundle_with_option( package @@ -523,7 +545,7 @@ impl StarcoinVM { .map(|m| m.code().to_vec()) .collect(), package.package_address(), // be careful with the sender. - cost_strategy, + gas_meter, PublishModuleBundleOption { force_publish: enforced, only_new_module, @@ -536,7 +558,7 @@ impl StarcoinVM { // after publish the modules, we need to clear loader cache, to make init script function and // epilogue use the new modules. - session.empty_loader_cache()?; + // clear logic move in publish_module_bundle_with_option if let Some(init_script) = package.init_script() { let genesis_address = genesis_address(); @@ -544,7 +566,7 @@ impl StarcoinVM { // instead of the txn sender address. It provides the opportunity to add new resource // under the genesis address through DAO. let sender = if package_address == genesis_address { - cost_strategy.set_metering(false); + gas_meter.set_metering(false); genesis_address } else { txn_data.sender @@ -556,53 +578,49 @@ impl StarcoinVM { sender ); session - .as_mut() - .execute_script_function( + .execute_entry_function( init_script.module(), init_script.function(), init_script.ty_args().to_vec(), init_script.args().to_vec(), - vec![sender], - cost_strategy, + gas_meter, + sender, ) .map_err(|e| e.into_vm_status())?; } - charge_global_write_gas_usage(cost_strategy, &session, &txn_data.sender())?; + charge_global_write_gas_usage(gas_meter, &session, &txn_data.sender())?; - cost_strategy.set_metering(false); - self.success_transaction_cleanup( - session, - gas_schedule, - cost_strategy.remaining_gas(), - txn_data, - ) + gas_meter.set_metering(false); + self.success_transaction_cleanup(session, gas_meter, txn_data) } } fn execute_script_or_script_function( &self, remote_cache: &StateViewCache<'_, S>, - gas_schedule: &CostTable, - cost_strategy: &mut GasStatus, + gas_meter: &mut StarcoinGasMeter, txn_data: &TransactionMetadata, payload: &TransactionPayload, ) -> Result<(VMStatus, TransactionOutput), VMStatus> { - let mut session: SessionAdapter<_> = self.move_vm.new_session(remote_cache).into(); + let data_cache = remote_cache.as_move_resolver(); + let mut session: SessionAdapter<_> = self + .move_vm + .new_session(&data_cache, SessionId::txn_meta(txn_data)) + .into(); // Run the validation logic { - cost_strategy.set_metering(false); - //let _timer = TXN_VERIFICATION_SECONDS.start_timer(); + gas_meter.set_metering(false); self.check_gas(txn_data)?; - self.run_prologue(&mut session, cost_strategy, txn_data)?; + self.run_prologue(&mut session, gas_meter, txn_data)?; } // Run the execution logic { //let _timer = TXN_EXECUTION_SECONDS.start_timer(); - cost_strategy.set_metering(true); - cost_strategy - .charge_intrinsic_gas(txn_data.transaction_size()) + gas_meter.set_metering(true); + gas_meter + .charge_intrinsic_gas_for_transaction(txn_data.transaction_size()) .map_err(|e| e.into_vm_status())?; match payload { TransactionPayload::Script(script) => { @@ -610,23 +628,24 @@ impl StarcoinVM { if let Ok(s) = CompiledScript::deserialize(script.code()) { self.check_move_version(s.version() as u64)?; }; - - session.as_mut().execute_script( + debug!("TransactionPayload::{:?}", script); + session.execute_script( script.code().to_vec(), script.ty_args().to_vec(), script.args().to_vec(), - vec![txn_data.sender()], - cost_strategy, + gas_meter, + txn_data.sender(), ) } TransactionPayload::ScriptFunction(script_function) => { - session.as_mut().execute_script_function( + debug!("TransactionPayload::{:?}", script_function); + session.execute_entry_function( script_function.module(), script_function.function(), script_function.ty_args().to_vec(), script_function.args().to_vec(), - vec![txn_data.sender()], - cost_strategy, + gas_meter, + txn_data.sender(), ) } TransactionPayload::Package(_) => { @@ -638,38 +657,29 @@ impl StarcoinVM { warn!("[VM] execute_script_function error, status_type: {:?}, status_code:{:?}, message:{:?}, location:{:?}", e.status_type(), e.major_status(), e.message(), e.location()); e.into_vm_status() })?; + charge_global_write_gas_usage(gas_meter, &session, &txn_data.sender())?; - charge_global_write_gas_usage(cost_strategy, &session, &txn_data.sender())?; - - cost_strategy.set_metering(false); - self.success_transaction_cleanup( - session, - gas_schedule, - cost_strategy.remaining_gas(), - txn_data, - ) + self.success_transaction_cleanup(session, gas_meter, txn_data) } } /// Run the prologue of a transaction by calling into `PROLOGUE_NAME` function stored /// in the `ACCOUNT_MODULE` on chain. - fn run_prologue( + fn run_prologue( &self, session: &mut SessionAdapter, - gas_status: &mut GasStatus, + gas_meter: &mut StarcoinGasMeter, txn_data: &TransactionMetadata, ) -> Result<(), VMStatus> { let genesis_address = genesis_address(); - let gas_token_ty = TypeTag::Struct( - txn_data - .gas_token_code() - .try_into() - .map_err(|_e| VMStatus::Error(StatusCode::BAD_TRANSACTION_FEE_CURRENCY))?, - ); + let gas_token_ty = + TypeTag::Struct(Box::new(txn_data.gas_token_code().try_into().map_err( + |_e| VMStatus::Error(StatusCode::BAD_TRANSACTION_FEE_CURRENCY), + )?)); let txn_sequence_number = txn_data.sequence_number(); let authentication_key_preimage = txn_data.authentication_key_preimage().to_vec(); - let txn_gas_price = txn_data.gas_unit_price().get(); - let txn_max_gas_amount = txn_data.max_gas_amount().get(); + let txn_gas_price = u64::from(txn_data.gas_unit_price()); + let txn_max_gas_amount = u64::from(txn_data.max_gas_amount()); let txn_expiration_time = txn_data.expiration_time_secs(); let chain_id = txn_data.chain_id().id(); let (payload_type, script_or_package_hash, package_address) = match txn_data.payload() { @@ -689,7 +699,7 @@ impl StarcoinVM { // Run prologue by genesis account session .as_mut() - .execute_function( + .execute_function_bypass_visibility( &account_config::G_TRANSACTION_MANAGER_MODULE, &G_PROLOGUE_NAME, vec![gas_token_ty], @@ -706,7 +716,7 @@ impl StarcoinVM { MoveValue::vector_u8(script_or_package_hash.to_vec()), MoveValue::Address(package_address), ]), - gas_status, + gas_meter, ) .map(|_return_vals| ()) .or_else(convert_prologue_runtime_error) @@ -714,25 +724,23 @@ impl StarcoinVM { /// Run the epilogue of a transaction by calling into `EPILOGUE_NAME` function stored /// in the `ACCOUNT_MODULE` on chain. - fn run_epilogue( + fn run_epilogue( &self, session: &mut SessionAdapter, - gas_status: &mut GasStatus, + gas_meter: &mut StarcoinGasMeter, txn_data: &TransactionMetadata, success: bool, ) -> Result<(), VMStatus> { let genesis_address = genesis_address(); - let gas_token_ty = TypeTag::Struct( - txn_data - .gas_token_code() - .try_into() - .map_err(|_e| VMStatus::Error(StatusCode::BAD_TRANSACTION_FEE_CURRENCY))?, - ); + let gas_token_ty = + TypeTag::Struct(Box::new(txn_data.gas_token_code().try_into().map_err( + |_e| VMStatus::Error(StatusCode::BAD_TRANSACTION_FEE_CURRENCY), + )?)); let txn_sequence_number = txn_data.sequence_number(); let txn_authentication_key_preimage = txn_data.authentication_key_preimage().to_vec(); - let txn_gas_price = txn_data.gas_unit_price().get(); - let txn_max_gas_amount = txn_data.max_gas_amount().get(); - let gas_remaining = gas_status.remaining_gas().get(); + let txn_gas_price = u64::from(txn_data.gas_unit_price()); + let txn_max_gas_amount = u64::from(txn_data.max_gas_amount()); + let gas_remaining = u64::from(gas_meter.balance()); let (payload_type, script_or_package_hash, package_address) = match txn_data.payload() { TransactionPayloadMetadata::Script(hash) => { (TransactionPayloadType::Script, *hash, AccountAddress::ZERO) @@ -785,12 +793,12 @@ impl StarcoinVM { }; session .as_mut() - .execute_function( + .execute_function_bypass_visibility( &account_config::G_TRANSACTION_MANAGER_MODULE, function_name, vec![gas_token_ty], args, - gas_status, + gas_meter, ) .map(|_return_vals| ()) .or_else(convert_normal_success_epilogue_error) @@ -801,16 +809,16 @@ impl StarcoinVM { remote_cache: &mut StateViewCache<'_, S>, block_metadata: BlockMetadata, ) -> Result { + #[cfg(testing)] + info!("process_block_meta begin"); let txn_sender = account_config::genesis_address(); // always use 0 gas for system. - let max_gas_amount = GasUnits::new(0); - let cost_table = &G_ZERO_COST_SCHEDULE; - let mut gas_status = { - let mut gas_status = GasStatus::new(cost_table, max_gas_amount); - gas_status.set_metering(false); - gas_status - }; - + let max_gas_amount: Gas = 0.into(); + // let mut gas_meter = UnmeteredGasMeter; + // for debug + let mut gas_meter = StarcoinGasMeter::new(StarcoinGasParameters::zeros(), max_gas_amount); + gas_meter.set_metering(false); + let session_id = SessionId::block_meta(&block_metadata); let ( parent_id, timestamp, @@ -835,22 +843,26 @@ impl StarcoinVM { MoveValue::U8(chain_id.id()), MoveValue::U64(parent_gas_used), ]); - let mut session: SessionAdapter<_> = self.move_vm.new_session(remote_cache).into(); + let data_cache = remote_cache.as_move_resolver(); + let mut session: SessionAdapter<_> = + self.move_vm.new_session(&data_cache, session_id).into(); session .as_mut() - .execute_function( + .execute_function_bypass_visibility( &account_config::G_TRANSACTION_MANAGER_MODULE, &account_config::G_BLOCK_PROLOGUE_NAME, vec![], args, - &mut gas_status, + &mut gas_meter, ) .map(|_return_vals| ()) .or_else(convert_prologue_runtime_error)?; + #[cfg(testing)] + info!("process_block_meta end"); get_transaction_output( &mut (), session, - &gas_status, + 0.into(), max_gas_amount, KeptVMStatus::Executed, ) @@ -861,16 +873,6 @@ impl StarcoinVM { txn: SignedUserTransaction, remote_cache: &mut StateViewCache<'_, S>, ) -> (VMStatus, TransactionOutput) { - let gas_schedule = match self.get_gas_schedule() { - Ok(gas_schedule) => gas_schedule, - Err(e) => { - if remote_cache.is_genesis() { - &G_LATEST_GAS_SCHEDULE - } else { - return discard_error_vm_status(e); - } - } - }; let txn_id = txn.id(); let txn_data = match TransactionMetadata::new(&txn) { Ok(txn_data) => txn_data, @@ -878,12 +880,19 @@ impl StarcoinVM { return discard_error_vm_status(e); } }; - - let mut gas_status = { - let mut gas_status = GasStatus::new(gas_schedule, txn_data.max_gas_amount()); - gas_status.set_metering(false); - gas_status + let gas_params = match self.get_gas_parameters() { + Ok(gas_params) => gas_params, + Err(e) => { + if remote_cache.is_genesis() { + &G_LATEST_GAS_PARAMS + } else { + return discard_error_vm_status(e); + } + } }; + + let mut gas_meter = StarcoinGasMeter::new(gas_params.clone(), txn_data.max_gas_amount()); + gas_meter.set_metering(false); // check signature let signature_checked_txn = match txn.check_signature() { Ok(t) => Ok(t), @@ -897,18 +906,13 @@ impl StarcoinVM { | payload @ TransactionPayload::ScriptFunction(_) => self .execute_script_or_script_function( remote_cache, - gas_schedule, - &mut gas_status, + &mut gas_meter, &txn_data, payload, ), - TransactionPayload::Package(p) => self.execute_package( - remote_cache, - gas_schedule, - &mut gas_status, - &txn_data, - p, - ), + TransactionPayload::Package(p) => { + self.execute_package(remote_cache, &mut gas_meter, &txn_data, p) + } }; match result { Ok(status_and_output) => { @@ -928,8 +932,7 @@ impl StarcoinVM { } else { self.failed_transaction_cleanup( err, - gas_schedule, - gas_status.remaining_gas(), + &mut gas_meter, &txn_data, remote_cache, ) @@ -950,12 +953,11 @@ impl StarcoinVM { let remote_cache = StateViewCache::new(state_view); //TODO load config by config change event. self.load_configs(&remote_cache)?; - - let gas_schedule = match self.get_gas_schedule() { - Ok(gas_schedule) => gas_schedule, + let gas_params = match self.get_gas_parameters() { + Ok(gas_params) => gas_params, Err(e) => { if remote_cache.is_genesis() { - &G_LATEST_GAS_SCHEDULE + &G_LATEST_GAS_PARAMS } else { return Ok(discard_error_vm_status(e)); } @@ -968,23 +970,19 @@ impl StarcoinVM { Ok(txn_data) => txn_data, Err(e) => return Ok(discard_error_vm_status(e)), }; - let mut gas_status = { - let mut gas_status = GasStatus::new(gas_schedule, txn_data.max_gas_amount()); - gas_status.set_metering(false); - gas_status - }; + let mut gas_meter = StarcoinGasMeter::new(gas_params.clone(), txn_data.max_gas_amount()); + gas_meter.set_metering(false); let result = match txn.raw_txn.payload() { payload @ TransactionPayload::Script(_) | payload @ TransactionPayload::ScriptFunction(_) => self .execute_script_or_script_function( &remote_cache, - gas_schedule, - &mut gas_status, + &mut gas_meter, &txn_data, payload, ), TransactionPayload::Package(p) => { - self.execute_package(&remote_cache, gas_schedule, &mut gas_status, &txn_data, p) + self.execute_package(&remote_cache, &mut gas_meter, &txn_data, p) } }; Ok(match result { @@ -994,13 +992,7 @@ impl StarcoinVM { if txn_status.is_discarded() { discard_error_vm_status(err) } else { - self.failed_transaction_cleanup( - err, - gas_schedule, - gas_status.remaining_gas(), - &txn_data, - &remote_cache, - ) + self.failed_transaction_cleanup(err, &mut gas_meter, &txn_data, &remote_cache) } } }) @@ -1022,6 +1014,8 @@ impl StarcoinVM { Ok(()) } + /// XXX FIXME YSG add delta_change_set for TransactionOutput + /// Execute a block transactions with gas_limit, /// if gas is used up when executing some txn, only return the outputs of previous succeed txns. pub fn execute_block_transactions( @@ -1170,9 +1164,9 @@ impl StarcoinVM { .with_label_values(&["execute_readonly_function"]) .start_timer() }); - let data_cache = StateViewCache::new(state_view); + let data_cache = state_view.as_move_resolver(); - let mut gas_status = if check_gas { + let mut gas_meter = if check_gas { if let Err(err) = self.load_configs(state_view) { warn!( "Load config error at execute_readonly_function_internal: {}", @@ -1180,52 +1174,70 @@ impl StarcoinVM { ); return Err(VMStatus::Error(StatusCode::VM_STARTUP_FAILURE)); } - let gas_constants = &self.get_gas_schedule()?.gas_constants; - let mut gas_status = GasStatus::new( - &G_LATEST_GAS_SCHEDULE, - GasUnits::new(gas_constants.maximum_number_of_gas_units.get()), + let gas_params = self.get_gas_parameters()?; + let mut gas_meter = StarcoinGasMeter::new( + G_LATEST_GAS_PARAMS.clone(), + gas_params.txn.maximum_number_of_gas_units, ); - gas_status.set_metering(true); - gas_status + gas_meter.set_metering(true); + gas_meter } else { - let mut gas_status = GasStatus::new(&G_ZERO_COST_SCHEDULE, GasUnits::new(0)); - gas_status.set_metering(false); - gas_status + let max_gas_amount: Gas = 0.into(); + let mut gas_meter = + StarcoinGasMeter::new(StarcoinGasParameters::zeros(), max_gas_amount); + gas_meter.set_metering(false); + gas_meter }; - let mut session = self.move_vm.new_session(&data_cache); + let mut session = self.move_vm.new_session(&data_cache, SessionId::void()); let result = session - .execute_function(module, function_name, type_params, args, &mut gas_status) + .execute_function_bypass_visibility( + module, + function_name, + type_params, + args, + &mut gas_meter, + ) + .map_err(|e| e.into_vm_status())? + .return_values + .into_iter() + .map(|(a, _)| a) + .collect(); + + let (change_set, events, mut extensions) = session + .finish_with_extensions() .map_err(|e| e.into_vm_status())?; - - let (changeset, events) = session.finish().map_err(|e| e.into_vm_status())?; - let (writeset, _events) = convert_changeset_and_events(changeset, events)?; - if !writeset.is_empty() { + let table_context: NativeTableContext = extensions.remove(); + let table_change_set = table_context + .into_change_set() + .map_err(|e| e.finish(Location::Undefined))?; + let (write_set, _events) = SessionOutput { + change_set, + events, + table_change_set, + } + .into_change_set(&mut ())?; + if !write_set.is_empty() { warn!("Readonly function {} changes state", function_name); return Err(VMStatus::Error(StatusCode::REJECTED_WRITE_SET)); } Ok(result) } - fn success_transaction_cleanup( + fn success_transaction_cleanup( &self, mut session: SessionAdapter, - gas_schedule: &CostTable, - gas_left: GasUnits, + gas_meter: &mut StarcoinGasMeter, txn_data: &TransactionMetadata, ) -> Result<(VMStatus, TransactionOutput), VMStatus> { - let mut gas_status = { - let mut gas_status = GasStatus::new(gas_schedule, gas_left); - gas_status.set_metering(false); - gas_status - }; - self.run_epilogue(&mut session, &mut gas_status, txn_data, true)?; + gas_meter.set_metering(false); + self.run_epilogue(&mut session, gas_meter, txn_data, true)?; Ok(( VMStatus::Executed, get_transaction_output( &mut (), session, - &gas_status, + gas_meter.balance(), txn_data.max_gas_amount, KeptVMStatus::Executed, )?, @@ -1235,17 +1247,17 @@ impl StarcoinVM { fn failed_transaction_cleanup( &self, error_code: VMStatus, - gas_schedule: &CostTable, - gas_left: GasUnits, + gas_meter: &mut StarcoinGasMeter, txn_data: &TransactionMetadata, remote_cache: &StateViewCache<'_, S>, ) -> (VMStatus, TransactionOutput) { - let mut gas_status = { - let mut gas_status = GasStatus::new(gas_schedule, gas_left); - gas_status.set_metering(false); - gas_status - }; - let mut session: SessionAdapter<_> = self.move_vm.new_session(remote_cache).into(); + // XXX FIXME YSG, confirm whether is right + gas_meter.set_metering(false); + let data_cache = remote_cache.as_move_resolver(); + let mut session: SessionAdapter<_> = self + .move_vm + .new_session(&data_cache, SessionId::txn_meta(txn_data)) + .into(); // init_script doesn't need run epilogue if remote_cache.is_genesis() { @@ -1254,13 +1266,13 @@ impl StarcoinVM { match TransactionStatus::from(error_code.clone()) { TransactionStatus::Keep(status) => { - if let Err(e) = self.run_epilogue(&mut session, &mut gas_status, txn_data, false) { + if let Err(e) = self.run_epilogue(&mut session, gas_meter, txn_data, false) { return discard_error_vm_status(e); } let txn_output = get_transaction_output( &mut (), session, - &gas_status, + gas_meter.balance(), txn_data.max_gas_amount, status, ) @@ -1272,6 +1284,13 @@ impl StarcoinVM { } } } + + pub fn get_gas_parameters(&self) -> Result<&StarcoinGasParameters, VMStatus> { + self.gas_params.as_ref().ok_or_else(|| { + debug!("VM Startup Failed. Gas Parameters Not Found"); + VMStatus::Error(StatusCode::VM_STARTUP_FAILURE) + }) + } } #[allow(clippy::large_enum_variant)] @@ -1312,25 +1331,22 @@ pub fn chunk_block_transactions(txns: Vec) -> Vec blocks } -pub(crate) fn charge_global_write_gas_usage( - cost_strategy: &mut GasStatus, +pub(crate) fn charge_global_write_gas_usage( + gas_meter: &mut StarcoinGasMeter, session: &SessionAdapter, sender: &AccountAddress, ) -> Result<(), VMStatus> { - let total_cost = session.as_ref().num_mutated_accounts(sender) - * cost_strategy - .cost_table() - .gas_constants - .global_memory_per_byte_write_cost - .mul( - cost_strategy - .cost_table() - .gas_constants - .default_account_size, - ) - .get(); - cost_strategy - .deduct_gas(InternalGasUnits::new(total_cost)) + let write_set_gas = u64::from(gas_meter.cal_write_set_gas()); + let total_cost = InternalGasPerByte::from(write_set_gas) + * NumBytes::new(session.as_ref().num_mutated_accounts(sender)); + #[cfg(testing)] + info!( + "charge_global_write_gas_usage {} {}", + total_cost, + gas_meter.get_metering() + ); + gas_meter + .deduct_gas(total_cost) .map_err(|p_err| p_err.finish(Location::Undefined).into_vm_status()) } @@ -1358,76 +1374,33 @@ pub(crate) fn discard_error_output(err: StatusCode) -> TransactionOutput { ) } -pub fn convert_changeset_and_events_cached( - ap_cache: &mut C, - changeset: MoveChangeSet, - events: Vec, -) -> Result<(WriteSet, Vec), VMStatus> { - // TODO: Cache access path computations if necessary. - let mut ops = vec![]; - - for (addr, account_changeset) in changeset.into_inner() { - let (modules, resources) = account_changeset.into_inner(); - for (struct_tag, blob_opt) in resources { - let ap = ap_cache.get_resource_path(addr, struct_tag); - let op = match blob_opt { - None => WriteOp::Deletion, - Some(blob) => WriteOp::Value(blob), - }; - ops.push((ap, op)) - } - - for (name, blob_opt) in modules { - let ap = ap_cache.get_module_path(ModuleId::new(addr, name)); - let op = match blob_opt { - None => WriteOp::Deletion, - Some(blob) => WriteOp::Value(blob), - }; - - ops.push((ap, op)) - } - } - - let ws = WriteSetMut::new(ops) - .freeze() - .map_err(|_| VMStatus::Error(StatusCode::DATA_FORMAT_ERROR))?; - - let events = events - .into_iter() - .map(|(guid, seq_num, ty_tag, blob)| { - let key = EventKey::try_from(guid.as_slice()) - .map_err(|_| VMStatus::Error(StatusCode::EVENT_KEY_MISMATCH))?; - Ok(ContractEvent::new(key, seq_num, ty_tag, blob)) - }) - .collect::, VMStatus>>()?; - - Ok((ws, events)) -} - -pub fn convert_changeset_and_events( - changeset: MoveChangeSet, - events: Vec, -) -> Result<(WriteSet, Vec), VMStatus> { - convert_changeset_and_events_cached(&mut (), changeset, events) -} - -pub(crate) fn get_transaction_output( +pub(crate) fn get_transaction_output( ap_cache: &mut A, session: SessionAdapter, - cost_strategy: &GasStatus, - max_gas_amount: GasUnits, + gas_left: Gas, + max_gas_amount: Gas, status: KeptVMStatus, ) -> Result { - let gas_used: u64 = max_gas_amount.sub(cost_strategy.remaining_gas()).get(); - - let (changeset, events) = Into::>::into(session) - .finish() - .map_err(|e| e.into_vm_status())?; - let (write_set, events) = convert_changeset_and_events_cached(ap_cache, changeset, events)?; + // original code use sub, now we use checked_sub + let gas_used = max_gas_amount + .checked_sub(gas_left) + .expect("Balance should always be less than or equal to max gas amount"); + let (change_set, events, mut extensions) = + Into::>::into(session).finish_with_extensions()?; + let table_context: NativeTableContext = extensions.remove(); + let table_change_set = table_context + .into_change_set() + .map_err(|e| e.finish(Location::Undefined))?; + let (write_set, events) = SessionOutput { + change_set, + events, + table_change_set, + } + .into_change_set(ap_cache)?; Ok(TransactionOutput::new( write_set, events, - gas_used, + u64::from(gas_used), TransactionStatus::Keep(status), )) } diff --git a/vm/vm-runtime/tests/test_native_functions.rs b/vm/vm-runtime/tests/test_native_functions.rs index e387e3460c..6795a2e556 100644 --- a/vm/vm-runtime/tests/test_native_functions.rs +++ b/vm/vm-runtime/tests/test_native_functions.rs @@ -1,4 +1,5 @@ use anyhow::Result; +use starcoin_config::genesis_config::G_LATEST_GAS_PARAMS; use starcoin_vm_types::access::ModuleAccess; use starcoin_vm_types::normalized::Function; use std::collections::HashSet; @@ -30,10 +31,11 @@ pub fn test_native_function_matches() -> Result<()> { }) .collect(); - let mut native_function_table = starcoin_vm_runtime::natives::starcoin_natives() - .iter() - .map(|(addr, m_name, f_name, _)| (*addr, m_name.to_string(), f_name.to_string())) - .collect::>(); + let mut native_function_table = + starcoin_vm_runtime::natives::starcoin_natives(G_LATEST_GAS_PARAMS.clone().natives) + .iter() + .map(|(addr, m_name, f_name, _)| (*addr, m_name.to_string(), f_name.to_string())) + .collect::>(); for f in native_functions { assert!( diff --git a/vm/vm-status-translator/src/lib.rs b/vm/vm-status-translator/src/lib.rs index fd291fbaa3..13cc897b46 100644 --- a/vm/vm-status-translator/src/lib.rs +++ b/vm/vm-status-translator/src/lib.rs @@ -7,6 +7,7 @@ use starcoin_vm_types::access_path::AccessPath; use starcoin_vm_types::file_format::{CompiledModule, FunctionDefinitionIndex}; use starcoin_vm_types::identifier::Identifier; use starcoin_vm_types::language_storage::ModuleId; +use starcoin_vm_types::state_store::state_key::StateKey; use starcoin_vm_types::state_view::StateView; use starcoin_vm_types::vm_status::{AbortLocation, StatusCode, VMStatus}; use std::convert::TryFrom; @@ -22,7 +23,7 @@ pub fn locate_execution_failure( let ap = AccessPath::code_access_path(*module_id.address(), module_id.name().to_owned()); - match state.get(&ap)? { + match state.get_state_value(&StateKey::AccessPath(ap))? { Some(bytes) => CompiledModule::deserialize(&bytes).ok(), None => None, } @@ -53,18 +54,18 @@ pub fn explain_move_abort(abort_location: AbortLocation, abort_code: u64) -> Mov let category = abort_code & 0xFFu64; let reason_code = abort_code >> 8; - let err_context = match abort_location { + let err_description = match abort_location { AbortLocation::Module(module_id) => { starcoin_move_explain::get_explanation(&module_id, abort_code) } AbortLocation::Script => None, }; - match err_context { - Some(ctx) => MoveAbortExplain { + match err_description { + Some(description) => MoveAbortExplain { category_code: category, - category_name: Some(ctx.category.code_name), + category_name: Some(description.code_name.clone()), reason_code, - reason_name: Some(ctx.reason.code_name), + reason_name: Some(description.code_name), }, None => MoveAbortExplain { category_code: category, diff --git a/x.toml b/x.toml index b5b957e092..e54ed5ace9 100644 --- a/x.toml +++ b/x.toml @@ -162,15 +162,10 @@ root-members = [ # --- [[determinator.path-rule]] -globs = [".github/**/*", ".circleci/**/*", "codecov.yml"] +globs = [".github/**/*", ".circleci/**/*", "devtools/**/*", "codecov.yml"] mark-changed = "all" # Core devtools files. [[determinator.path-rule]] -globs = ["cargo-toolchain", "cargo-flags", "scripts/dev_setup.sh", "x.toml"] -mark-changed = "all" - -[[determinator.package-rule]] -# x controls the build process, so if it changes, build everything. -on-affected = ["x"] +globs = ["cargo-toolchain", "cargo-flags", "scripts/dev_setup.sh", "scripts/dev_setup.ps1", "x.toml"] mark-changed = "all"