diff --git a/ATTRIBUTIONS.md b/ATTRIBUTIONS.md index 559ca45140f..00768e04545 100644 --- a/ATTRIBUTIONS.md +++ b/ATTRIBUTIONS.md @@ -1,14 +1,14 @@ # NEAR Client Attributions We have taken inspiration and few pieces of code from: - * [Parity Ethereum](https://github.com/paritytech/parity-ethereum) + * [OpenEthereum](https://github.com/openethereum/openethereum) * [Parity Substrate](https://github.com/paritytech/substrate) * [Parity Trie](https://github.com/paritytech/trie) * [Grin](https://github.com/mimblewimble/grin/) ## Licenses -### Parity {Ethereum, Substrate} +### OpenEthereum, Parity Substrate GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 diff --git a/Cargo.lock b/Cargo.lock index d27e0f4d067..02d5231669e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,7 +18,7 @@ dependencies = [ "log", "parking_lot 0.10.2", "pin-project", - "smallvec", + "smallvec 1.4.0", "tokio", "tokio-util 0.2.0", "trust-dns-proto", @@ -127,8 +127,8 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21705adc76bbe4bc98434890e73a89cd00c6015e5704a60bb6eea6c3b72316b6" dependencies = [ - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -155,7 +155,7 @@ dependencies = [ "copyless", "futures-channel", "futures-util", - "smallvec", + "smallvec 1.4.0", "tokio", ] @@ -297,9 +297,9 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f00371942083469785f7e28c540164af1913ee7c96a4534acb9cea92c39f057" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -308,9 +308,9 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -373,9 +373,9 @@ version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da71fef07bc806586090247e971229289f64c210a278ee5ae419314eb386b31d" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -491,14 +491,29 @@ dependencies = [ "lazycell", "log", "peeking_take_while", - "proc-macro2", - "quote", + "proc-macro2 1.0.19", + "quote 1.0.3", "regex", "rustc-hash", "shlex", "which", ] +[[package]] +name = "bit-set" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" + [[package]] name = "bitflags" version = "1.2.1" @@ -589,6 +604,19 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "bn" +version = "0.4.4" +source = "git+https://github.com/near/bn?rev=43953916ed1a314b78320771734f36af77993dd9#43953916ed1a314b78320771734f36af77993dd9" +dependencies = [ + "byteorder", + "crunchy", + "lazy_static", + "rand 0.6.5", + "rustc-hex 2.1.0", + "rustc-serialize", +] + [[package]] name = "borsh" version = "0.7.1" @@ -606,7 +634,7 @@ checksum = "b2d74755d937d261d5e9bdef87e0addfbc1ace0214f7776f21532d6e97325356" dependencies = [ "borsh-derive-internal", "borsh-schema-derive-internal", - "syn", + "syn 1.0.38", ] [[package]] @@ -615,9 +643,9 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c9f966cb7a42c8ed83546ef481bc1d1dec888fe5f84a4737d5c2094a483e41e" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -626,9 +654,9 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5df2543b56ebc2b4493e70d024ebde2cbb48d97bf7b1a16318eff30bd02669b8" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -835,9 +863,9 @@ checksum = "fb51c9e75b94452505acd21d929323f5a5c6c4735a852adbd39ef5fb1b014f30" dependencies = [ "heck", "proc-macro-error 0.4.12", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -942,7 +970,7 @@ dependencies = [ "log", "regalloc", "serde", - "smallvec", + "smallvec 1.4.0", "target-lexicon", "thiserror", ] @@ -980,7 +1008,7 @@ checksum = "3062a6fce384623ac2d19e98e7c774c944584bb5a8e42910e93dcebed7c44d87" dependencies = [ "cranelift-codegen", "log", - "smallvec", + "smallvec 1.4.0", "target-lexicon", ] @@ -1144,15 +1172,26 @@ dependencies = [ "log", ] +[[package]] +name = "derivative" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f" +dependencies = [ + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", +] + [[package]] name = "derive_more" version = "0.99.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -1161,9 +1200,9 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3df5480412da86cdf5d6b7f3b682422c84359ff7399aa658df1d15ee83244b1d" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -1244,9 +1283,9 @@ dependencies = [ "byteorder", "lazy_static", "owning_ref", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -1265,8 +1304,8 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2a9b11b96248fc9efa0c093e6406fea7e55a7e893c932dbdf47074f34ec52e7" dependencies = [ - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -1298,6 +1337,15 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +[[package]] +name = "elastic-array" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "580f3768bd6465780d063f5b8213a2ebd506e139b345e4a81eb301ceae3d61e1" +dependencies = [ + "heapsize", +] + [[package]] name = "elastic-array" version = "0.11.0" @@ -1329,9 +1377,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc4bfcfacb61d231109d1d55202c1f33263319668b168843e02ad4652725ec9c" dependencies = [ "heck", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", +] + +[[package]] +name = "enum-primitive-derive" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f52288f9a7ebb08959188872b58e7eaa12af9cb47da8e94158e16da7e143340" +dependencies = [ + "num-traits", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -1368,6 +1427,104 @@ dependencies = [ "libc", ] +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "version_check", +] + +[[package]] +name = "ethabi" +version = "9.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965126c64662832991f5a748893577630b558e47fa94e7f35aefcd20d737cef7" +dependencies = [ + "error-chain", + "ethereum-types", + "rustc-hex 2.1.0", + "serde", + "serde_derive", + "serde_json", + "tiny-keccak", +] + +[[package]] +name = "ethabi-contract" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf407dce0290374bfbb1528493bc14320e663f75856b73a5b76262d8e2cec3c9" + +[[package]] +name = "ethabi-derive" +version = "9.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0753d4f9e1dba99450da5f2400b20527702ae8ce0309a5f7c239d305539884" +dependencies = [ + "ethabi", + "heck", + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "ethbloom" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cfe1c169414b709cf28aa30c74060bdb830a03a8ba473314d079ac79d80a5f" +dependencies = [ + "crunchy", + "fixed-hash 0.5.2", + "impl-rlp", + "impl-serde 0.2.3", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba744248e3553a393143d5ebb68939fc3a4ec0c22a269682535f5ffe7fed728c" +dependencies = [ + "ethbloom", + "fixed-hash 0.5.2", + "impl-rlp", + "impl-serde 0.2.3", + "primitive-types 0.6.2", + "uint", +] + +[[package]] +name = "ethjson" +version = "0.1.0" +source = "git+https://github.com/openethereum/openethereum?rev=v2.7.2#2662d1925ec794f3ad7c5759b2412ff5128d259b" +dependencies = [ + "ethereum-types", + "rustc-hex 1.0.0", + "serde", + "serde_json", +] + +[[package]] +name = "evm" +version = "0.1.0" +source = "git+https://github.com/openethereum/openethereum?rev=v2.7.2#2662d1925ec794f3ad7c5759b2412ff5128d259b" +dependencies = [ + "bit-set", + "ethereum-types", + "keccak-hash", + "lazy_static", + "log", + "memory-cache", + "parity-bytes", + "parity-util-mem", + "parking_lot 0.9.0", + "vm", +] + [[package]] name = "faerie" version = "0.15.0" @@ -1399,9 +1556,9 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", "synstructure", ] @@ -1427,6 +1584,18 @@ dependencies = [ "log", ] +[[package]] +name = "fixed-hash" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" +dependencies = [ + "byteorder", + "rand 0.7.3", + "rustc-hex 2.1.0", + "static_assertions", +] + [[package]] name = "fixed-hash" version = "0.6.0" @@ -1435,7 +1604,7 @@ checksum = "32529fc42e86ec06e5047092082aab9ad459b070c5d2a76b14f4f5ce70bf2e84" dependencies = [ "byteorder", "rand 0.7.3", - "rustc-hex", + "rustc-hex 2.1.0", "static_assertions", ] @@ -1478,6 +1647,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -1549,9 +1724,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" dependencies = [ "proc-macro-hack", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -1634,6 +1809,7 @@ dependencies = [ "near-crypto", "near-network", "near-primitives", + "near-runtime-utils", "neard", "node-runtime", "serde", @@ -1685,7 +1861,7 @@ dependencies = [ "byteorder", "fallible-iterator", "indexmap", - "smallvec", + "smallvec 1.4.0", "stable_deref_trait", ] @@ -1706,9 +1882,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34a97a52fdee1870a34fa6e4b77570cba531b27d1838874fef4429a791a3d657" dependencies = [ "proc-macro-hack", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -1762,6 +1938,21 @@ dependencies = [ "tokio-util 0.3.1", ] +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hashbrown" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" +dependencies = [ + "autocfg 0.1.7", +] + [[package]] name = "heapsize" version = "0.4.2" @@ -1814,6 +2005,27 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac 0.7.0", + "digest 0.8.1", +] + +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +dependencies = [ + "digest 0.8.1", + "generic-array 0.12.3", + "hmac", +] + [[package]] name = "hostname" version = "0.3.1" @@ -1957,6 +2169,33 @@ dependencies = [ "parity-scale-codec", ] +[[package]] +name = "impl-rlp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f7a72f11830b52333f36e3b09a288333888bf54380fd0ac0790a3c31ab0f3c5" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-serde" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" +dependencies = [ + "serde", +] + [[package]] name = "indexer-example" version = "0.1.0" @@ -2054,8 +2293,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cdea9771bec3d95893f6c665a4fcd477af7858446a46bc2772f560534eee43b" dependencies = [ "derive_utils", - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -2127,6 +2366,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" +[[package]] +name = "keccak-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f0e55d8f242fdc281c21c4cd70960a25db6dd17cc6232d8b38b564b5b18c784" +dependencies = [ + "primitive-types 0.6.2", + "tiny-keccak", +] + +[[package]] +name = "keccak-hasher" +version = "0.1.1" +source = "git+https://github.com/openethereum/openethereum?rev=v2.7.2#2662d1925ec794f3ad7c5759b2412ff5128d259b" +dependencies = [ + "ethereum-types", + "hash-db", + "plain_hasher", + "tiny-keccak", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -2152,11 +2412,25 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" +[[package]] +name = "lazy-static-include" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10200e516c7a80a6dcfb1cdc23cd01ca0d8e97df71e9c5aa6d116302b89a928" +dependencies = [ + "lazy_static", + "starts-ends-with-caseless", + "syn 1.0.38", +] + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "lazycell" @@ -2197,6 +2471,22 @@ dependencies = [ "libc", ] +[[package]] +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +dependencies = [ + "arrayref", + "crunchy", + "digest 0.8.1", + "hmac-drbg", + "rand 0.7.3", + "sha2 0.8.1", + "subtle 2.2.2", + "typenum", +] + [[package]] name = "lightbeam" version = "0.17.0" @@ -2212,7 +2502,7 @@ dependencies = [ "itertools 0.8.2", "memoffset", "more-asserts", - "smallvec", + "smallvec 1.4.0", "staticvec", "thiserror", "typemap", @@ -2295,6 +2585,17 @@ dependencies = [ "libc", ] +[[package]] +name = "malloc_size_of_derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632647502a8bfa82458c07134791fffa7a719f00427d1afd79c3cb6d4960a982" +dependencies = [ + "proc-macro2 1.0.19", + "syn 1.0.38", + "synstructure", +] + [[package]] name = "match_cfg" version = "0.1.0" @@ -2347,6 +2648,15 @@ dependencies = [ "autocfg 1.0.0", ] +[[package]] +name = "memory-cache" +version = "0.1.0" +source = "git+https://github.com/openethereum/openethereum?rev=v2.7.2#2662d1925ec794f3ad7c5759b2412ff5128d259b" +dependencies = [ + "lru-cache", + "parity-util-mem", +] + [[package]] name = "mime" version = "0.3.16" @@ -2505,6 +2815,7 @@ dependencies = [ "near-crypto", "near-primitives", "near-runtime-configs", + "near-runtime-fees", "num-rational 0.2.4", "serde", "serde_json", @@ -2609,7 +2920,7 @@ dependencies = [ "near-primitives", "near-store", "num-rational 0.2.4", - "primitive-types", + "primitive-types 0.7.2", "rand 0.6.5", "rand 0.7.3", "serde", @@ -2617,6 +2928,42 @@ dependencies = [ "smart-default", ] +[[package]] +name = "near-evm-runner" +version = "2.2.0" +dependencies = [ + "bn", + "borsh", + "byteorder", + "derivative", + "enum-primitive-derive", + "ethabi", + "ethabi-contract", + "ethabi-derive", + "ethereum-types", + "evm", + "hex", + "keccak-hash", + "lazy-static-include", + "lazy_static", + "libsecp256k1", + "near-crypto", + "near-runtime-fees", + "near-runtime-utils", + "near-vm-errors", + "near-vm-logic", + "num-bigint 0.3.0", + "num-traits", + "parity-bytes", + "ripemd160", + "rlp", + "serde", + "serde_json", + "sha2 0.9.1", + "sha3", + "vm", +] + [[package]] name = "near-indexer" version = "0.6.0" @@ -2652,6 +2999,7 @@ dependencies = [ "near-network", "near-primitives", "near-rpc-error-macro", + "near-runtime-utils", "prometheus", "serde", "serde_json", @@ -2764,7 +3112,7 @@ dependencies = [ "near-rpc-error-macro", "near-vm-errors", "num-rational 0.2.4", - "primitive-types", + "primitive-types 0.7.2", "rand 0.7.3", "reed-solomon-erasure", "regex", @@ -2806,11 +3154,11 @@ dependencies = [ name = "near-rpc-error-core" version = "0.1.0" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.19", + "quote 1.0.3", "serde", "serde_json", - "syn", + "syn 1.0.38", ] [[package]] @@ -2818,11 +3166,11 @@ name = "near-rpc-error-macro" version = "0.1.0" dependencies = [ "near-rpc-error-core", - "proc-macro2", - "quote", + "proc-macro2 1.0.19", + "quote 1.0.3", "serde", "serde_json", - "syn", + "syn 1.0.38", ] [[package]] @@ -2858,6 +3206,10 @@ dependencies = [ [[package]] name = "near-runtime-utils" version = "2.2.0" +dependencies = [ + "lazy_static", + "regex", +] [[package]] name = "near-store" @@ -2868,7 +3220,7 @@ dependencies = [ "byteorder", "cached", "derive_more", - "elastic-array", + "elastic-array 0.11.0", "lazy_static", "near-crypto", "near-primitives", @@ -2900,6 +3252,8 @@ name = "near-vm-errors" version = "2.2.0" dependencies = [ "borsh", + "ethereum-types", + "hex", "near-rpc-error-macro", "serde", ] @@ -2930,6 +3284,7 @@ dependencies = [ "bencher", "borsh", "log", + "near-evm-runner", "near-primitives", "near-runtime-fees", "near-vm-errors", @@ -2973,11 +3328,13 @@ dependencies = [ "near-logger-utils", "near-network", "near-primitives", + "near-runtime-standalone", "near-store", "neard", "node-runtime", "openssl-probe", "rand 0.7.3", + "runtime-params-estimator", "serde_json", "testlib", ] @@ -3018,7 +3375,7 @@ dependencies = [ "node-runtime", "num-rational 0.2.4", "openssl-probe", - "primitive-types", + "primitive-types 0.7.2", "rand 0.7.3", "rocksdb", "serde", @@ -3061,11 +3418,14 @@ dependencies = [ "base64 0.11.0", "borsh", "byteorder", + "ethereum-types", "hex", "indicatif 0.13.0", "lazy_static", "log", + "near-chain-configs", "near-crypto", + "near-evm-runner", "near-metrics", "near-primitives", "near-runtime-configs", @@ -3165,9 +3525,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ "autocfg 1.0.0", ] @@ -3340,13 +3700,19 @@ dependencies = [ "http", "lazy_static", "proc-macro-error 1.0.4", - "proc-macro2", - "quote", + "proc-macro2 1.0.19", + "quote 1.0.3", "strum", "strum_macros", - "syn", + "syn 1.0.38", ] +[[package]] +name = "parity-bytes" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b56e3a2420138bdb970f84dfb9c774aea80fa0e7371549eedec0d80c209c67" + [[package]] name = "parity-scale-codec" version = "1.3.5" @@ -3371,12 +3737,37 @@ dependencies = [ "rand 0.7.3", ] +[[package]] +name = "parity-util-mem" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8174d85e62c4d615fddd1ef67966bdc5757528891d0742f15b131ad04667b3f9" +dependencies = [ + "cfg-if", + "ethereum-types", + "malloc_size_of_derive", + "parking_lot 0.9.0", + "smallvec 1.4.0", + "winapi 0.3.8", +] + [[package]] name = "parity-wasm" version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" +[[package]] +name = "parking_lot" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" +dependencies = [ + "lock_api 0.3.4", + "parking_lot_core 0.6.2", + "rustc_version", +] + [[package]] name = "parking_lot" version = "0.10.2" @@ -3398,6 +3789,21 @@ dependencies = [ "parking_lot_core 0.8.0", ] +[[package]] +name = "parking_lot_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +dependencies = [ + "cfg-if", + "cloudabi 0.0.3", + "libc", + "redox_syscall", + "rustc_version", + "smallvec 0.6.13", + "winapi 0.3.8", +] + [[package]] name = "parking_lot_core" version = "0.7.2" @@ -3408,7 +3814,7 @@ dependencies = [ "cloudabi 0.0.3", "libc", "redox_syscall", - "smallvec", + "smallvec 1.4.0", "winapi 0.3.8", ] @@ -3423,10 +3829,24 @@ dependencies = [ "instant", "libc", "redox_syscall", - "smallvec", + "smallvec 1.4.0", "winapi 0.3.8", ] +[[package]] +name = "patricia-trie-ethereum" +version = "0.1.0" +source = "git+https://github.com/openethereum/openethereum?rev=v2.7.2#2662d1925ec794f3ad7c5759b2412ff5128d259b" +dependencies = [ + "elastic-array 0.10.3", + "ethereum-types", + "hash-db", + "keccak-hasher", + "parity-bytes", + "rlp", + "trie-db", +] + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -3460,9 +3880,9 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8988430ce790d8682672117bc06dda364c0be32d3abd738234f19f3240bad99a" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -3489,19 +3909,41 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "plain_hasher" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e19e6491bdde87c2c43d70f4c194bc8a758f2eb732df00f61e43f7362e3b4cc" +dependencies = [ + "crunchy", +] + [[package]] name = "ppv-lite86" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +[[package]] +name = "primitive-types" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" +dependencies = [ + "fixed-hash 0.5.2", + "impl-codec", + "impl-rlp", + "impl-serde 0.3.1", + "uint", +] + [[package]] name = "primitive-types" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c55c21c64d0eaa4d7ed885d959ef2d62d9e488c27c0e02d9aa5ce6c877b7d5f8" dependencies = [ - "fixed-hash", + "fixed-hash 0.6.0", "impl-codec", "uint", ] @@ -3513,9 +3955,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" dependencies = [ "proc-macro-error-attr 0.4.12", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", "version_check", ] @@ -3526,9 +3968,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr 1.0.4", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", "version_check", ] @@ -3538,9 +3980,9 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", "syn-mid", "version_check", ] @@ -3551,8 +3993,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.19", + "quote 1.0.3", "version_check", ] @@ -3568,13 +4010,22 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + [[package]] name = "proc-macro2" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" dependencies = [ - "unicode-xid", + "unicode-xid 0.2.0", ] [[package]] @@ -3614,13 +4065,22 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + [[package]] name = "quote" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" dependencies = [ - "proc-macro2", + "proc-macro2 1.0.19", ] [[package]] @@ -3642,6 +4102,7 @@ dependencies = [ "rand_hc 0.1.0", "rand_isaac", "rand_jitter", + "rand_os", "rand_pcg", "rand_xorshift 0.1.1", "winapi 0.3.8", @@ -3742,6 +4203,20 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi 0.0.3", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi 0.3.8", +] + [[package]] name = "rand_pcg" version = "0.1.2" @@ -3805,6 +4280,15 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.1.56" @@ -3828,7 +4312,7 @@ version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a415a013dd7c5d4221382329a5a3482566da675737494935cbbbcdec04662f9d" dependencies = [ - "smallvec", + "smallvec 1.4.0", ] [[package]] @@ -3839,7 +4323,7 @@ checksum = "cca5b48c9db66c5ba084e4660b4c0cfe8b551a96074bc04b7c11de86ad0bf1f9" dependencies = [ "log", "rustc-hash", - "smallvec", + "smallvec 1.4.0", ] [[package]] @@ -3969,6 +4453,26 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "rlp" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1190dcc8c3a512f1eef5d09bb8c84c7f39e1054e174d1795482e18f5272f2e73" +dependencies = [ + "rustc-hex 2.1.0", +] + [[package]] name = "rocksdb" version = "0.14.0" @@ -3985,10 +4489,18 @@ dependencies = [ "borsh", "clap 2.33.0", "csv", + "ethabi", + "ethabi-contract", + "ethabi-derive", + "ethereum-types", "glob 0.3.0", "gnuplot", + "hex", "indicatif 0.15.0", + "lazy-static-include", + "near-chain-configs", "near-crypto", + "near-evm-runner", "near-primitives", "near-runtime-fees", "near-store", @@ -3997,11 +4509,14 @@ dependencies = [ "neard", "node-runtime", "num-rational 0.3.0", + "num-traits", "rand 0.7.3", "rand_xorshift 0.2.0", "rocksdb", "serde_json", + "state-viewer", "tempfile", + "testlib", "walrus", ] @@ -4029,12 +4544,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hex" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" + [[package]] name = "rustc-hex" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" + [[package]] name = "rustc_version" version = "0.2.3" @@ -4094,9 +4621,9 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e367622f934864ffa1c704ba2b82280aab856e3d8213c84c5720257eb34b15b9" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -4190,9 +4717,9 @@ version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -4311,6 +4838,15 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +[[package]] +name = "smallvec" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +dependencies = [ + "maybe-uninit", +] + [[package]] name = "smallvec" version = "1.4.0" @@ -4323,9 +4859,9 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -4352,6 +4888,12 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" +[[package]] +name = "starts-ends-with-caseless" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1c13a0dff1a602924cf45fcb409855d46a5fd470a15b76ddcb61be675296d3" + [[package]] name = "state-viewer" version = "0.1.0" @@ -4447,9 +4989,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" dependencies = [ "heck", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -4464,15 +5006,26 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + [[package]] name = "syn" version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4" dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", + "proc-macro2 1.0.19", + "quote 1.0.3", + "unicode-xid 0.2.0", ] [[package]] @@ -4481,9 +5034,9 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -4492,10 +5045,10 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", + "unicode-xid 0.2.0", ] [[package]] @@ -4569,6 +5122,10 @@ dependencies = [ "borsh", "byteorder", "clap 2.33.0", + "ethabi", + "ethabi-contract", + "ethabi-derive", + "ethereum-types", "futures", "hex", "lazy_static", @@ -4577,6 +5134,7 @@ dependencies = [ "near-chain-configs", "near-client", "near-crypto", + "near-evm-runner", "near-jsonrpc", "near-jsonrpc-client", "near-logger-utils", @@ -4617,9 +5175,9 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -4650,6 +5208,15 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "tiny-keccak" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" +dependencies = [ + "crunchy", +] + [[package]] name = "tokio" version = "0.2.18" @@ -4680,9 +5247,9 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -4777,8 +5344,8 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbad39da2f9af1cae3016339ad7f2c7a9e870f12e8fd04c4fd7ef35b30c0d2b" dependencies = [ - "quote", - "syn", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -4825,7 +5392,7 @@ dependencies = [ "serde", "serde_json", "sharded-slab", - "smallvec", + "smallvec 1.4.0", "tracing-core", "tracing-log", "tracing-serde", @@ -4837,6 +5404,19 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +[[package]] +name = "trie-db" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "191fda5d0106f3ed35a8c6875428b213e15c516e48129cc263dd7ad16e9a665f" +dependencies = [ + "hash-db", + "hashbrown", + "log", + "rand 0.6.5", + "smallvec 1.4.0", +] + [[package]] name = "trust-dns-proto" version = "0.18.0-alpha.2" @@ -4851,7 +5431,7 @@ dependencies = [ "lazy_static", "log", "rand 0.7.3", - "smallvec", + "smallvec 1.4.0", "socket2", "tokio", "url 2.1.1", @@ -4871,7 +5451,7 @@ dependencies = [ "log", "lru-cache", "resolv-conf", - "smallvec", + "smallvec 1.4.0", "tokio", "trust-dns-proto", ] @@ -4905,7 +5485,7 @@ checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" dependencies = [ "byteorder", "crunchy", - "rustc-hex", + "rustc-hex 2.1.0", "static_assertions", ] @@ -4933,7 +5513,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" dependencies = [ - "smallvec", + "smallvec 1.4.0", ] [[package]] @@ -4948,6 +5528,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + [[package]] name = "unicode-xid" version = "0.2.0" @@ -5023,10 +5609,10 @@ checksum = "e668e9cd05c5009b833833aa1147e5727b5396ea401f22dd1167618eed4a10c9" dependencies = [ "if_chain", "lazy_static", - "proc-macro2", - "quote", + "proc-macro2 1.0.19", + "quote 1.0.3", "regex", - "syn", + "syn 1.0.38", "validator", ] @@ -5048,6 +5634,19 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +[[package]] +name = "vm" +version = "0.1.0" +source = "git+https://github.com/openethereum/openethereum?rev=v2.7.2#2662d1925ec794f3ad7c5759b2412ff5128d259b" +dependencies = [ + "ethereum-types", + "ethjson", + "keccak-hash", + "parity-bytes", + "patricia-trie-ethereum", + "rlp", +] + [[package]] name = "void" version = "1.0.2" @@ -5098,9 +5697,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c2bb690b44cb1b0fdcc54d4998d21f8bdaf706b93775425e440b174f39ad16" dependencies = [ "heck", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", ] [[package]] @@ -5140,9 +5739,9 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", "wasm-bindgen-shared", ] @@ -5164,7 +5763,7 @@ version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" dependencies = [ - "quote", + "quote 1.0.3", "wasm-bindgen-macro-support", ] @@ -5174,9 +5773,9 @@ version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5224,7 +5823,7 @@ dependencies = [ "serde-bench", "serde_bytes", "serde_derive", - "smallvec", + "smallvec 1.4.0", "target-lexicon", "wasmparser 0.51.4", "winapi 0.3.8", @@ -5245,7 +5844,7 @@ dependencies = [ "nix", "serde", "serde_derive", - "smallvec", + "smallvec 1.4.0", "wasmer-runtime-core", ] @@ -5538,9 +6137,9 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.19", + "quote 1.0.3", + "syn 1.0.38", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index 747a1ad1134..0476d7a9fdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,12 +13,13 @@ members = [ "core/store", "core/metrics", "utils/actix", - "runtime/runtime", - "runtime/runtime-standalone", + "runtime/near-evm-runner", "runtime/near-runtime-fees", "runtime/near-vm-logic", "runtime/near-vm-runner", "runtime/near-vm-runner-standalone", + "runtime/runtime", + "runtime/runtime-standalone", "runtime/runtime-params-estimator", "chain/chain", "chain/chunks", @@ -65,6 +66,8 @@ near-chain-configs = { path = "./core/chain-configs" } near-crypto = { path = "./core/crypto" } near-primitives = { path = "./core/primitives" } near-store = { path = "./core/store" } +near-runtime-standalone = { path = "./runtime/runtime-standalone" } +runtime-params-estimator = { path = "./runtime/runtime-params-estimator" } node-runtime = { path = "./runtime/runtime" } @@ -107,5 +110,6 @@ metric_recorder = ["neard/metric_recorder"] delay_detector = ["neard/delay_detector"] rosetta_rpc = ["neard/rosetta_rpc"] protocol_feature_forward_chunk_parts = ["neard/protocol_feature_forward_chunk_parts"] -nightly_protocol = [] -nightly_protocol_features = ["nightly_protocol", "neard/nightly_protocol_features"] +nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_protocol"] +nightly_protocol_features = ["nightly_protocol", "neard/nightly_protocol_features", "protocol_feature_evm"] +protocol_feature_evm = ["neard/protocol_feature_evm", "testlib/protocol_feature_evm", "near-runtime-standalone/protocol_feature_evm", "runtime-params-estimator/protocol_feature_evm"] diff --git a/chain/chain/Cargo.toml b/chain/chain/Cargo.toml index 0287e8cd7d5..240f3c81c72 100644 --- a/chain/chain/Cargo.toml +++ b/chain/chain/Cargo.toml @@ -41,6 +41,7 @@ expensive_tests = [] adversarial = [] delay_detector = ["delay-detector"] no_cache = ["near-store/no_cache"] +protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-chain-configs/protocol_feature_evm"] protocol_feature_rectify_inflation = [] nightly_protocol_features = ["nightly_protocol", "protocol_feature_rectify_inflation"] nightly_protocol = [] diff --git a/chain/chain/src/test_utils.rs b/chain/chain/src/test_utils.rs index 1bc2a50aaa9..935a3fc69ad 100644 --- a/chain/chain/src/test_utils.rs +++ b/chain/chain/src/test_utils.rs @@ -959,6 +959,12 @@ impl RuntimeAdapter for KeyValueRuntime { ) -> Result<(ValidatorStake, bool), Error> { Err(ErrorKind::NotAValidator.into()) } + + #[cfg(feature = "protocol_feature_evm")] + fn evm_chain_id(&self) -> u128 { + // See https://github.com/ethereum-lists/chains/blob/master/_data/chains/1313161555.json + 1313161555 + } } pub fn setup() -> (Chain, Arc, Arc) { diff --git a/chain/chain/src/types.rs b/chain/chain/src/types.rs index 44fce13ab93..91995b0a4f6 100644 --- a/chain/chain/src/types.rs +++ b/chain/chain/src/types.rs @@ -586,6 +586,9 @@ pub trait RuntimeAdapter: Send + Sync { header_head: &CryptoHash, ) -> Result; + #[cfg(feature = "protocol_feature_evm")] + fn evm_chain_id(&self) -> u128; + /// Build receipts hashes. // Due to borsh serialization constraints, we have to use `&Vec` instead of `&[Receipt]` // here. diff --git a/chain/chunks/Cargo.toml b/chain/chunks/Cargo.toml index f6508935384..6af66720ef4 100644 --- a/chain/chunks/Cargo.toml +++ b/chain/chunks/Cargo.toml @@ -29,5 +29,3 @@ near-logger-utils = { path = "../../test-utils/logger" } byzantine_asserts = ["near-chain/byzantine_asserts"] expensive_tests = [] protocol_feature_forward_chunk_parts = ["near-primitives/protocol_feature_forward_chunk_parts", "near-network/protocol_feature_forward_chunk_parts"] -nightly_protocol_features = ["nightly_protocol", "protocol_feature_forward_chunk_parts", "near-primitives/nightly_protocol_features"] -nightly_protocol = ["near-primitives/nightly_protocol"] diff --git a/chain/chunks/src/lib.rs b/chain/chunks/src/lib.rs index f24e39453ae..c1b3c748654 100644 --- a/chain/chunks/src/lib.rs +++ b/chain/chunks/src/lib.rs @@ -1701,17 +1701,14 @@ impl ShardsManager { #[cfg(test)] mod test { - use crate::test_utils::{ChunkForwardingTestFixture, SealsManagerTestFixture}; - use crate::{ - ChunkRequestInfo, ProcessPartialEncodedChunkResult, Seal, SealsManager, ShardsManager, - CHUNK_REQUEST_RETRY_MS, NUM_PARTS_REQUESTED_IN_SEAL, - }; + use super::*; + use crate::test_utils::*; use near_chain::test_utils::KeyValueRuntime; use near_network::test_utils::MockNetworkAdapter; #[cfg(feature = "protocol_feature_forward_chunk_parts")] use near_network::types::PartialEncodedChunkForwardMsg; use near_primitives::hash::{hash, CryptoHash}; - use near_primitives::sharding::{ChunkHash, PartialEncodedChunkV2}; + #[cfg(feature = "protocol_feature_forward_chunk_parts")] use near_primitives::version::PROTOCOL_VERSION; use near_store::test_utils::create_test_store; use std::sync::Arc; diff --git a/chain/client/src/client_actor.rs b/chain/client/src/client_actor.rs index cbeb385e9e6..6c1a6ccf2df 100644 --- a/chain/client/src/client_actor.rs +++ b/chain/client/src/client_actor.rs @@ -754,7 +754,10 @@ impl ClientActor { ); delay = core::cmp::min( delay, - self.doomslug_timer_next_attempt.signed_duration_since(now).to_std().unwrap(), + self.doomslug_timer_next_attempt + .signed_duration_since(now) + .to_std() + .unwrap_or(delay), ) } if self.block_production_started { @@ -771,7 +774,10 @@ impl ClientActor { delay = core::cmp::min( delay, - self.block_production_next_attempt.signed_duration_since(now).to_std().unwrap(), + self.block_production_next_attempt + .signed_duration_since(now) + .to_std() + .unwrap_or(delay), ) } self.chunk_request_retry_next_attempt = self.run_timer( @@ -786,7 +792,10 @@ impl ClientActor { ); core::cmp::min( delay, - self.chunk_request_retry_next_attempt.signed_duration_since(now).to_std().unwrap(), + self.chunk_request_retry_next_attempt + .signed_duration_since(now) + .to_std() + .unwrap_or(delay), ) } diff --git a/chain/epoch_manager/Cargo.toml b/chain/epoch_manager/Cargo.toml index 37bb95e27a9..43887f343f7 100644 --- a/chain/epoch_manager/Cargo.toml +++ b/chain/epoch_manager/Cargo.toml @@ -15,7 +15,7 @@ rand = "0.7" serde = { version = "1", features = [ "derive" ] } serde_json = "1" smart-default = "0.6" -primitive-types = { version = "0.7", default-features = false } +primitive-types = "0.7" num-rational = "0.2.4" chrono = { version = "0.4.4", optional = true} diff --git a/chain/jsonrpc/Cargo.toml b/chain/jsonrpc/Cargo.toml index 8b04578e95f..edec01a4716 100644 --- a/chain/jsonrpc/Cargo.toml +++ b/chain/jsonrpc/Cargo.toml @@ -25,6 +25,7 @@ near-client = { path = "../client" } near-network = { path = "../network" } near-jsonrpc-client = { path = "client" } near-rpc-error-macro = { path = "../../tools/rpctypegen/macro" } +near-runtime-utils = { path = "../../runtime/near-runtime-utils" } [dev-dependencies] near-logger-utils = { path = "../../test-utils/logger" } @@ -32,4 +33,4 @@ near-logger-utils = { path = "../../test-utils/logger" } [features] dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] adversarial = [] -nightly_protocol = [] +nightly_protocol = ["near-primitives/nightly_protocol"] diff --git a/chain/jsonrpc/src/lib.rs b/chain/jsonrpc/src/lib.rs index fcf27eef8cd..4e7cfecf713 100644 --- a/chain/jsonrpc/src/lib.rs +++ b/chain/jsonrpc/src/lib.rs @@ -38,10 +38,11 @@ use near_primitives::rpc::{ use near_primitives::serialize::{from_base, from_base64, BaseEncode}; use near_primitives::transaction::SignedTransaction; use near_primitives::types::{AccountId, BlockId, BlockReference, MaybeBlockId}; -use near_primitives::utils::is_valid_account_id; use near_primitives::views::{ FinalExecutionOutcomeView, FinalExecutionOutcomeViewEnum, QueryRequest, }; +use near_runtime_utils::is_valid_account_id; + mod metrics; /// Max size of the query path (soft-deprecated) diff --git a/chain/network/Cargo.toml b/chain/network/Cargo.toml index fb5da80e0ae..3c3b6fb753d 100644 --- a/chain/network/Cargo.toml +++ b/chain/network/Cargo.toml @@ -44,9 +44,7 @@ near-telemetry = { path = "../telemetry" } adversarial = [] metric_recorder = [] delay_detector = ["delay-detector"] -protocol_feature_forward_chunk_parts = [] -nightly_protocol_features = ["nightly_protocol", "protocol_feature_forward_chunk_parts"] -nightly_protocol = [] +protocol_feature_forward_chunk_parts = ["near-primitives/protocol_feature_forward_chunk_parts"] [[bench]] name = "graph" diff --git a/core/chain-configs/Cargo.toml b/core/chain-configs/Cargo.toml index 41ba0f0fa5c..3ada587c2d8 100644 --- a/core/chain-configs/Cargo.toml +++ b/core/chain-configs/Cargo.toml @@ -16,3 +16,8 @@ sha2 = "0.9" near-crypto = { path = "../crypto" } near-primitives = { path = "../primitives" } near-runtime-configs = { path = "../runtime-configs" } +near-runtime-fees = { path = "../../runtime/near-runtime-fees" } + +[features] +default = [] +protocol_feature_evm = ["near-primitives/protocol_feature_evm", "near-runtime-fees/protocol_feature_evm"] \ No newline at end of file diff --git a/core/chain-configs/src/genesis_config.rs b/core/chain-configs/src/genesis_config.rs index 241c3144b78..806f752f281 100644 --- a/core/chain-configs/src/genesis_config.rs +++ b/core/chain-configs/src/genesis_config.rs @@ -23,6 +23,16 @@ use near_primitives::types::{ use near_primitives::version::ProtocolVersion; use near_runtime_configs::RuntimeConfig; +const MAX_GAS_PRICE: Balance = 10_000_000_000_000_000_000_000; + +#[cfg(feature = "protocol_feature_evm")] +/// See https://github.com/ethereum-lists/chains/blob/master/_data/chains/1313161555.json +pub const TEST_EVM_CHAIN_ID: u128 = 1313161555; + +#[cfg(feature = "protocol_feature_evm")] +/// See https://github.com/ethereum-lists/chains/blob/master/_data/chains/1313161554.json +pub const MAINNET_EVM_CHAIN_ID: u128 = 1313161554; + fn default_online_min_threshold() -> Rational { Rational::new(90, 100) } @@ -39,8 +49,6 @@ fn default_protocol_upgrade_stake_threshold() -> Rational { Rational::new(8, 10) } -const MAX_GAS_PRICE: Balance = 10_000_000_000_000_000_000_000; - #[derive(Debug, Clone, SmartDefault, Serialize, Deserialize)] pub struct GenesisConfig { /// Protocol version that this genesis works with. @@ -164,7 +172,9 @@ impl GenesisConfig { /// GenesisConfig structure. pub fn from_file>(path: P) -> Self { let reader = BufReader::new(File::open(path).expect("Could not open genesis config file.")); - serde_json::from_reader(reader).expect("Failed to deserialize the genesis records.") + let genesis_config: GenesisConfig = + serde_json::from_reader(reader).expect("Failed to deserialize the genesis records."); + genesis_config } /// Writes GenesisConfig to the file. diff --git a/core/chain-configs/src/lib.rs b/core/chain-configs/src/lib.rs index e0fd5ac30b1..776568dc291 100644 --- a/core/chain-configs/src/lib.rs +++ b/core/chain-configs/src/lib.rs @@ -3,3 +3,5 @@ mod genesis_config; pub use client_config::{ClientConfig, LogSummaryStyle}; pub use genesis_config::{Genesis, GenesisConfig, GenesisRecords}; +#[cfg(feature = "protocol_feature_evm")] +pub use genesis_config::{MAINNET_EVM_CHAIN_ID, TEST_EVM_CHAIN_ID}; diff --git a/core/crypto/src/signature.rs b/core/crypto/src/signature.rs index a04512a01d1..ac94d8e38d8 100644 --- a/core/crypto/src/signature.rs +++ b/core/crypto/src/signature.rs @@ -108,6 +108,12 @@ impl std::fmt::Debug for Secp256K1PublicKey { } } +impl From for [u8; 64] { + fn from(pubkey: Secp256K1PublicKey) -> Self { + pubkey.0 + } +} + impl PartialEq for Secp256K1PublicKey { fn eq(&self, other: &Self) -> bool { self.0[..] == other.0[..] @@ -567,6 +573,12 @@ impl Debug for Secp256K1Signature { } } +impl From for [u8; 65] { + fn from(sig: Secp256K1Signature) -> [u8; 65] { + sig.0 + } +} + /// Signature container supporting different curves. #[derive(Clone, PartialEq, Eq)] pub enum Signature { @@ -614,7 +626,7 @@ impl Signature { .unwrap(); let sig = rsig.to_standard(&SECP256K1); let pdata: [u8; 65] = { - // code borrowed from https://github.com/paritytech/parity-ethereum/blob/98b7c07171cd320f32877dfa5aa528f585dc9a72/ethkey/src/signature.rs#L210 + // code borrowed from https://github.com/openethereum/openethereum/blob/98b7c07171cd320f32877dfa5aa528f585dc9a72/ethkey/src/signature.rs#L210 let mut temp = [4u8; 65]; temp[1..65].copy_from_slice(&public_key.0); temp diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index 757f5458abf..9563cd95d7e 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -24,7 +24,7 @@ reed-solomon-erasure = "4" jemallocator = { version = "0.3", optional = true } hex = "0.4" num-rational = "0.2.4" -primitive-types = { version = "0.7", default-features = false } +primitive-types = "0.7" borsh = "0.7.1" @@ -37,7 +37,8 @@ default = ["jemallocator"] dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] protocol_feature_forward_chunk_parts = [] protocol_feature_rectify_inflation = [] -nightly_protocol_features = ["nightly_protocol", "protocol_feature_forward_chunk_parts", "protocol_feature_rectify_inflation"] +protocol_feature_evm = [] +nightly_protocol_features = ["nightly_protocol", "protocol_feature_forward_chunk_parts", "protocol_feature_rectify_inflation", "protocol_feature_evm"] nightly_protocol = [] diff --git a/core/primitives/src/errors.rs b/core/primitives/src/errors.rs index c3445e634b4..77b15c2f704 100644 --- a/core/primitives/src/errors.rs +++ b/core/primitives/src/errors.rs @@ -107,13 +107,13 @@ impl std::error::Error for StorageError {} pub enum InvalidTxError { /// Happens if a wrong AccessKey used or AccessKey has not enough permissions InvalidAccessKeyError(InvalidAccessKeyError), - /// TX signer_id is not in a valid format or not satisfy requirements see `near_core::primitives::utils::is_valid_account_id` + /// TX signer_id is not in a valid format or not satisfy requirements see `near_runtime_utils::utils::is_valid_account_id` InvalidSignerId { signer_id: AccountId }, /// TX signer_id is not found in a storage SignerDoesNotExist { signer_id: AccountId }, /// Transaction nonce must be account[access_key].nonce + 1 InvalidNonce { tx_nonce: Nonce, ak_nonce: Nonce }, - /// TX receiver_id is not in a valid format or not satisfy requirements see `near_core::primitives::utils::is_valid_account_id` + /// TX receiver_id is not in a valid format or not satisfy requirements see `near_runtime_utils::is_valid_account_id` InvalidReceiverId { receiver_id: AccountId }, /// TX signature is not valid InvalidSignature, diff --git a/core/primitives/src/test_utils.rs b/core/primitives/src/test_utils.rs index ca4abe138ce..a6b0a75c3af 100644 --- a/core/primitives/src/test_utils.rs +++ b/core/primitives/src/test_utils.rs @@ -1,11 +1,16 @@ +use std::collections::HashMap; + +use num_rational::Rational; + use near_crypto::{EmptySigner, PublicKey, Signature, Signer}; use crate::account::{AccessKey, AccessKeyPermission, Account}; use crate::block::Block; use crate::block_header::{BlockHeader, BlockHeaderV2}; -use crate::errors::EpochError; +use crate::errors::{EpochError, TxExecutionError}; use crate::hash::CryptoHash; use crate::merkle::PartialMerkleTree; +use crate::serialize::from_base64; use crate::sharding::ShardChunkHeader; use crate::transaction::{ Action, AddKeyAction, CreateAccountAction, DeleteAccountAction, DeleteKeyAction, @@ -15,8 +20,7 @@ use crate::transaction::{ use crate::types::{AccountId, Balance, BlockHeight, EpochId, EpochInfoProvider, Gas, Nonce}; use crate::validator_signer::ValidatorSigner; use crate::version::PROTOCOL_VERSION; -use num_rational::Rational; -use std::collections::HashMap; +use crate::views::FinalExecutionStatus; pub fn account_new(amount: Balance, code_hash: CryptoHash) -> Account { Account { amount, locked: 0, code_hash, storage_usage: std::mem::size_of::() as u64 } @@ -430,3 +434,23 @@ impl EpochInfoProvider for MockEpochInfoProvider { Ok(0) } } + +impl FinalExecutionStatus { + pub fn as_success(self) -> Option { + match self { + FinalExecutionStatus::SuccessValue(value) => Some(value), + _ => None, + } + } + + pub fn as_failure(self) -> Option { + match self { + FinalExecutionStatus::Failure(failure) => Some(failure), + _ => None, + } + } + + pub fn as_success_decoded(self) -> Option> { + self.as_success().and_then(|value| from_base64(&value).ok()) + } +} diff --git a/core/primitives/src/utils.rs b/core/primitives/src/utils.rs index 39f361cfd79..1d8beea3db3 100644 --- a/core/primitives/src/utils.rs +++ b/core/primitives/src/utils.rs @@ -6,11 +6,8 @@ use byteorder::{LittleEndian, WriteBytesExt}; use chrono::{DateTime, NaiveDateTime, Utc}; use rand::distributions::Alphanumeric; use rand::{thread_rng, Rng}; -use regex::Regex; use serde; -use lazy_static::lazy_static; - use crate::hash::{hash, CryptoHash}; use crate::receipt::Receipt; use crate::transaction::SignedTransaction; @@ -20,9 +17,6 @@ use crate::version::{ }; use std::mem::size_of; -pub const MIN_ACCOUNT_ID_LEN: usize = 2; -pub const MAX_ACCOUNT_ID_LEN: usize = 64; - /// Number of nano seconds in a second. const NS_IN_SECOND: u64 = 1_000_000_000; @@ -157,54 +151,12 @@ pub fn index_to_bytes(index: u64) -> Vec { bytes } -lazy_static! { - /// See NEP#0006 - static ref VALID_ACCOUNT_ID: Regex = - Regex::new(r"^(([a-z\d]+[\-_])*[a-z\d]+\.)*([a-z\d]+[\-_])*[a-z\d]+$").unwrap(); - /// Represents a part of an account ID with a suffix of as a separator `.`. - static ref VALID_ACCOUNT_PART_ID_WITH_TAIL_SEPARATOR: Regex = - Regex::new(r"^([a-z\d]+[\-_])*[a-z\d]+\.$").unwrap(); - /// Represents a top level account ID. - static ref VALID_TOP_LEVEL_ACCOUNT_ID: Regex = - Regex::new(r"^([a-z\d]+[\-_])*[a-z\d]+$").unwrap(); -} - -/// const does not allow function call, so have to resort to this +/// This is duplicate of near_runtime_utils::system_account. +/// TODO: code that uses this system_account should be moved into runtime and depend on it. pub fn system_account() -> AccountId { "system".to_string() } -pub fn is_valid_account_id(account_id: &AccountId) -> bool { - account_id.len() >= MIN_ACCOUNT_ID_LEN - && account_id.len() <= MAX_ACCOUNT_ID_LEN - && VALID_ACCOUNT_ID.is_match(account_id) -} - -pub fn is_valid_top_level_account_id(account_id: &AccountId) -> bool { - account_id.len() >= MIN_ACCOUNT_ID_LEN - && account_id.len() <= MAX_ACCOUNT_ID_LEN - && account_id != &system_account() - && VALID_TOP_LEVEL_ACCOUNT_ID.is_match(account_id) -} - -/// Returns true if the signer_id can create a direct sub-account with the given account Id. -/// It assumes the signer_id is a valid account_id -pub fn is_valid_sub_account_id(signer_id: &AccountId, sub_account_id: &AccountId) -> bool { - if !is_valid_account_id(sub_account_id) { - return false; - } - if signer_id.len() >= sub_account_id.len() { - return false; - } - // Will not panic, since valid account id is utf-8 only and the length is checked above. - // e.g. when `near` creates `aa.near`, it splits into `aa.` and `near` - let (prefix, suffix) = sub_account_id.split_at(sub_account_id.len() - signer_id.len()); - if suffix != signer_id { - return false; - } - VALID_ACCOUNT_PART_ID_WITH_TAIL_SEPARATOR.is_match(prefix) -} - /// A wrapper around Option that provides native Display trait. /// Simplifies propagating automatic Display trait on parent structs. pub struct DisplayOption(pub Option); @@ -350,224 +302,6 @@ where mod tests { use super::*; - const OK_ACCOUNT_IDS: &[&str] = &[ - "aa", - "a-a", - "a-aa", - "100", - "0o", - "com", - "near", - "bowen", - "b-o_w_e-n", - "b.owen", - "bro.wen", - "a.ha", - "a.b-a.ra", - "system", - "over.9000", - "google.com", - "illia.cheapaccounts.near", - "0o0ooo00oo00o", - "alex-skidanov", - "10-4.8-2", - "b-o_w_e-n", - "no_lols", - "0123456789012345678901234567890123456789012345678901234567890123", - // Valid, but can't be created - "near.a", - ]; - - #[test] - fn test_is_valid_account_id() { - for account_id in OK_ACCOUNT_IDS { - assert!( - is_valid_account_id(&account_id.to_string()), - "Valid account id {:?} marked invalid", - account_id - ); - } - - let bad_account_ids = vec![ - "a", - "A", - "Abc", - "-near", - "near-", - "-near-", - "near.", - ".near", - "near@", - "@near", - "неар", - "@@@@@", - "0__0", - "0_-_0", - "0_-_0", - "..", - "a..near", - "nEar", - "_bowen", - "hello world", - "abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz", - "01234567890123456789012345678901234567890123456789012345678901234", - // `@` separators are banned now - "some-complex-address@gmail.com", - "sub.buy_d1gitz@atata@b0-rg.c_0_m", - ]; - for account_id in bad_account_ids { - assert!( - !is_valid_account_id(&account_id.to_string()), - "Invalid account id {:?} marked valid", - account_id - ); - } - } - - #[test] - fn test_is_valid_top_level_account_id() { - let ok_top_level_account_ids = vec![ - "aa", - "a-a", - "a-aa", - "100", - "0o", - "com", - "near", - "bowen", - "b-o_w_e-n", - "0o0ooo00oo00o", - "alex-skidanov", - "b-o_w_e-n", - "no_lols", - "0123456789012345678901234567890123456789012345678901234567890123", - ]; - for account_id in ok_top_level_account_ids { - assert!( - is_valid_top_level_account_id(&account_id.to_string()), - "Valid top level account id {:?} marked invalid", - account_id - ); - } - - let bad_top_level_account_ids = vec![ - "near.a", - "b.owen", - "bro.wen", - "a.ha", - "a.b-a.ra", - "some-complex-address@gmail.com", - "sub.buy_d1gitz@atata@b0-rg.c_0_m", - "over.9000", - "google.com", - "illia.cheapaccounts.near", - "10-4.8-2", - "a", - "A", - "Abc", - "-near", - "near-", - "-near-", - "near.", - ".near", - "near@", - "@near", - "неар", - "@@@@@", - "0__0", - "0_-_0", - "0_-_0", - "..", - "a..near", - "nEar", - "_bowen", - "hello world", - "abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz", - "01234567890123456789012345678901234567890123456789012345678901234", - // Valid regex and length, but reserved - "system", - ]; - for account_id in bad_top_level_account_ids { - assert!( - !is_valid_top_level_account_id(&account_id.to_string()), - "Invalid top level account id {:?} marked valid", - account_id - ); - } - } - - #[test] - fn test_is_valid_sub_account_id() { - let ok_pairs = vec![ - ("test", "a.test"), - ("test-me", "abc.test-me"), - ("gmail.com", "abc.gmail.com"), - ("gmail.com", "abc-lol.gmail.com"), - ("gmail.com", "abc_lol.gmail.com"), - ("gmail.com", "bro-abc_lol.gmail.com"), - ("g0", "0g.g0"), - ("1g", "1g.1g"), - ("5-3", "4_2.5-3"), - ]; - for (signer_id, sub_account_id) in ok_pairs { - assert!( - is_valid_sub_account_id(&signer_id.to_string(), &sub_account_id.to_string()), - "Failed to create sub-account {:?} by account {:?}", - sub_account_id, - signer_id - ); - } - - let bad_pairs = vec![ - ("test", ".test"), - ("test", "test"), - ("test", "est"), - ("test", ""), - ("test", "st"), - ("test5", "ббб"), - ("test", "a-test"), - ("test", "etest"), - ("test", "a.etest"), - ("test", "retest"), - ("test-me", "abc-.test-me"), - ("test-me", "Abc.test-me"), - ("test-me", "-abc.test-me"), - ("test-me", "a--c.test-me"), - ("test-me", "a_-c.test-me"), - ("test-me", "a-_c.test-me"), - ("test-me", "_abc.test-me"), - ("test-me", "abc_.test-me"), - ("test-me", "..test-me"), - ("test-me", "a..test-me"), - ("gmail.com", "a.abc@gmail.com"), - ("gmail.com", ".abc@gmail.com"), - ("gmail.com", ".abc@gmail@com"), - ("gmail.com", "abc@gmail@com"), - ("test", "a@test"), - ("test_me", "abc@test_me"), - ("gmail.com", "abc@gmail.com"), - ("gmail@com", "abc.gmail@com"), - ("gmail.com", "abc-lol@gmail.com"), - ("gmail@com", "abc_lol.gmail@com"), - ("gmail@com", "bro-abc_lol.gmail@com"), - ("gmail.com", "123456789012345678901234567890123456789012345678901234567890@gmail.com"), - ( - "123456789012345678901234567890123456789012345678901234567890", - "1234567890.123456789012345678901234567890123456789012345678901234567890", - ), - ("aa", "ъ@aa"), - ("aa", "ъ.aa"), - ]; - for (signer_id, sub_account_id) in bad_pairs { - assert!( - !is_valid_sub_account_id(&signer_id.to_string(), &sub_account_id.to_string()), - "Invalid sub-account {:?} created by account {:?}", - sub_account_id, - signer_id - ); - } - } - #[test] fn test_num_chunk_producers() { for num_seats in 1..50 { diff --git a/core/primitives/src/version.rs b/core/primitives/src/version.rs index 86d949c32c3..fa8e937cb70 100644 --- a/core/primitives/src/version.rs +++ b/core/primitives/src/version.rs @@ -47,11 +47,11 @@ pub const UPGRADABILITY_FIX_PROTOCOL_VERSION: ProtocolVersion = 37; /// Updates the way receipt ID, data ID and random seeds are constructed. pub const CREATE_HASH_PROTOCOL_VERSION: ProtocolVersion = 38; -pub const SHARD_CHUNK_HEADER_UPGRADE_VERSION: ProtocolVersion = 41; - /// Fix the storage usage of the delete key action. pub const DELETE_KEY_STORAGE_USAGE_PROTOCOL_VERSION: ProtocolVersion = 40; +pub const SHARD_CHUNK_HEADER_UPGRADE_VERSION: ProtocolVersion = 41; + pub struct ProtocolVersionRange { lower: ProtocolVersion, upper: Option, @@ -70,16 +70,18 @@ impl ProtocolVersionRange { /// New Protocol features should go here. Features are guarded by their corresponding feature flag. /// For example, if we have `ProtocolFeature::EVM` and a corresponding feature flag `evm`, it will look /// like -/// ``` -/// #[cfg(feature = "evm")] -/// EVM -/// ``` +/// +/// #[cfg(feature = "protocol_feature_evm")] +/// EVM code +/// #[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)] pub enum ProtocolFeature { #[cfg(feature = "protocol_feature_forward_chunk_parts")] ForwardChunkParts, #[cfg(feature = "protocol_feature_rectify_inflation")] RectifyInflation, + #[cfg(feature = "protocol_feature_evm")] + EVM, } /// Current latest stable version of the protocol. @@ -88,7 +90,7 @@ pub const PROTOCOL_VERSION: ProtocolVersion = 41; /// Current latest nightly version of the protocol. #[cfg(feature = "nightly_protocol")] -pub const PROTOCOL_VERSION: ProtocolVersion = 43; +pub const PROTOCOL_VERSION: ProtocolVersion = 44; lazy_static! { static ref STABLE_PROTOCOL_FEATURES_TO_VERSION_MAPPING: HashMap = vec![ @@ -116,6 +118,8 @@ lazy_static! { (ProtocolFeature::ForwardChunkParts, 42), #[cfg(feature = "protocol_feature_rectify_inflation")] (ProtocolFeature::RectifyInflation, 43), + #[cfg(feature = "protocol_feature_evm")] + (ProtocolFeature::EVM, 44), ] .into_iter() .collect(); diff --git a/core/primitives/src/views.rs b/core/primitives/src/views.rs index 9edcf513f40..37c7701846f 100644 --- a/core/primitives/src/views.rs +++ b/core/primitives/src/views.rs @@ -75,6 +75,9 @@ pub struct ViewApplyState { pub current_protocol_version: ProtocolVersion, /// Cache for compiled contracts. pub cache: Option>, + /// EVM chain ID + #[cfg(feature = "protocol_feature_evm")] + pub evm_chain_id: u128, } impl From<&Account> for AccountView { @@ -186,7 +189,9 @@ pub struct ViewStateResult { pub proof: TrieProofPath, } -#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] +#[derive( + BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default, +)] pub struct CallResult { pub result: Vec, pub logs: Vec, @@ -308,6 +313,17 @@ impl TryFrom for AccountView { } } +impl TryFrom for CallResult { + type Error = String; + + fn try_from(query_response: QueryResponse) -> Result { + match query_response.kind { + QueryResponseKind::CallResult(res) => Ok(res), + _ => Err("Invalid type of response".into()), + } + } +} + impl TryFrom for ViewStateResult { type Error = String; diff --git a/deny.toml b/deny.toml index 3fb24bc3232..b0ad139e573 100644 --- a/deny.toml +++ b/deny.toml @@ -7,7 +7,19 @@ targets = [ [bans] multiple-versions = "deny" deny = [ + # See: https://github.com/rust-random/rand/issues/645 + { name = "rand", version = "<0.6" }, + + # See: https://github.com/near/nearcore/pull/3595 + { name = "ethabi", version = "<9.0.1" }, + { name = "ethabi-contract", version = "<9.0.0" }, + { name = "ethabi-derive", version = "<9.0.1" }, + { name = "ethereum-types", version = "<0.8.0" }, + { name = "keccak-hash", version = "<0.4.1" }, + { name = "primitive-types", version = "<0.6.2" }, + { name = "uint", version = "<0.8.2" }, ] + skip = [ # actix 0.9.0 still uses it { name = "tokio-util", version = "=0.2.0" }, @@ -39,16 +51,42 @@ skip = [ { name = "rand_core", version = "=0.4.2" }, # wasmer 0.17 and wasmtime 0.17 uses older versions of some crates { name = "sha2", version = "=0.8.1" }, - { name = "digest", version = "=0.8.1" }, { name = "crypto-mac", version = "=0.7.0" }, { name = "block-padding", version = "=0.1.5" }, { name = "block-buffer", version = "=0.7.3" }, { name = "opaque-debug", version = "=0.2.3" }, { name = "generic-array", version = "=0.12.3" }, + # `sha2` uses it + { name = "cfg-if", version = "=1.0.0" }, + # rosetta-rpc pull paperclip which introduce the following duplicates (https://github.com/wafflespeanut/paperclip/pull/209) { name = "url", version = "=1.7.2" }, { name = "idna", version = "=0.1.5" }, { name = "semver", version = "=0.9.0" }, { name = "percent-encoding", version = "=1.0.1" }, + + # evm support has some legacy. Updating it fails at this point. + # to fully update, need to fork half of parity libraries, as they stopped development. + # See: https://github.com/near/nearcore/issues/3506 + { name = "digest", version = "=0.8.1" }, + { name = "elastic-array", version = "=0.10.3" }, + { name = "impl-serde", version = "=0.2.3" }, + { name = "num-bigint", version = "=0.2.6" }, + { name = "parking_lot", version = "=0.11.0" }, + { name = "parking_lot_core", version = "=0.6.2" }, + { name = "proc-macro2", version = "=0.4.30" }, + { name = "quote", version = "=0.6.13" }, + { name = "rustc-hex", version = "=1.0.0" }, + { name = "smallvec", version = "=0.6.13" }, + { name = "syn", version = "=0.15.44" }, + { name = "unicode-xid", version = "=0.1.0" }, + { name = "primitive-types", version = "=0.6.2" }, + { name = "fixed-hash", version = "=0.5.2" }, + + # param estimator uses newer imports, but it's not part of neard + { name = "indicatif", version = "=0.15.0" }, + { name = "num-rational", version = "=0.3.0" }, + { name = "rand_xorshift", version = "=0.2.0" }, + { name = "wasmparser", version = "=0.59.0" }, ] diff --git a/genesis-tools/genesis-csv-to-json/Cargo.toml b/genesis-tools/genesis-csv-to-json/Cargo.toml index 189d900c0c2..c59815d912b 100644 --- a/genesis-tools/genesis-csv-to-json/Cargo.toml +++ b/genesis-tools/genesis-csv-to-json/Cargo.toml @@ -16,6 +16,7 @@ near-crypto = { path = "../../core/crypto" } near-primitives = { path = "../../core/primitives" } node-runtime = { path = "../../runtime/runtime" } near-network = { path = "../../chain/network" } +near-runtime-utils = { path = "../../runtime/near-runtime-utils" } [dev-dependencies] tempfile = "3" diff --git a/genesis-tools/genesis-csv-to-json/src/csv_parser.rs b/genesis-tools/genesis-csv-to-json/src/csv_parser.rs index d18077c7884..622de64c98a 100644 --- a/genesis-tools/genesis-csv-to-json/src/csv_parser.rs +++ b/genesis-tools/genesis-csv-to-json/src/csv_parser.rs @@ -15,7 +15,7 @@ use near_primitives::receipt::{ActionReceipt, Receipt, ReceiptEnum}; use near_primitives::state_record::StateRecord; use near_primitives::transaction::{Action, FunctionCallAction}; use near_primitives::types::{AccountId, AccountInfo, Balance, Gas}; -use near_primitives::utils::is_valid_account_id; +use near_runtime_utils::is_valid_account_id; /// Methods that can be called by a non-privileged access key. const REGULAR_METHOD_NAMES: &[&str] = &["stake", "transfer"]; diff --git a/neard/Cargo.toml b/neard/Cargo.toml index b8df5893bcc..c17783e6f18 100644 --- a/neard/Cargo.toml +++ b/neard/Cargo.toml @@ -61,7 +61,8 @@ delay_detector = ["near-client/delay_detector"] rosetta_rpc = ["near-rosetta-rpc"] protocol_feature_forward_chunk_parts = ["near-client/protocol_feature_forward_chunk_parts"] protocol_feature_rectify_inflation = ["near-epoch-manager/protocol_feature_rectify_inflation"] -nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protocol_features", "near-client/nightly_protocol_features", "near-epoch-manager/nightly_protocol_features", "near-store/nightly_protocol_features", "protocol_feature_forward_chunk_parts", "protocol_feature_rectify_inflation"] +protocol_feature_evm = ["near-primitives/protocol_feature_evm", "node-runtime/protocol_feature_evm", "near-chain-configs/protocol_feature_evm", "near-chain/protocol_feature_evm"] +nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protocol_features", "near-client/nightly_protocol_features", "near-epoch-manager/nightly_protocol_features", "near-store/nightly_protocol_features", "protocol_feature_forward_chunk_parts", "protocol_feature_rectify_inflation", "protocol_feature_evm"] nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_protocol"] [[bin]] diff --git a/neard/src/config.rs b/neard/src/config.rs index 23317a4cb3d..5b64895c137 100644 --- a/neard/src/config.rs +++ b/neard/src/config.rs @@ -129,6 +129,9 @@ pub const MINIMUM_STAKE_DIVISOR: u64 = 10; /// Number of epochs before protocol upgrade. pub const PROTOCOL_UPGRADE_NUM_EPOCHS: EpochHeight = 2; +#[cfg(feature = "protocol_feature_evm")] +pub const TEST_EVM_CHAIN_ID: u128 = 0x99; + pub const CONFIG_FILENAME: &str = "config.json"; pub const GENESIS_CONFIG_FILENAME: &str = "genesis.json"; pub const NODE_KEY_FILE: &str = "node_key.json"; @@ -475,16 +478,13 @@ impl Genesis { amount: TESTING_INIT_STAKE, }); } - records.extend( - state_records_account_with_key( - account, - &signer.public_key.clone(), - TESTING_INIT_BALANCE - - if i < num_validator_seats { TESTING_INIT_STAKE } else { 0 }, - if i < num_validator_seats { TESTING_INIT_STAKE } else { 0 }, - CryptoHash::default(), - ) - .into_iter(), + add_account_with_key( + &mut records, + account, + &signer.public_key.clone(), + TESTING_INIT_BALANCE - if i < num_validator_seats { TESTING_INIT_STAKE } else { 0 }, + if i < num_validator_seats { TESTING_INIT_STAKE } else { 0 }, + CryptoHash::default(), ); } add_protocol_account(&mut records); @@ -678,37 +678,37 @@ fn add_protocol_account(records: &mut Vec) { KeyType::ED25519, PROTOCOL_TREASURY_ACCOUNT, ); - records.extend(state_records_account_with_key( + add_account_with_key( + records, PROTOCOL_TREASURY_ACCOUNT, &signer.public_key, TESTING_INIT_BALANCE, 0, CryptoHash::default(), - )); + ); } fn random_chain_id() -> String { format!("test-chain-{}", generate_random_string(5)) } -fn state_records_account_with_key( +fn add_account_with_key( + records: &mut Vec, account_id: &str, public_key: &PublicKey, amount: u128, staked: u128, code_hash: CryptoHash, -) -> Vec { - vec![ - StateRecord::Account { - account_id: account_id.to_string(), - account: Account { amount, locked: staked, code_hash, storage_usage: 0 }, - }, - StateRecord::AccessKey { - account_id: account_id.to_string(), - public_key: public_key.clone(), - access_key: AccessKey::full_access(), - }, - ] +) { + records.push(StateRecord::Account { + account_id: account_id.to_string(), + account: Account { amount, locked: staked, code_hash, storage_usage: 0 }, + }); + records.push(StateRecord::AccessKey { + account_id: account_id.to_string(), + public_key: public_key.clone(), + access_key: AccessKey::full_access(), + }); } /// Generate a validator key and save it to the file path. @@ -827,13 +827,26 @@ pub fn init_configs( let network_signer = InMemorySigner::from_random("".to_string(), KeyType::ED25519); network_signer.write_to_file(&dir.join(config.node_key_file)); - let mut records = state_records_account_with_key( + let mut records = vec![]; + add_account_with_key( + &mut records, &account_id, &signer.public_key(), TESTING_INIT_BALANCE, TESTING_INIT_STAKE, CryptoHash::default(), ); + #[cfg(feature = "protocol_feature_evm")] + // EVM account is created here only for new generated genesis + // For existing network, evm account has to be created with linkdrop + add_account_with_key( + &mut records, + "evm", + &signer.public_key(), + TESTING_INIT_BALANCE, + 0, + CryptoHash::default(), + ); add_protocol_account(&mut records); let genesis_config = GenesisConfig { diff --git a/neard/src/runtime.rs b/neard/src/runtime.rs index 1b43285fed9..f1562416508 100644 --- a/neard/src/runtime.rs +++ b/neard/src/runtime.rs @@ -14,6 +14,8 @@ use near_chain::chain::NUM_EPOCHS_TO_KEEP_STORE_DATA; use near_chain::types::{ApplyTransactionResult, BlockHeaderInfo}; use near_chain::{BlockHeader, Error, ErrorKind, RuntimeAdapter}; use near_chain_configs::{Genesis, GenesisConfig}; +#[cfg(feature = "protocol_feature_evm")] +use near_chain_configs::{MAINNET_EVM_CHAIN_ID, TEST_EVM_CHAIN_ID}; use near_crypto::{PublicKey, Signature}; use near_epoch_manager::{EpochManager, RewardCalculator}; use near_pool::types::PoolIterator; @@ -452,6 +454,8 @@ impl NightshadeRuntime { current_protocol_version, ), cache: Some(Arc::new(StoreCompiledContractCache { store: self.store.clone() })), + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: self.evm_chain_id(), }; let apply_result = self @@ -1155,6 +1159,8 @@ impl RuntimeAdapter for NightshadeRuntime { &mut logs, &self.epoch_manager, current_protocol_version, + #[cfg(feature = "protocol_feature_evm")] + self.evm_chain_id(), ) { Ok(result) => Ok(QueryResponse { kind: QueryResponseKind::CallResult(CallResult { result, logs }), @@ -1250,8 +1256,8 @@ impl RuntimeAdapter for NightshadeRuntime { Ok(partial_state) => partial_state, Err(e) => { error!(target: "runtime", - "Can't get_trie_nodes_for_part for {:?}, part_id {:?}, num_parts {:?}, {:?}", - state_root, part_id, num_parts, e + "Can't get_trie_nodes_for_part for {:?}, part_id {:?}, num_parts {:?}, {:?}", + state_root, part_id, num_parts, e ); return Err(e.to_string().into()); } @@ -1372,6 +1378,15 @@ impl RuntimeAdapter for NightshadeRuntime { && chunk_next_epoch_id != head_epoch_id && chunk_epoch_id != head_next_epoch_id) } + + #[cfg(feature = "protocol_feature_evm")] + /// ID of the EVM chain: https://github.com/ethereum-lists/chains + fn evm_chain_id(&self) -> u128 { + match self.genesis_config.chain_id.as_str() { + "mainnet" => MAINNET_EVM_CHAIN_ID, + _ => TEST_EVM_CHAIN_ID, + } + } } impl node_runtime::adapter::ViewRuntimeAdapter for NightshadeRuntime { @@ -1400,6 +1415,7 @@ impl node_runtime::adapter::ViewRuntimeAdapter for NightshadeRuntime { logs: &mut Vec, epoch_info_provider: &dyn EpochInfoProvider, current_protocol_version: ProtocolVersion, + #[cfg(feature = "protocol_feature_evm")] evm_chain_id: u128, ) -> Result, Box> { let state_update = self.get_tries().new_trie_update_view(shard_id, state_root); let view_state = ViewApplyState { @@ -1410,10 +1426,12 @@ impl node_runtime::adapter::ViewRuntimeAdapter for NightshadeRuntime { block_timestamp, current_protocol_version, cache: Some(Arc::new(StoreCompiledContractCache { store: self.tries.get_store() })), + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id, }; self.trie_viewer.call_function( state_update, - &view_state, + view_state, contract_id, method_name, args, diff --git a/nightly/nightly.txt b/nightly/nightly.txt index a6dfdbb044f..0e058a10bca 100644 --- a/nightly/nightly.txt +++ b/nightly/nightly.txt @@ -145,6 +145,7 @@ expensive nearcore test_cases_testnet_rpc test::test_delete_access_key_testnet expensive nearcore test_cases_testnet_rpc test::test_add_access_key_with_allowance_testnet expensive nearcore test_cases_testnet_rpc test::test_delete_access_key_with_allowance_testnet expensive nearcore test_cases_testnet_rpc test::test_access_key_smart_contract_testnet +expensive nearcore test_cases_testnet_rpc test::test_evm_deploy_call_testnet # GC tests expensive --timeout=900 near-chain gc tests::test_gc_remove_fork_large diff --git a/runtime/near-evm-runner/Cargo.toml b/runtime/near-evm-runner/Cargo.toml new file mode 100644 index 00000000000..48254ace63f --- /dev/null +++ b/runtime/near-evm-runner/Cargo.toml @@ -0,0 +1,61 @@ +[package] +name = "near-evm-runner" +version = "2.2.0" +authors = ["Near Inc "] +edition = "2018" +license = "Apache-2.0" +repository = "https://github.com/nearprotocol/nearcore" +homepage = "https://github.com/nearprotocol/nearcore" + +[dependencies] +borsh = "0.7.1" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1" +hex = "0.4" +byteorder = "1.0" +num-bigint = { version = "0.3", default-features = false } +num-traits = "0.2.12" +enum-primitive-derive = "0.2" + +sha2 = ">=0.8,<0.10" +sha3 = "0.9" +rlp = "0.4.2" +keccak-hash = "0.4.1" +ripemd160 = "0.9.0" +libsecp256k1 = "0.3.5" + +evm = { git = "https://github.com/openethereum/openethereum", rev = "v2.7.2" } +vm = { git = "https://github.com/openethereum/openethereum", rev = "v2.7.2" } +bn = { git = "https://github.com/near/bn", rev = "43953916ed1a314b78320771734f36af77993dd9" } +parity-bytes = "0.1.0" +ethereum-types = "0.8.0" + +near-vm-logic = { path = "../near-vm-logic" } +near-vm-errors = { path = "../near-vm-errors" } +near-runtime-utils = { path = "../near-runtime-utils" } +near-runtime-fees = { path = "../near-runtime-fees" } + +derivative = "2.1.1" + +[dev-dependencies] +ethabi = "9.0.1" +ethabi-contract = "9.0.0" +ethabi-derive = "9.0.1" +lazy_static = "1.4" +lazy-static-include = "2.2.2" + +near-crypto = { path = "../../core/crypto" } + +[features] +costs_counting = [] +protocol_feature_evm = ["near-runtime-fees/protocol_feature_evm", "near-vm-logic/protocol_feature_evm"] + +[[test]] +name = "failures" +path = "tests/failures.rs" +required-features = ["protocol_feature_evm"] + +[[test]] +name = "standard_ops" +path = "tests/standard_ops.rs" +required-features = ["protocol_feature_evm"] diff --git a/runtime/near-evm-runner/src/builtins.rs b/runtime/near-evm-runner/src/builtins.rs new file mode 100644 index 00000000000..f5b4571f827 --- /dev/null +++ b/runtime/near-evm-runner/src/builtins.rs @@ -0,0 +1,648 @@ +use std::{ + cmp::{max, min}, + io::{self, Cursor, Read}, + mem::size_of, +}; + +use crate::pricer::{ + AltBn128PairingPrice, AltBn128PairingPricer, Bls12ConstOperations, Linear, ModexpPricer, + Pricer, Pricing, +}; +use crate::utils::ecrecover_address; +use byteorder::{BigEndian, ByteOrder, LittleEndian, ReadBytesExt}; + +use ethereum_types::{Address, U256}; +use near_runtime_fees::EvmPrecompileCostConfig; +use num_bigint::BigUint; +use num_traits::{FromPrimitive, One, ToPrimitive, Zero}; +use parity_bytes::BytesRef; +use vm::{MessageCallResult, ReturnData}; + +#[derive(Primitive)] +enum Precompile { + EcRecover = 1, + Sha256 = 2, + Ripemd160 = 3, + Identity = 4, + ModexpImpl = 5, + Bn128AddImpl = 6, + Bn128MulImpl = 7, + Bn128PairingImpl = 8, + Blake2FImpl = 9, + LastPrecompile = 10, +} + +pub fn is_precompile(addr: &Address) -> bool { + *addr < Address::from_low_u64_be(Precompile::LastPrecompile.to_u64().unwrap()) +} + +pub fn precompile(id: u64) -> Result, String> { + Ok(match Precompile::from_u64(id) { + Some(Precompile::EcRecover) => Box::new(EcRecover) as Box, + Some(Precompile::Sha256) => Box::new(Sha256) as Box, + Some(Precompile::Ripemd160) => Box::new(Ripemd160) as Box, + Some(Precompile::Identity) => Box::new(Identity) as Box, + Some(Precompile::ModexpImpl) => Box::new(ModexpImpl) as Box, + Some(Precompile::Bn128AddImpl) => Box::new(Bn128AddImpl) as Box, + Some(Precompile::Bn128MulImpl) => Box::new(Bn128MulImpl) as Box, + Some(Precompile::Bn128PairingImpl) => Box::new(Bn128PairingImpl) as Box, + Some(Precompile::Blake2FImpl) => Box::new(Blake2FImpl) as Box, + _ => return Err(format!("Invalid builtin ID: {}", id)), + }) +} + +pub fn process_precompile( + addr: &Address, + input: &[u8], + gas: &U256, + precompile_costs: &EvmPrecompileCostConfig, +) -> MessageCallResult { + let f = match precompile(addr.to_low_u64_be()) { + Ok(f) => f, + Err(_) => return MessageCallResult::Failed, + }; + let mut bytes = vec![]; + let mut output = parity_bytes::BytesRef::Flexible(&mut bytes); + let cost = f.gas(input, precompile_costs); + + if cost > *gas { + return MessageCallResult::Failed; + } + + // mutates bytes + match f.execute(input, &mut output) { + Ok(()) => {} + Err(_) => return MessageCallResult::Failed, + }; + let size = bytes.len(); + + MessageCallResult::Success(*gas - cost, ReturnData::new(bytes, 0, size)) +} + +/** the following is copied from ethcore/src/builtin.rs **/ + +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Ethereum. If not, see . + +/// Execution error. +#[derive(Debug)] +pub struct Error(pub &'static str); + +impl From<&'static str> for Error { + fn from(val: &'static str) -> Self { + Error(val) + } +} + +impl Into for Error { + fn into(self) -> ::vm::Error { + vm::Error::BuiltIn(self.0) + } +} +#[derive(Debug)] +struct EcRecover; + +#[derive(Debug)] +struct Sha256; + +#[derive(Debug)] +struct Ripemd160; + +#[derive(Debug)] +struct Identity; + +#[derive(Debug)] +struct ModexpImpl; + +#[derive(Debug)] +struct Bn128AddImpl; + +#[derive(Debug)] +struct Bn128MulImpl; + +#[derive(Debug)] +struct Bn128PairingImpl; + +#[derive(Debug)] +pub struct Blake2FImpl; + +/// Native implementation of a built-in contract. +pub trait Impl: Send + Sync { + /// execute this built-in on the given input, writing to the given output. + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error>; + // how many evm gas will cost + fn gas(&self, _input: &[u8], _evm_gas_config: &EvmPrecompileCostConfig) -> U256; +} + +impl Impl for Identity { + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + output.write(0, input); + Ok(()) + } + fn gas(&self, input: &[u8], precompile_costs: &EvmPrecompileCostConfig) -> U256 { + Pricing::Linear(Linear { + base: precompile_costs.identity_cost.base, + word: precompile_costs.identity_cost.word, + }) + .cost(input) + } +} + +impl Impl for EcRecover { + fn execute(&self, i: &[u8], output: &mut BytesRef) -> Result<(), Error> { + let len = min(i.len(), 128); + + let mut input = [0; 128]; + input[..len].copy_from_slice(&i[..len]); + let mut hash = [0; 32]; + hash.copy_from_slice(&input[..32]); + let mut signature = [0; 65]; + signature.copy_from_slice(&input[63..]); + + let result = ecrecover_address(&hash, &signature); + output.write(0, &[0, 12]); + output.write(12, &result.0); + + Ok(()) + } + + fn gas(&self, input: &[u8], precompile_costs: &EvmPrecompileCostConfig) -> U256 { + Pricing::Linear(Linear { + base: precompile_costs.ecrecover_cost.base, + word: precompile_costs.ecrecover_cost.word, + }) + .cost(input) + } +} + +impl Impl for Sha256 { + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + use sha2::Digest; + let d = sha2::Sha256::digest(input); + output.write(0, &*d); + Ok(()) + } + + fn gas(&self, input: &[u8], precompile_costs: &EvmPrecompileCostConfig) -> U256 { + Pricing::Linear(Linear { + base: precompile_costs.sha256_cost.base, + word: precompile_costs.sha256_cost.word, + }) + .cost(input) + } +} + +impl Impl for Ripemd160 { + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + use ripemd160::Digest; + let hash = ripemd160::Ripemd160::digest(input); + output.write(0, &[0; 12][..]); + output.write(12, &hash); + Ok(()) + } + + fn gas(&self, input: &[u8], precompile_costs: &EvmPrecompileCostConfig) -> U256 { + Pricing::Linear(Linear { + base: precompile_costs.ripemd160_cost.base, + word: precompile_costs.ripemd160_cost.word, + }) + .cost(input) + } +} + +// calculate modexp: left-to-right binary exponentiation to keep multiplicands lower +fn modexp(mut base: BigUint, exp: Vec, modulus: BigUint) -> BigUint { + const BITS_PER_DIGIT: usize = 8; + + // n^m % 0 || n^m % 1 + if modulus <= BigUint::one() { + return BigUint::zero(); + } + + // normalize exponent + let mut exp = exp.into_iter().skip_while(|d| *d == 0).peekable(); + + // n^0 % m + if exp.peek().is_none() { + return BigUint::one(); + } + + // 0^n % m, n > 0 + if base.is_zero() { + return BigUint::zero(); + } + + base %= &modulus; + + // Fast path for base divisible by modulus. + if base.is_zero() { + return BigUint::zero(); + } + + // Left-to-right binary exponentiation (Handbook of Applied Cryptography - Algorithm 14.79). + // http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf + let mut result = BigUint::one(); + + for digit in exp { + let mut mask = 1 << (BITS_PER_DIGIT - 1); + + for _ in 0..BITS_PER_DIGIT { + result = &result * &result % &modulus; + + if digit & mask > 0 { + result = result * &base % &modulus; + } + + mask >>= 1; + } + } + + result +} + +impl Impl for ModexpImpl { + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + let mut reader = input.chain(io::repeat(0)); + let mut buf = [0; 32]; + + // read lengths as usize. + // ignoring the first 24 bytes might technically lead us to fall out of consensus, + // but so would running out of addressable memory! + let mut read_len = |reader: &mut io::Chain<&[u8], io::Repeat>| { + reader + .read_exact(&mut buf[..]) + .expect("reading from zero-extended memory cannot fail; qed"); + BigEndian::read_u64(&buf[24..]) as usize + }; + + let base_len = read_len(&mut reader); + let exp_len = read_len(&mut reader); + let mod_len = read_len(&mut reader); + + // Gas formula allows arbitrary large exp_len when base and modulus are empty, so we need to handle empty base first. + let r = if base_len == 0 && mod_len == 0 { + BigUint::zero() + } else { + // read the numbers themselves. + let mut buf = vec![0; max(mod_len, max(base_len, exp_len))]; + let mut read_num = |reader: &mut io::Chain<&[u8], io::Repeat>, len: usize| { + reader + .read_exact(&mut buf[..len]) + .expect("reading from zero-extended memory cannot fail; qed"); + BigUint::from_bytes_be(&buf[..len]) + }; + + let base = read_num(&mut reader, base_len); + + let mut exp_buf = vec![0; exp_len]; + reader + .read_exact(&mut exp_buf[..exp_len]) + .expect("reading from zero-extended memory cannot fail; qed"); + + let modulus = read_num(&mut reader, mod_len); + + modexp(base, exp_buf, modulus) + }; + + // write output to given memory, left padded and same length as the modulus. + let bytes = r.to_bytes_be(); + + // always true except in the case of zero-length modulus, which leads to + // output of length and value 1. + if bytes.len() <= mod_len { + let res_start = mod_len - bytes.len(); + output.write(res_start, &bytes); + } + + Ok(()) + } + + fn gas(&self, input: &[u8], precompile_costs: &EvmPrecompileCostConfig) -> U256 { + Pricing::Modexp(ModexpPricer { divisor: precompile_costs.modexp_cost.divisor }).cost(input) + } +} + +fn read_fr(reader: &mut io::Chain<&[u8], io::Repeat>) -> Result<::bn::Fr, Error> { + let mut buf = [0u8; 32]; + + reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed"); + ::bn::Fr::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid field element")) +} + +fn read_point(reader: &mut io::Chain<&[u8], io::Repeat>) -> Result<::bn::G1, Error> { + use bn::{AffineG1, Fq, Group, G1}; + + let mut buf = [0u8; 32]; + + reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed"); + let px = Fq::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid point x coordinate"))?; + + reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed"); + let py = Fq::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid point y coordinate"))?; + Ok(if px == Fq::zero() && py == Fq::zero() { + G1::zero() + } else { + AffineG1::new(px, py).map_err(|_| Error::from("Invalid curve point"))?.into() + }) +} + +impl Impl for Bn128AddImpl { + // Can fail if any of the 2 points does not belong the bn128 curve + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + use bn::AffineG1; + + let mut padded_input = input.chain(io::repeat(0)); + let p1 = read_point(&mut padded_input)?; + let p2 = read_point(&mut padded_input)?; + + let mut write_buf = [0u8; 64]; + if let Some(sum) = AffineG1::from_jacobian(p1 + p2) { + // point not at infinity + sum.x() + .to_big_endian(&mut write_buf[0..32]) + .expect("Cannot fail since 0..32 is 32-byte length"); + sum.y() + .to_big_endian(&mut write_buf[32..64]) + .expect("Cannot fail since 32..64 is 32-byte length"); + } + output.write(0, &write_buf); + + Ok(()) + } + + fn gas(&self, input: &[u8], precompile_costs: &EvmPrecompileCostConfig) -> U256 { + Pricing::Bls12ConstOperations(Bls12ConstOperations { + price: precompile_costs.bn128_add_cost.price, + }) + .cost(input) + } +} + +impl Impl for Bn128MulImpl { + // Can fail if first paramter (bn128 curve point) does not actually belong to the curve + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + use bn::AffineG1; + + let mut padded_input = input.chain(io::repeat(0)); + let p = read_point(&mut padded_input)?; + let fr = read_fr(&mut padded_input)?; + + let mut write_buf = [0u8; 64]; + if let Some(sum) = AffineG1::from_jacobian(p * fr) { + // point not at infinity + sum.x() + .to_big_endian(&mut write_buf[0..32]) + .expect("Cannot fail since 0..32 is 32-byte length"); + sum.y() + .to_big_endian(&mut write_buf[32..64]) + .expect("Cannot fail since 32..64 is 32-byte length"); + } + output.write(0, &write_buf); + Ok(()) + } + + fn gas(&self, input: &[u8], precompile_costs: &EvmPrecompileCostConfig) -> U256 { + Pricing::Bls12ConstOperations(Bls12ConstOperations { + price: precompile_costs.bn128_mul_cost.price, + }) + .cost(input) + } +} + +impl Impl for Bn128PairingImpl { + /// Can fail if: + /// - input length is not a multiple of 192 + /// - any of odd points does not belong to bn128 curve + /// - any of even points does not belong to the twisted bn128 curve over the field F_p^2 = F_p[i] / (i^2 + 1) + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + if input.len() % 192 != 0 { + return Err("Invalid input length, must be multiple of 192 (3 * (32*2))".into()); + } + + self.execute_with_error(input, output) + } + + fn gas(&self, input: &[u8], precompile_costs: &EvmPrecompileCostConfig) -> U256 { + Pricing::AltBn128Pairing(AltBn128PairingPricer { + price: AltBn128PairingPrice { + base: precompile_costs.bn128_pairing_cost.base, + pair: precompile_costs.bn128_pairing_cost.pair, + }, + }) + .cost(input) + } +} + +impl Bn128PairingImpl { + fn execute_with_error(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + use bn::{pairing, AffineG1, AffineG2, Fq, Fq2, Group, Gt, G1, G2}; + + let elements = input.len() / 192; // (a, b_a, b_b - each 64-byte affine coordinates) + let ret_val = if elements == 0 { + U256::one() + } else { + let mut vals = Vec::new(); + for idx in 0..elements { + let a_x = Fq::from_slice(&input[idx * 192..idx * 192 + 32]) + .map_err(|_| Error::from("Invalid a argument x coordinate"))?; + + let a_y = Fq::from_slice(&input[idx * 192 + 32..idx * 192 + 64]) + .map_err(|_| Error::from("Invalid a argument y coordinate"))?; + + let b_a_y = Fq::from_slice(&input[idx * 192 + 64..idx * 192 + 96]) + .map_err(|_| Error::from("Invalid b argument imaginary coeff x coordinate"))?; + + let b_a_x = Fq::from_slice(&input[idx * 192 + 96..idx * 192 + 128]) + .map_err(|_| Error::from("Invalid b argument imaginary coeff y coordinate"))?; + + let b_b_y = Fq::from_slice(&input[idx * 192 + 128..idx * 192 + 160]) + .map_err(|_| Error::from("Invalid b argument real coeff x coordinate"))?; + + let b_b_x = Fq::from_slice(&input[idx * 192 + 160..idx * 192 + 192]) + .map_err(|_| Error::from("Invalid b argument real coeff y coordinate"))?; + + let b_a = Fq2::new(b_a_x, b_a_y); + let b_b = Fq2::new(b_b_x, b_b_y); + let b = if b_a.is_zero() && b_b.is_zero() { + G2::zero() + } else { + G2::from( + AffineG2::new(b_a, b_b) + .map_err(|_| Error::from("Invalid b argument - not on curve"))?, + ) + }; + let a = if a_x.is_zero() && a_y.is_zero() { + G1::zero() + } else { + G1::from( + AffineG1::new(a_x, a_y) + .map_err(|_| Error::from("Invalid a argument - not on curve"))?, + ) + }; + vals.push((a, b)); + } + + let mul = vals.into_iter().fold(Gt::one(), |s, (a, b)| s * pairing(a, b)); + + if mul == Gt::one() { + U256::one() + } else { + U256::zero() + } + }; + + let mut buf = [0u8; 32]; + ret_val.to_big_endian(&mut buf); + output.write(0, &buf); + + Ok(()) + } +} + +/// The precomputed values for BLAKE2b [from the spec](https://tools.ietf.org/html/rfc7693#section-2.7) +/// There are 10 16-byte arrays - one for each round +/// the entries are calculated from the sigma constants. +const SIGMA: [[usize; 16]; 10] = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], + [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], + [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], + [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], + [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], + [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], + [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], + [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], + [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], +]; + +/// IV is the initialization vector for BLAKE2b. See https://tools.ietf.org/html/rfc7693#section-2.6 +/// for details. +const IV: [u64; 8] = [ + 0x6a09e667f3bcc908, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, +]; + +#[inline(always)] +#[allow(clippy::many_single_char_names)] +fn g(v: &mut [u64], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { + v[a] = v[a].wrapping_add(v[b]).wrapping_add(x); + v[d] = (v[d] ^ v[a]).rotate_right(32); + v[c] = v[c].wrapping_add(v[d]); + v[b] = (v[b] ^ v[c]).rotate_right(24); + + v[a] = v[a].wrapping_add(v[b]).wrapping_add(y); + v[d] = (v[d] ^ v[a]).rotate_right(16); + v[c] = v[c].wrapping_add(v[d]); + v[b] = (v[b] ^ v[c]).rotate_right(63); +} + +/// The Blake2b compression function F. See https://tools.ietf.org/html/rfc7693#section-3.2 +/// Takes as an argument the state vector `h`, message block vector `m`, offset counter `t`, final +/// block indicator flag `f`, and number of rounds `rounds`. The state vector provided as the first +/// parameter is modified by the function. +#[allow(clippy::many_single_char_names)] +pub fn compress(h: &mut [u64; 8], m: [u64; 16], t: [u64; 2], f: bool, rounds: usize) { + let mut v = [0u64; 16]; + v[..8].copy_from_slice(h); // First half from state. + v[8..].copy_from_slice(&IV); // Second half from IV. + + v[12] ^= t[0]; + v[13] ^= t[1]; + + if f { + v[14] = !v[14]; // Invert all bits if the last-block-flag is set. + } + + for i in 0..rounds { + // Message word selection permutation for this round. + let s = &SIGMA[i % 10]; + g(&mut v, 0, 4, 8, 12, m[s[0]], m[s[1]]); + g(&mut v, 1, 5, 9, 13, m[s[2]], m[s[3]]); + g(&mut v, 2, 6, 10, 14, m[s[4]], m[s[5]]); + g(&mut v, 3, 7, 11, 15, m[s[6]], m[s[7]]); + + g(&mut v, 0, 5, 10, 15, m[s[8]], m[s[9]]); + g(&mut v, 1, 6, 11, 12, m[s[10]], m[s[11]]); + g(&mut v, 2, 7, 8, 13, m[s[12]], m[s[13]]); + g(&mut v, 3, 4, 9, 14, m[s[14]], m[s[15]]); + } + + for i in 0..8 { + h[i] ^= v[i] ^ v[i + 8]; + } +} + +impl Impl for Blake2FImpl { + /// Format of `input`: + /// [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] + fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> { + const BLAKE2_F_ARG_LEN: usize = 213; + const PROOF: &str = "Checked the length of the input above; qed"; + + if input.len() != BLAKE2_F_ARG_LEN { + return Err(Error("input length for Blake2 F precompile should be exactly 213 bytes")); + } + + let mut cursor = Cursor::new(input); + let rounds = cursor.read_u32::().expect(PROOF); + + // state vector, h + let mut h = [0u64; 8]; + for state_word in &mut h { + *state_word = cursor.read_u64::().expect(PROOF); + } + + // message block vector, m + let mut m = [0u64; 16]; + for msg_word in &mut m { + *msg_word = cursor.read_u64::().expect(PROOF); + } + + // 2w-bit offset counter, t + let t = [ + cursor.read_u64::().expect(PROOF), + cursor.read_u64::().expect(PROOF), + ]; + + // final block indicator flag, "f" + let f = match input.last() { + Some(1) => true, + Some(0) => false, + _ => { + return Err(Error("incorrect final block indicator flag")); + } + }; + + compress(&mut h, m, t, f, rounds as usize); + + let mut output_buf = [0u8; 8 * size_of::()]; + for (i, state_word) in h.iter().enumerate() { + output_buf[i * 8..(i + 1) * 8].copy_from_slice(&state_word.to_le_bytes()); + } + output.write(0, &output_buf[..]); + Ok(()) + } + + fn gas(&self, input: &[u8], precompile_costs: &EvmPrecompileCostConfig) -> U256 { + Pricing::Blake2F(precompile_costs.blake2f_cost).cost(input) + } +} diff --git a/runtime/near-evm-runner/src/evm_state.rs b/runtime/near-evm-runner/src/evm_state.rs new file mode 100644 index 00000000000..1e419297f85 --- /dev/null +++ b/runtime/near-evm-runner/src/evm_state.rs @@ -0,0 +1,584 @@ +use std::collections::{HashMap, HashSet}; +use std::io::{Error, Write}; + +use borsh::{BorshDeserialize, BorshSerialize}; +use ethereum_types::{Address, U256}; + +use near_vm_errors::EvmError; +use near_vm_logic::VMLogicError; + +use crate::types::{DataKey, RawU256, Result}; +use crate::utils; +use crate::utils::split_data_key; + +#[derive(Default, Clone, Copy, Debug)] +pub struct EvmAccount { + pub balance: U256, + pub nonce: U256, +} + +impl BorshSerialize for EvmAccount { + fn serialize(&self, writer: &mut W) -> std::result::Result<(), Error> { + self.balance.0.serialize(writer)?; + self.nonce.0.serialize(writer) + } +} + +impl BorshDeserialize for EvmAccount { + fn deserialize(buf: &mut &[u8]) -> std::result::Result { + let balance = U256(<[u64; 4]>::deserialize(buf)?); + let nonce = U256(<[u64; 4]>::deserialize(buf)?); + Ok(Self { balance, nonce }) + } +} + +pub trait EvmState { + fn code_at(&self, address: &Address) -> Result>>; + fn set_code(&mut self, address: &Address, bytecode: &[u8]) -> Result<()>; + + fn get_account(&self, address: &Address) -> Result>; + fn set_account(&mut self, address: &Address, account: &EvmAccount) -> Result<()>; + + fn balance_of(&self, address: &Address) -> Result { + let account = self.get_account(address)?.unwrap_or_default(); + Ok(account.balance.into()) + } + + fn nonce_of(&self, address: &Address) -> Result { + let account = self.get_account(address)?.unwrap_or_default(); + Ok(account.nonce.into()) + } + + fn set_nonce(&mut self, address: &Address, nonce: U256) -> Result> { + let mut account = self.get_account(address)?.unwrap_or_default(); + account.nonce = nonce; + self.set_account(address, &account)?; + Ok(Some(account.nonce)) + } + + fn set_balance(&mut self, address: &Address, balance: U256) -> Result<()> { + let mut account = self.get_account(address)?.unwrap_or_default(); + account.balance = balance; + self.set_account(address, &account) + } + + fn next_nonce(&mut self, address: &Address) -> Result { + let mut account = self.get_account(address)?.unwrap_or_default(); + let nonce = account.nonce; + account.nonce = account + .nonce + .checked_add(U256::from(1)) + .ok_or_else(|| VMLogicError::EvmError(EvmError::IntegerOverflow))?; + self.set_account(address, &account)?; + Ok(nonce) + } + + fn _read_contract_storage(&self, key: &DataKey) -> Result>; + fn read_contract_storage(&self, address: &Address, key: &RawU256) -> Result> { + self._read_contract_storage(&utils::internal_storage_key(address, key)) + } + + fn _set_contract_storage(&mut self, key: &DataKey, value: RawU256) -> Result<()>; + + fn set_contract_storage( + &mut self, + address: &Address, + key: &RawU256, + value: RawU256, + ) -> Result<()> { + self._set_contract_storage(&utils::internal_storage_key(address, key), value) + } + + fn commit_changes(&mut self, other: &StateStore) -> Result<()>; + + fn add_balance(&mut self, address: &Address, incr: U256) -> Result<()> { + let mut account = self.get_account(address)?.unwrap_or_default(); + account.balance = account + .balance + .checked_add(incr) + .ok_or_else(|| VMLogicError::EvmError(EvmError::IntegerOverflow))?; + self.set_account(address, &account) + } + + fn sub_balance(&mut self, address: &Address, decr: U256) -> Result<()> { + let mut account = self.get_account(address)?.unwrap_or_default(); + account.balance = account + .balance + .checked_sub(decr) + .ok_or_else(|| VMLogicError::EvmError(EvmError::InsufficientFunds))?; + self.set_account(address, &account) + } + + fn transfer_balance( + &mut self, + sender: &Address, + recipient: &Address, + amnt: U256, + ) -> Result<()> { + self.sub_balance(sender, amnt)?; + self.add_balance(recipient, amnt) + } + + fn recreate(&mut self, address: Address); +} + +#[derive(Default, Debug)] +pub struct StateStore { + pub code: HashMap>, + pub accounts: HashMap, + pub storages: HashMap>, + pub logs: Vec, + pub self_destructs: HashSet
, + pub recreated: HashSet
, +} + +impl StateStore { + fn delete_from_storage(&mut self, addr: &Address) { + self.storages.remove(addr); + // let address_key = addr.0.to_vec(); + // // If address in the last, use RangeFrom to remove all elements until the end. + // let keys: Vec<_> = if addr.0 == [255; 20] { + // self.storages.range(std::ops::RangeFrom { start: address_key }) + // } else { + // let next_address = utils::safe_next_address(&addr.0); + // + // let range = ( + // std::ops::Bound::Excluded(address_key), + // std::ops::Bound::Excluded(next_address.to_vec()), + // ); + // + // self.storages.range(range) + // } + // .map(|(k, _)| k.clone()) + // .collect(); + // for k in keys.iter() { + // self.storages.remove(k); + // } + } + + pub fn commit_code(&mut self, other: &HashMap>) { + self.code.extend(other.iter().map(|(k, v)| (*k, v.clone()))); + } + + pub fn commit_accounts(&mut self, other: &HashMap) { + self.accounts.extend(other.iter().map(|(k, v)| (*k, *v))); + } + + pub fn commit_storages(&mut self, other: &HashMap>) { + for (address, values) in other.iter() { + if let Some(acc) = self.storages.get_mut(address) { + acc.extend(values.iter().map(|(k, v)| (k.clone(), *v))); + } else { + self.storages.insert(address.clone(), values.clone()); + } + } + } + + pub fn commit_self_destructs(&mut self, other: &HashSet
) { + self.self_destructs.extend(other); + } + + pub fn commit_recreated(&mut self, other: &HashSet
) { + self.recreated.extend(other); + } +} + +impl EvmState for StateStore { + fn code_at(&self, address: &Address) -> Result>> { + if self.self_destructs.contains(address) { + Ok(None) + } else { + Ok(self.code.get(address).cloned()) + } + } + + fn set_code(&mut self, address: &Address, bytecode: &[u8]) -> Result<()> { + self.code.insert(address.clone(), bytecode.to_vec()); + Ok(()) + } + + fn get_account(&self, address: &Address) -> Result> { + Ok(self.accounts.get(&address).map(|account| account.clone())) + } + + fn set_account(&mut self, address: &Address, account: &EvmAccount) -> Result<()> { + self.accounts.insert(address.clone(), account.clone()); + Ok(()) + } + + fn _read_contract_storage(&self, key: &DataKey) -> Result> { + let (addr, subkey) = split_data_key(&key); + if self.self_destructs.contains(&addr) { + Ok(None) + } else { + Ok(self.storages.get(&addr).and_then(|x| x.get(&subkey).cloned())) + } + } + + fn _set_contract_storage(&mut self, key: &DataKey, value: RawU256) -> Result<()> { + let (addr, subkey) = split_data_key(&key); + self.storages.entry(addr).or_insert_with(|| HashMap::default()).insert(subkey, value); + Ok(()) + } + + fn commit_changes(&mut self, other: &StateStore) -> Result<()> { + self.commit_self_destructs(&other.self_destructs); + self.commit_recreated(&other.recreated); + self.commit_code(&other.code); + self.commit_accounts(&other.accounts); + self.commit_storages(&other.storages); + self.logs.extend(other.logs.iter().cloned()); + Ok(()) + } + + fn recreate(&mut self, addr: Address) { + self.code.remove(&addr); + // We do not remove account because balances persist across recreation. + self.accounts.entry(addr).or_insert(EvmAccount::default()).nonce = U256::from(0); + self.delete_from_storage(&addr); + self.self_destructs.remove(&addr); + self.recreated.insert(addr); + } +} + +pub struct SubState<'a> { + pub msg_sender: &'a Address, + pub state: &'a mut StateStore, + pub parent: &'a dyn EvmState, +} + +impl SubState<'_> { + pub fn new<'a>( + msg_sender: &'a Address, + state: &'a mut StateStore, + parent: &'a dyn EvmState, + ) -> SubState<'a> { + SubState { msg_sender, state, parent } + } + + pub fn self_destruct(&mut self, address: &Address) -> Result<()> { + self.state.self_destructs.insert(address.clone()); + let mut account = self.get_account(address)?.unwrap_or_default(); + account.nonce = U256::from(0); + self.state.set_account(address, &account) + } +} + +impl EvmState for SubState<'_> { + fn code_at(&self, address: &Address) -> Result>> { + if self.state.self_destructs.contains(address) { + Ok(None) + } else { + self.state + .code + .get(&address) + .map_or_else(|| self.parent.code_at(address), |k| Ok(Some(k.to_vec()))) + } + } + + fn set_code(&mut self, address: &Address, bytecode: &[u8]) -> Result<()> { + self.state.code.insert(address.clone(), bytecode.to_vec()); + Ok(()) + } + + fn get_account(&self, address: &Address) -> Result> { + self.state + .get_account(address)? + .map_or_else(|| self.parent.get_account(address), |v| Ok(Some(v))) + } + + fn set_account(&mut self, address: &Address, account: &EvmAccount) -> Result<()> { + self.state.set_account(address, account) + } + + fn _read_contract_storage(&self, key: &DataKey) -> Result> { + let (addr, subkey) = split_data_key(&key); + if self.state.self_destructs.contains(&addr) { + Ok(None) + } else { + self.state + .storages + .get(&addr) + .and_then(|x| x.get(&subkey)) + .map_or_else(|| self.parent._read_contract_storage(&key), |v| Ok(Some(*v))) + } + } + + fn _set_contract_storage(&mut self, key: &DataKey, value: RawU256) -> Result<()> { + let (addr, subkey) = split_data_key(&key); + self.state.storages.entry(addr).or_default().insert(subkey, value); + Ok(()) + } + + fn commit_changes(&mut self, other: &StateStore) -> Result<()> { + self.state.commit_self_destructs(&other.self_destructs); + self.state.commit_recreated(&other.recreated); + self.state.commit_code(&other.code); + self.state.commit_accounts(&other.accounts); + self.state.commit_storages(&other.storages); + self.state.logs.extend(other.logs.iter().cloned()); + Ok(()) + } + + fn recreate(&mut self, address: Address) { + self.state.recreate(address); + } +} + +#[derive(Debug)] +pub struct EvmGasCounter { + pub used_gas: U256, + pub max_gas: U256, +} + +impl EvmGasCounter { + pub fn new(used_gas: U256, max_gas: U256) -> EvmGasCounter { + Self { used_gas, max_gas } + } + + pub fn pay_gas(&mut self, amount: U256) { + debug_assert!(self.used_gas + amount <= self.max_gas); + self.used_gas += amount; + } + + pub fn set_gas_left(&mut self, left: U256) { + self.used_gas = self.max_gas.saturating_sub(left); + } + + pub fn gas_left(&self) -> U256 { + self.max_gas - self.used_gas + } +} + +#[cfg(test)] +mod test { + use super::*; + + use ethereum_types::H160; + + #[test] + fn substate_tests() { + let addr_0 = Address::repeat_byte(0); + let addr_1 = Address::repeat_byte(1); + let addr_2 = Address::repeat_byte(2); + let zero = U256::zero(); + let code: [u8; 3] = [0, 1, 2]; + let nonce = U256::from_dec_str("103030303").unwrap(); + let balance = U256::from_dec_str("3838209").unwrap(); + let storage_key_0 = [4u8; 32]; + let storage_key_1 = [5u8; 32]; + let storage_value_0 = [6u8; 32]; + let storage_value_1 = [7u8; 32]; + + // Create the top-level store + let mut top = StateStore::default(); + + top.set_code(&addr_0, &code).unwrap(); + assert_eq!(top.code_at(&addr_0).unwrap(), Some(code.to_vec())); + assert_eq!(top.code_at(&addr_1).unwrap(), None); + assert_eq!(top.code_at(&addr_2).unwrap(), None); + + top.set_nonce(&addr_0, nonce).unwrap(); + assert_eq!(top.nonce_of(&addr_0).unwrap(), nonce); + assert_eq!(top.nonce_of(&addr_1).unwrap(), zero); + assert_eq!(top.nonce_of(&addr_2).unwrap(), zero); + + top.set_balance(&addr_0, balance).unwrap(); + assert_eq!(top.balance_of(&addr_0).unwrap(), balance); + assert_eq!(top.balance_of(&addr_1).unwrap(), zero); + assert_eq!(top.balance_of(&addr_2).unwrap(), zero); + + top.set_contract_storage(&addr_0, &storage_key_0, storage_value_0).unwrap(); + assert_eq!( + top.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!(top.read_contract_storage(&addr_1, &storage_key_0).unwrap(), None); + assert_eq!(top.read_contract_storage(&addr_2, &storage_key_0).unwrap(), None); + + let next = { + // Open a new store + let mut next = StateStore::default(); + let mut sub_1 = SubState::new(&addr_0, &mut next, &mut top); + + sub_1.set_code(&addr_1, &code).unwrap(); + assert_eq!(sub_1.code_at(&addr_0).unwrap(), Some(code.to_vec())); + assert_eq!(sub_1.code_at(&addr_1).unwrap(), Some(code.to_vec())); + assert_eq!(sub_1.code_at(&addr_2).unwrap(), None); + + sub_1.set_nonce(&addr_1, nonce).unwrap(); + assert_eq!(sub_1.nonce_of(&addr_0).unwrap(), nonce); + assert_eq!(sub_1.nonce_of(&addr_1).unwrap(), nonce); + assert_eq!(sub_1.nonce_of(&addr_2).unwrap(), zero); + + sub_1.set_balance(&addr_1, balance).unwrap(); + assert_eq!(sub_1.balance_of(&addr_0).unwrap(), balance); + assert_eq!(sub_1.balance_of(&addr_1).unwrap(), balance); + assert_eq!(sub_1.balance_of(&addr_2).unwrap(), zero); + + sub_1.set_contract_storage(&addr_1, &storage_key_0, storage_value_0).unwrap(); + assert_eq!( + sub_1.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + sub_1.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!(sub_1.read_contract_storage(&addr_2, &storage_key_0).unwrap(), None); + + sub_1.set_contract_storage(&addr_1, &storage_key_0, storage_value_1).unwrap(); + assert_eq!( + sub_1.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + sub_1.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_1) + ); + assert_eq!(sub_1.read_contract_storage(&addr_2, &storage_key_0).unwrap(), None); + + sub_1.set_contract_storage(&addr_1, &storage_key_1, storage_value_1).unwrap(); + assert_eq!( + sub_1.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_1) + ); + assert_eq!( + sub_1.read_contract_storage(&addr_1, &storage_key_1).unwrap(), + Some(storage_value_1) + ); + + sub_1.set_contract_storage(&addr_1, &storage_key_0, storage_value_0).unwrap(); + assert_eq!( + sub_1.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + sub_1.read_contract_storage(&addr_1, &storage_key_1).unwrap(), + Some(storage_value_1) + ); + + next + }; + + top.commit_changes(&next).unwrap(); + assert_eq!(top.code_at(&addr_0).unwrap(), Some(code.to_vec())); + assert_eq!(top.code_at(&addr_1).unwrap(), Some(code.to_vec())); + assert_eq!(top.code_at(&addr_2).unwrap(), None); + assert_eq!(top.nonce_of(&addr_0).unwrap(), nonce); + assert_eq!(top.nonce_of(&addr_1).unwrap(), nonce); + assert_eq!(top.nonce_of(&addr_2).unwrap(), zero); + assert_eq!(top.balance_of(&addr_0).unwrap(), balance); + assert_eq!(top.balance_of(&addr_1).unwrap(), balance); + assert_eq!(top.balance_of(&addr_2).unwrap(), zero); + assert_eq!( + top.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + top.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + top.read_contract_storage(&addr_1, &storage_key_1).unwrap(), + Some(storage_value_1) + ); + assert_eq!(top.read_contract_storage(&addr_2, &storage_key_0).unwrap(), None); + } + + #[test] + fn test_overflows() { + let mut top = StateStore::default(); + let mut address = [0; 20]; + address[19] = 255; + top.delete_from_storage(&H160(address)); + top.delete_from_storage(&H160([255; 20])); + } + + #[test] + fn self_destruct_tests() { + let addr_0 = Address::repeat_byte(0); + let addr_1 = Address::repeat_byte(1); + let zero = U256::zero(); + let code: [u8; 3] = [0, 1, 2]; + let nonce = U256::from_dec_str("103030303").unwrap(); + let balance_0 = U256::from_dec_str("3838209").unwrap(); + let balance_1 = U256::from_dec_str("11223344").unwrap(); + let storage_key_0 = [4u8; 32]; + let storage_key_1 = [5u8; 32]; + let storage_value_0 = [6u8; 32]; + let storage_value_1 = [7u8; 32]; + + // Create the top-level store + let mut top = StateStore::default(); + + top.set_code(&addr_0, &code).unwrap(); + top.set_nonce(&addr_0, nonce).unwrap(); + top.set_balance(&addr_0, balance_0).unwrap(); + top.set_contract_storage(&addr_0, &storage_key_0, storage_value_0).unwrap(); + + top.set_code(&addr_1, &code).unwrap(); + top.set_nonce(&addr_1, nonce).unwrap(); + top.set_balance(&addr_1, balance_0).unwrap(); + top.set_contract_storage(&addr_1, &storage_key_1, storage_value_1).unwrap(); + + assert_eq!(top.code_at(&addr_0).unwrap(), Some(code.to_vec())); + assert_eq!(top.code_at(&addr_1).unwrap(), Some(code.to_vec())); + + assert_eq!(top.nonce_of(&addr_0).unwrap(), nonce); + assert_eq!(top.nonce_of(&addr_1).unwrap(), nonce); + + assert_eq!(top.balance_of(&addr_0).unwrap(), balance_0); + assert_eq!(top.balance_of(&addr_1).unwrap(), balance_0); + + assert_eq!( + top.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + top.read_contract_storage(&addr_1, &storage_key_1).unwrap(), + Some(storage_value_1) + ); + + let next = { + // Open a new store + let mut next = StateStore::default(); + let mut sub_1 = SubState::new(&addr_0, &mut next, &mut top); + + assert_eq!(sub_1.code_at(&addr_1).unwrap(), Some(code.to_vec())); + assert_eq!(sub_1.nonce_of(&addr_1).unwrap(), nonce); + assert_eq!(sub_1.balance_of(&addr_1).unwrap(), balance_0); + assert_eq!( + sub_1.read_contract_storage(&addr_1, &storage_key_1).unwrap(), + Some(storage_value_1) + ); + + sub_1.self_destruct(&addr_1).unwrap(); + sub_1.set_balance(&addr_1, balance_1).unwrap(); + + assert_eq!(sub_1.code_at(&addr_1).unwrap(), None); + assert_eq!(sub_1.nonce_of(&addr_1).unwrap(), zero); + assert_eq!(sub_1.balance_of(&addr_1).unwrap(), balance_1); + assert_eq!(sub_1.read_contract_storage(&addr_1, &storage_key_1).unwrap(), None); + + next + }; + + top.commit_changes(&next).unwrap(); + + assert_eq!(top.code_at(&addr_0).unwrap(), Some(code.to_vec())); + assert_eq!(top.code_at(&addr_1).unwrap(), None); + + assert_eq!(top.nonce_of(&addr_0).unwrap(), nonce); + assert_eq!(top.nonce_of(&addr_1).unwrap(), zero); + + assert_eq!(top.balance_of(&addr_0).unwrap(), balance_0); + assert_eq!(top.balance_of(&addr_1).unwrap(), balance_1); + + assert_eq!( + top.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!(top.read_contract_storage(&addr_1, &storage_key_1).unwrap(), None); + } +} diff --git a/runtime/near-evm-runner/src/interpreter.rs b/runtime/near-evm-runner/src/interpreter.rs new file mode 100644 index 00000000000..c0bb2262ed4 --- /dev/null +++ b/runtime/near-evm-runner/src/interpreter.rs @@ -0,0 +1,348 @@ +use std::sync::Arc; + +use ethereum_types::{Address, U256}; +use evm::{CreateContractAddress, Factory}; +use near_runtime_fees::EvmCostConfig; +use vm::{ + ActionParams, ActionType, ActionValue, ContractCreateResult, ExecTrapResult, Ext, GasLeft, + MessageCallResult, ParamsType, ReturnData, Schedule, +}; + +use near_vm_errors::{EvmError, VMLogicError}; + +use crate::evm_state::{EvmState, StateStore, SubState}; +use crate::near_ext::NearExt; +use crate::types::{convert_vm_error, Result}; +use crate::utils; + +pub fn deploy_code( + state: &mut T, + origin: &Address, + sender: &Address, + value: U256, + call_stack_depth: usize, + address_type: CreateContractAddress, + recreate: bool, + code: &[u8], + gas: &U256, + evm_gas_config: &EvmCostConfig, + chain_id: u128, +) -> Result { + let mut nonce = U256::zero(); + if address_type == CreateContractAddress::FromSenderAndNonce { + nonce = state.next_nonce(&sender)?; + }; + let (address, _) = utils::evm_contract_address(address_type, &sender, &nonce, &code); + + if recreate { + state.recreate(address); + } else if state.code_at(&address)?.is_some() { + return Err(VMLogicError::EvmError(EvmError::DuplicateContract(address.0.to_vec()))); + } + + let (result, state_updates) = _create( + state, + origin, + sender, + value, + call_stack_depth, + &address, + code, + gas, + evm_gas_config, + chain_id, + )?; + + // Apply known gas amount changes (all reverts are NeedsReturn) + // Apply NeedsReturn changes if apply_state + // Return the result unmodified + let (return_data, apply, gas_left) = match result { + Ok(Ok(GasLeft::Known(left))) => (ReturnData::empty(), true, left), + Ok(Ok(GasLeft::NeedsReturn { gas_left: left, data, apply_state })) => { + (data, apply_state, left) + } + Ok(Err(err)) => return Err(convert_vm_error(err)), + Err(_) => return Err(VMLogicError::EvmError(EvmError::Reverted)), + }; + + if apply { + state.commit_changes(&state_updates.unwrap())?; + state.set_code(&address, &return_data.to_vec())?; + Ok(ContractCreateResult::Created(address, gas_left)) + } else { + Ok(ContractCreateResult::Reverted(gas_left, return_data)) + } +} + +pub fn _create( + state: &mut T, + origin: &Address, + sender: &Address, + value: U256, + call_stack_depth: usize, + address: &Address, + code: &[u8], + gas: &U256, + evm_gas_config: &EvmCostConfig, + chain_id: u128, +) -> Result<(ExecTrapResult, Option)> { + let mut store = StateStore::default(); + let mut sub_state = SubState::new(sender, &mut store, state); + + let params = ActionParams { + code_address: *address, + code_hash: None, + code_version: U256::zero(), + address: *address, + sender: *sender, + origin: *origin, + gas: *gas, + gas_price: 1.into(), + value: ActionValue::Transfer(value), + code: Some(Arc::new(code.to_vec())), + data: None, + action_type: ActionType::Create, + params_type: vm::ParamsType::Embedded, + }; + + sub_state.transfer_balance(sender, address, value)?; + + let mut ext = NearExt::new( + *address, + *origin, + &mut sub_state, + call_stack_depth + 1, + false, + evm_gas_config, + chain_id, + ); + ext.info.gas_limit = U256::from(gas); + ext.schedule = Schedule::new_constantinople(); + + let instance = Factory::default().create(params, ext.schedule(), ext.depth()); + + // Run the code + let result = instance.exec(&mut ext); + Ok((result, Some(store))) +} + +#[allow(clippy::too_many_arguments)] +pub fn call( + state: &mut T, + origin: &Address, + sender: &Address, + value: Option, + call_stack_depth: usize, + contract_address: &Address, + input: &[u8], + should_commit: bool, + gas: &U256, + evm_gas_config: &EvmCostConfig, + chain_id: u128, +) -> Result { + run_and_commit_if_success( + state, + origin, + sender, + value, + call_stack_depth, + ActionType::Call, + contract_address, + contract_address, + input, + false, + should_commit, + gas, + evm_gas_config, + chain_id, + ) +} + +pub fn delegate_call( + state: &mut T, + origin: &Address, + sender: &Address, + call_stack_depth: usize, + context: &Address, + delegee: &Address, + input: &[u8], + gas: &U256, + evm_gas_config: &EvmCostConfig, + chain_id: u128, +) -> Result { + run_and_commit_if_success( + state, + origin, + sender, + None, + call_stack_depth, + ActionType::DelegateCall, + context, + delegee, + input, + false, + true, + gas, + evm_gas_config, + chain_id, + ) +} + +pub fn static_call( + state: &mut T, + origin: &Address, + sender: &Address, + call_stack_depth: usize, + contract_address: &Address, + input: &[u8], + gas: &U256, + evm_gas_config: &EvmCostConfig, + chain_id: u128, +) -> Result { + run_and_commit_if_success( + state, + origin, + sender, + None, + call_stack_depth, + ActionType::StaticCall, + contract_address, + contract_address, + input, + true, + false, + gas, + evm_gas_config, + chain_id, + ) +} + +#[allow(clippy::too_many_arguments)] +fn run_and_commit_if_success( + state: &mut T, + origin: &Address, + sender: &Address, + value: Option, + call_stack_depth: usize, + call_type: ActionType, + state_address: &Address, + code_address: &Address, + input: &[u8], + is_static: bool, + should_commit: bool, + gas: &U256, + evm_gas_config: &EvmCostConfig, + chain_id: u128, +) -> Result { + // run the interpreter and + let (result, state_updates) = run_against_state( + state, + origin, + sender, + value, + call_stack_depth, + call_type, + state_address, + code_address, + input, + is_static, + gas, + evm_gas_config, + chain_id, + )?; + + // Apply known gas amount changes (all reverts are NeedsReturn) + // Apply NeedsReturn changes if apply_state + // Return the result unmodified + let mut should_apply_state = true; + let return_data = match result { + Ok(Ok(GasLeft::Known(gas_left))) => { + Ok(MessageCallResult::Success(gas_left, ReturnData::empty())) + } + Ok(Ok(GasLeft::NeedsReturn { gas_left, data, apply_state: true })) => { + Ok(MessageCallResult::Success(gas_left, data)) + } + Ok(Ok(GasLeft::NeedsReturn { gas_left, data, apply_state: false })) => { + should_apply_state = false; + Ok(MessageCallResult::Reverted(gas_left, data)) + } + Ok(Err(err)) => Err(convert_vm_error(err)), + Err(_) => Err(VMLogicError::EvmError(EvmError::Reverted)), + }; + + // Don't apply changes from a static context (these _should_ error in the ext) + if !is_static && return_data.is_ok() && should_apply_state && should_commit { + state.commit_changes(&state_updates.unwrap())?; + } + return_data +} + +/// Runs the interpreter. Produces state diffs +#[allow(clippy::too_many_arguments)] +fn run_against_state( + state: &mut T, + origin: &Address, + sender: &Address, + value: Option, + call_stack_depth: usize, + call_type: ActionType, + state_address: &Address, + code_address: &Address, + input: &[u8], + is_static: bool, + gas: &U256, + evm_gas_config: &EvmCostConfig, + chain_id: u128, +) -> Result<(ExecTrapResult, Option)> { + let code = state.code_at(code_address)?.unwrap_or_else(Vec::new); + + // Check that if there are arguments this is contract call. + // Otherwise, this is just transfer call. + if code.len() == 0 && input.len() > 0 { + return Err(VMLogicError::EvmError(EvmError::ContractNotFound)); + } + + let mut store = StateStore::default(); + let mut sub_state = SubState::new(sender, &mut store, state); + + let mut params = ActionParams { + code_address: *code_address, + code_hash: None, + code_version: U256::zero(), + address: *state_address, + sender: *sender, + origin: *origin, + gas: *gas, + gas_price: 1.into(), + value: ActionValue::Apparent(0.into()), + code: Some(Arc::new(code)), + data: Some(input.to_vec()), + action_type: call_type, + params_type: ParamsType::Separate, + }; + + if let Some(val) = value { + params.value = ActionValue::Transfer(val); + // substate transfer will get reverted if the call fails + sub_state.transfer_balance(sender, state_address, val)?; + } + + let mut ext = NearExt::new( + *state_address, + *origin, + &mut sub_state, + call_stack_depth + 1, + is_static, + evm_gas_config, + chain_id, + ); + // Gas limit is evm block gas limit, should at least prepaid gas. + ext.info.gas_limit = *gas; + ext.schedule = Schedule::new_constantinople(); + + let instance = Factory::default().create(params, ext.schedule(), ext.depth()); + + // Run the code + let result = instance.exec(&mut ext); + Ok((result, Some(store))) +} diff --git a/runtime/near-evm-runner/src/lib.rs b/runtime/near-evm-runner/src/lib.rs new file mode 100644 index 00000000000..e9ab8dc02e6 --- /dev/null +++ b/runtime/near-evm-runner/src/lib.rs @@ -0,0 +1,21 @@ +#[cfg(feature = "protocol_feature_evm")] +#[macro_use] +extern crate enum_primitive_derive; +#[cfg(feature = "protocol_feature_evm")] +mod builtins; +#[cfg(feature = "protocol_feature_evm")] +mod evm_state; +#[cfg(feature = "protocol_feature_evm")] +mod interpreter; +#[cfg(feature = "protocol_feature_evm")] +mod near_ext; +#[cfg(feature = "protocol_feature_evm")] +mod pricer; +#[cfg(feature = "protocol_feature_evm")] +mod runner; +#[cfg(feature = "protocol_feature_evm")] +pub mod types; +#[cfg(feature = "protocol_feature_evm")] +pub mod utils; +#[cfg(feature = "protocol_feature_evm")] +pub use runner::*; diff --git a/runtime/near-evm-runner/src/near_ext.rs b/runtime/near-evm-runner/src/near_ext.rs new file mode 100644 index 00000000000..64d725f7a1c --- /dev/null +++ b/runtime/near-evm-runner/src/near_ext.rs @@ -0,0 +1,364 @@ +use std::convert::TryInto; +use std::sync::Arc; + +use ethereum_types::{Address, H256, U256}; +use evm::ActionParams; +use keccak_hash::keccak; +use near_runtime_fees::EvmCostConfig; +use parity_bytes::Bytes; +use vm::{ + ActionType, ContractCreateResult, CreateContractAddress, EnvInfo, Error as VmError, + MessageCallResult, Result as EvmResult, ReturnData, Schedule, TrapKind, +}; + +use crate::evm_state::{EvmState, SubState}; +use crate::interpreter; + +use crate::utils::format_log; + +// https://github.com/openethereum/openethereum/blob/77643c13e80ca09d9a6b10631034f5a1568ba6d3/ethcore/machine/src/externalities.rs +pub struct NearExt<'a> { + pub info: EnvInfo, + pub origin: Address, + pub schedule: Schedule, + pub context_addr: Address, + pub selfdestruct_address: Option
, + pub sub_state: &'a mut SubState<'a>, + pub static_flag: bool, + pub depth: usize, + pub evm_gas_config: &'a EvmCostConfig, + pub chain_id: u128, +} + +impl std::fmt::Debug for NearExt<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "\nNearExt {{")?; + write!(f, "\n\tinfo: {:?}", self.info)?; + write!(f, "\n\torigin: {:?}", self.origin)?; + write!(f, "\n\tcontext_addr: {:?}", self.context_addr)?; + write!(f, "\n\tstatic_flag: {:?}", self.static_flag)?; + write!(f, "\n\tdepth: {:?}", self.depth)?; + write!(f, "\n\tchain_id: {:?}", self.chain_id)?; + write!(f, "\n}}") + } +} + +impl<'a> NearExt<'a> { + pub fn new( + context_addr: Address, + origin: Address, + sub_state: &'a mut SubState<'a>, + depth: usize, + static_flag: bool, + evm_gas_config: &'a EvmCostConfig, + chain_id: u128, + ) -> Self { + Self { + info: Default::default(), + origin, + schedule: Default::default(), + context_addr, + selfdestruct_address: Default::default(), + sub_state, + static_flag, + depth, + evm_gas_config, + chain_id, + } + } +} + +impl<'a> vm::Ext for NearExt<'a> { + /// EIP-1344: Returns the current chain's EIP-155 unique identifier. + /// See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1344.md + fn chain_id(&self) -> u64 { + self.chain_id.try_into().unwrap() + } + + /// Returns the storage value for a given key if reversion happens on the current transaction. + fn initial_storage_at(&self, key: &H256) -> EvmResult { + let raw_val = self + .sub_state + .parent // Read from the unmodified parent state + .read_contract_storage(&self.context_addr, &key.0) + .unwrap_or(None) + .unwrap_or([0u8; 32]); // default to an empty value + Ok(H256(raw_val)) + } + + /// Returns a value for given key. + fn storage_at(&self, key: &H256) -> EvmResult { + let raw_val = self + .sub_state + .read_contract_storage(&self.context_addr, &key.0) + .unwrap_or(None) + .unwrap_or([0u8; 32]); // default to an empty value + Ok(H256(raw_val)) + } + + /// Stores a value for given key. + fn set_storage(&mut self, key: H256, value: H256) -> EvmResult<()> { + if self.is_static() { + return Err(VmError::MutableCallInStaticContext); + } + self.sub_state + .set_contract_storage(&self.context_addr, &key.0, value.0) + .map_err(|err| vm::Error::Internal(err.to_string())) + } + + // TODO: research why these are different + fn exists(&self, address: &Address) -> EvmResult { + Ok(self.sub_state.balance_of(address).unwrap_or_else(|_| U256::zero()) > U256::zero() + || self.sub_state.code_at(address).unwrap_or(None).is_some()) + } + + fn exists_and_not_null(&self, address: &Address) -> EvmResult { + Ok(self.sub_state.balance_of(address).unwrap_or_else(|_| U256::zero()) > 0.into() + || self.sub_state.code_at(address).unwrap_or(None).is_some()) + } + + fn origin_balance(&self) -> EvmResult { + self.balance(&self.origin) + } + + fn balance(&self, address: &Address) -> EvmResult { + Ok(self + .sub_state + .get_account(address) + .unwrap_or(None) + .map(|account| account.balance.into()) + .unwrap_or(U256::zero())) + } + + fn blockhash(&mut self, number: &U256) -> H256 { + // TODO(3456): Return actual block hashes. + let mut buf = [0u8; 32]; + number.to_big_endian(&mut buf); + keccak(&buf[..]) + } + + fn create( + &mut self, + gas: &U256, + value: &U256, + code: &[u8], + _parent_version: &U256, + address_type: CreateContractAddress, + _trap: bool, + ) -> Result { + if self.is_static() { + return Err(TrapKind::Call(ActionParams::default())); + } + + // TODO: better error propagation. + interpreter::deploy_code( + self.sub_state, + &self.origin, + &self.context_addr, + *value, + self.depth, + address_type, + true, + &code.to_vec(), + gas, + &self.evm_gas_config, + self.chain_id, + ) + .map_err(|_| TrapKind::Call(ActionParams::default())) + } + + /// Message call. + /// + /// Returns Err, if we run out of gas. + /// Otherwise returns call_result which contains gas left + /// and true if subcall was successful. + fn call( + &mut self, + gas: &U256, + sender_address: &Address, + receive_address: &Address, + value: Option, + data: &[u8], + code_address: &Address, + call_type: ActionType, + _trap: bool, + ) -> Result { + if self.is_static() && call_type != ActionType::StaticCall { + panic!("MutableCallInStaticContext") + } + + // hijack builtins + if crate::builtins::is_precompile(receive_address) { + return Ok(crate::builtins::process_precompile( + receive_address, + data, + gas, + &self.evm_gas_config.precompile_costs, + )); + } + + let result = match call_type { + ActionType::Create | ActionType::Create2 => { + // Is not used. + return Err(TrapKind::Call(ActionParams::default())); + } + ActionType::Call => interpreter::call( + self.sub_state, + &self.origin, + sender_address, + value, + self.depth, + receive_address, + &data.to_vec(), + true, // should_commit + gas, + &self.evm_gas_config, + self.chain_id, + ), + ActionType::StaticCall => interpreter::static_call( + self.sub_state, + &self.origin, + sender_address, + self.depth, + receive_address, + &data.to_vec(), + gas, + &self.evm_gas_config, + self.chain_id, + ), + ActionType::CallCode => { + // Call another contract using storage of the current contract. No longer used. + return Err(TrapKind::Call(ActionParams::default())); + } + ActionType::DelegateCall => interpreter::delegate_call( + self.sub_state, + &self.origin, + sender_address, + self.depth, + receive_address, + code_address, + &data.to_vec(), + gas, + &self.evm_gas_config, + self.chain_id, + ), + }; + result.map_err(|_| TrapKind::Call(ActionParams::default())) + } + + /// Returns code at given address + fn extcode(&self, address: &Address) -> EvmResult>> { + let code = self.sub_state.code_at(address).unwrap_or(None).map(Arc::new); + Ok(code) + } + + /// Returns code hash at given address + fn extcodehash(&self, address: &Address) -> EvmResult> { + let code_opt = self.sub_state.code_at(address).unwrap_or(None); + let code = match code_opt { + Some(code) => code, + None => return Ok(None), + }; + if code.is_empty() { + Ok(None) + } else { + Ok(Some(keccak(code))) + } + } + + /// Returns code size at given address + fn extcodesize(&self, address: &Address) -> EvmResult> { + Ok(self.sub_state.code_at(address).unwrap_or(None).map(|c| c.len())) + } + + /// Creates log entry with given topics and data + fn log(&mut self, topics: Vec, data: &[u8]) -> EvmResult<()> { + if self.is_static() { + return Err(VmError::MutableCallInStaticContext); + } + if topics.len() > 256 { + return Err(VmError::Internal("Too many topics".to_string())); + } + self.sub_state.state.logs.push(hex::encode( + format_log(topics, data) + .map_err(|err| VmError::Internal(format!("Failed to format event: {}", err)))?, + )); + Ok(()) + } + + /// Should be called when transaction calls `RETURN` opcode. + /// Returns gas_left if cost of returning the data is not too high. + fn ret(self, _gas: &U256, _data: &ReturnData, _apply_state: bool) -> EvmResult { + // NOTE: this is only called through finalize(), but we are not using it + // so it should be safe to ignore it here. + Err(vm::Error::Internal("ret".to_string())) + } + + /// Should be called when contract commits suicide. + /// Address to which funds should be refunded. + /// Deletes code, moves balance + fn suicide(&mut self, refund_address: &Address) -> EvmResult<()> { + self.sub_state + .self_destruct(&self.context_addr) + .map_err(|err| vm::Error::Internal(err.to_string()))?; + + let account = + self.sub_state.get_account(&self.context_addr).unwrap_or(None).unwrap_or_default(); + self.sub_state + .add_balance(refund_address, account.balance.into()) + .map_err(|err| vm::Error::Internal(err.to_string()))?; + self.sub_state + .sub_balance(&self.context_addr, account.balance.into()) + .map_err(|err| vm::Error::Internal(err.to_string()))?; + Ok(()) + } + + /// Returns schedule. + fn schedule(&self) -> &Schedule { + &self.schedule + } + + /// Returns environment info. + fn env_info(&self) -> &EnvInfo { + &self.info + } + + /// Returns current depth of execution. + /// + /// If contract A calls contract B, and contract B calls C, + /// then A depth is 0, B is 1, C is 2 and so on. + fn depth(&self) -> usize { + self.depth + } + + /// Increments sstore refunds counter. + fn add_sstore_refund(&mut self, _value: usize) {} + + /// Decrements sstore refunds counter. + /// Left as NOP as evm gas is not metered + fn sub_sstore_refund(&mut self, _value: usize) {} + + /// Decide if any more operations should be traced. Passthrough for the VM trace. + fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _current_gas: U256) -> bool { + false + } + + /// Prepare to trace an operation. Passthrough for the VM trace. + fn trace_prepare_execute( + &mut self, + _pc: usize, + _instruction: u8, + _gas_cost: U256, + _mem_written: Option<(usize, usize)>, + _store_written: Option<(U256, U256)>, + ) { + } + + /// Trace the finalised execution of a single instruction. + fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem: &[u8]) {} + + /// Check if running in static context. + fn is_static(&self) -> bool { + self.static_flag + } +} diff --git a/runtime/near-evm-runner/src/pricer.rs b/runtime/near-evm-runner/src/pricer.rs new file mode 100644 index 00000000000..ff8640e274d --- /dev/null +++ b/runtime/near-evm-runner/src/pricer.rs @@ -0,0 +1,434 @@ +// Below is part of Open Ethereum: +// Copyright 2015-2020 Parity Technologies (UK) Ltd. + +// Source Reference +// https://github.com/openethereum/openethereum/blob/116554961c24b1c7de6cd15738a391720ae3fe56/ethcore/builtin/src/lib.rs#L159 + +// Open Ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Open Ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Open Ethereum. If not, see . + +use ethereum_types::U256; +use std::convert::TryInto; +use std::{ + cmp::{max, min}, + io::{self, Read}, +}; + +const SCALAR_BYTE_LENGTH: usize = 32; +const SERIALIZED_FP_BYTE_LENGTH: usize = 64; +const SERIALIZED_G1_POINT_BYTE_LENGTH: usize = SERIALIZED_FP_BYTE_LENGTH * 2; +const SERIALIZED_FP2_BYTE_LENGTH: usize = SERIALIZED_FP_BYTE_LENGTH * 2; +const SERIALIZED_G2_POINT_BYTE_LENGTH: usize = SERIALIZED_FP2_BYTE_LENGTH * 2; + +/// A gas pricing scheme for built-in contracts. +pub trait Pricer: Send + Sync { + /// The gas cost of running this built-in for the given input data at block number `at` + fn cost(&self, input: &[u8]) -> U256; +} + +/// Pricing for the Blake2 compression function (aka "F"). +/// Computes the price as a fixed cost per round where the number of rounds is part of the input +/// byte slice. +pub type Blake2FPricer = u64; + +impl Pricer for Blake2FPricer { + fn cost(&self, input: &[u8]) -> U256 { + const FOUR: usize = std::mem::size_of::(); + // Returning zero if the conversion fails is fine because `execute()` will check the length + // and bail with the appropriate error. + if input.len() < FOUR { + return U256::zero(); + } + let (rounds_bytes, _) = input.split_at(FOUR); + let rounds = u32::from_be_bytes(rounds_bytes.try_into().unwrap_or([0u8; FOUR])); + U256::from(*self as u128 * rounds as u128) + } +} + +/// Pricing model +#[allow(dead_code)] +#[derive(Debug)] +pub enum Pricing { + AltBn128Pairing(AltBn128PairingPricer), + AltBn128ConstOperations(AltBn128ConstOperations), + Blake2F(Blake2FPricer), + Linear(Linear), + Modexp(ModexpPricer), + Bls12Pairing(Bls12PairingPricer), + Bls12ConstOperations(Bls12ConstOperations), + Bls12MultiexpG1(Bls12MultiexpPricerG1), + Bls12MultiexpG2(Bls12MultiexpPricerG2), +} + +impl Pricer for Pricing { + fn cost(&self, input: &[u8]) -> U256 { + match self { + Pricing::AltBn128Pairing(inner) => inner.cost(input), + Pricing::AltBn128ConstOperations(inner) => inner.cost(input), + Pricing::Blake2F(inner) => inner.cost(input), + Pricing::Linear(inner) => inner.cost(input), + Pricing::Modexp(inner) => inner.cost(input), + Pricing::Bls12Pairing(inner) => inner.cost(input), + Pricing::Bls12ConstOperations(inner) => inner.cost(input), + Pricing::Bls12MultiexpG1(inner) => inner.cost(input), + Pricing::Bls12MultiexpG2(inner) => inner.cost(input), + } + } +} + +/// A linear pricing model. This computes a price using a base cost and a cost per-word. +#[derive(Debug)] +pub struct Linear { + pub base: u64, + pub word: u64, +} + +/// A special pricing model for modular exponentiation. +#[derive(Debug)] +pub struct ModexpPricer { + pub divisor: u64, +} + +impl Pricer for Linear { + fn cost(&self, input: &[u8]) -> U256 { + U256::from(self.base) + U256::from(self.word) * U256::from((input.len() + 31) / 32) + } +} + +/// alt_bn128 pairing price +#[derive(Debug, Copy, Clone)] +pub struct AltBn128PairingPrice { + pub base: u64, + pub pair: u64, +} + +/// alt_bn128_pairing pricing model. This computes a price using a base cost and a cost per pair. +#[derive(Debug)] +pub struct AltBn128PairingPricer { + pub price: AltBn128PairingPrice, +} + +/// Pricing for constant alt_bn128 operations (ECADD and ECMUL) +#[derive(Debug, Copy, Clone)] +pub struct AltBn128ConstOperations { + /// Fixed price. + pub price: u64, +} + +impl Pricer for AltBn128ConstOperations { + fn cost(&self, _input: &[u8]) -> U256 { + self.price.into() + } +} + +impl Pricer for AltBn128PairingPricer { + fn cost(&self, input: &[u8]) -> U256 { + U256::from(self.price.base) + U256::from(self.price.pair) * U256::from(input.len() / 192) + } +} + +impl Pricer for ModexpPricer { + fn cost(&self, input: &[u8]) -> U256 { + let mut reader = input.chain(io::repeat(0)); + let mut buf = [0; 32]; + + // read lengths as U256 here for accurate gas calculation. + let mut read_len = || { + reader + .read_exact(&mut buf[..]) + .expect("reading from zero-extended memory cannot fail; qed"); + U256::from_big_endian(&buf[..]) + }; + let base_len = read_len(); + let exp_len = read_len(); + let mod_len = read_len(); + + if mod_len.is_zero() && base_len.is_zero() { + return U256::zero(); + } + + let max_len = U256::from(u32::max_value() / 2); + if base_len > max_len || mod_len > max_len || exp_len > max_len { + return U256::max_value(); + } + let (base_len, exp_len, mod_len) = + (base_len.low_u64(), exp_len.low_u64(), mod_len.low_u64()); + + let m = max(mod_len, base_len); + // read fist 32-byte word of the exponent. + let exp_low = if base_len + 96 >= input.len() as u64 { + U256::zero() + } else { + buf.iter_mut().for_each(|b| *b = 0); + let mut reader = input[(96 + base_len as usize)..].chain(io::repeat(0)); + let len = min(exp_len, 32) as usize; + reader + .read_exact(&mut buf[(32 - len)..]) + .expect("reading from zero-extended memory cannot fail; qed"); + U256::from_big_endian(&buf[..]) + }; + + let adjusted_exp_len = Self::adjusted_exp_len(exp_len, exp_low); + + let (gas, overflow) = Self::mult_complexity(m).overflowing_mul(max(adjusted_exp_len, 1)); + if overflow { + return U256::max_value(); + } + (gas / self.divisor as u64).into() + } +} + +impl ModexpPricer { + fn adjusted_exp_len(len: u64, exp_low: U256) -> u64 { + let bit_index = if exp_low.is_zero() { 0 } else { (255 - exp_low.leading_zeros()) as u64 }; + if len <= 32 { + bit_index + } else { + 8 * (len - 32) + bit_index + } + } + + fn mult_complexity(x: u64) -> u64 { + match x { + x if x <= 64 => x * x, + x if x <= 1024 => (x * x) / 4 + 96 * x - 3072, + x => (x * x) / 16 + 480 * x - 199_680, + } + } +} + +/// Bls12 pairing price +#[derive(Debug, Copy, Clone)] +pub struct Bls12PairingPrice { + pub base: u64, + pub pair: u64, +} + +/// bls12_pairing pricing model. This computes a price using a base cost and a cost per pair. +#[derive(Debug)] +pub struct Bls12PairingPricer { + pub price: Bls12PairingPrice, +} + +/// Pricing for constant Bls12 operations (ADD and MUL in G1 and G2, as well as mappings) +#[derive(Debug, Copy, Clone)] +pub struct Bls12ConstOperations { + /// Fixed price. + pub price: u64, +} + +/// Discount table for multiexponentiation (Peppinger algorithm) +/// Later on is normalized using the divisor +pub const BLS12_MULTIEXP_DISCOUNTS_TABLE: [[u64; 2]; BLS12_MULTIEXP_PAIRS_FOR_MAX_DISCOUNT] = [ + [1, 1200], + [2, 888], + [3, 764], + [4, 641], + [5, 594], + [6, 547], + [7, 500], + [8, 453], + [9, 438], + [10, 423], + [11, 408], + [12, 394], + [13, 379], + [14, 364], + [15, 349], + [16, 334], + [17, 330], + [18, 326], + [19, 322], + [20, 318], + [21, 314], + [22, 310], + [23, 306], + [24, 302], + [25, 298], + [26, 294], + [27, 289], + [28, 285], + [29, 281], + [30, 277], + [31, 273], + [32, 269], + [33, 268], + [34, 266], + [35, 265], + [36, 263], + [37, 262], + [38, 260], + [39, 259], + [40, 257], + [41, 256], + [42, 254], + [43, 253], + [44, 251], + [45, 250], + [46, 248], + [47, 247], + [48, 245], + [49, 244], + [50, 242], + [51, 241], + [52, 239], + [53, 238], + [54, 236], + [55, 235], + [56, 233], + [57, 232], + [58, 231], + [59, 229], + [60, 228], + [61, 226], + [62, 225], + [63, 223], + [64, 222], + [65, 221], + [66, 220], + [67, 219], + [68, 219], + [69, 218], + [70, 217], + [71, 216], + [72, 216], + [73, 215], + [74, 214], + [75, 213], + [76, 213], + [77, 212], + [78, 211], + [79, 211], + [80, 210], + [81, 209], + [82, 208], + [83, 208], + [84, 207], + [85, 206], + [86, 205], + [87, 205], + [88, 204], + [89, 203], + [90, 202], + [91, 202], + [92, 201], + [93, 200], + [94, 199], + [95, 199], + [96, 198], + [97, 197], + [98, 196], + [99, 196], + [100, 195], + [101, 194], + [102, 193], + [103, 193], + [104, 192], + [105, 191], + [106, 191], + [107, 190], + [108, 189], + [109, 188], + [110, 188], + [111, 187], + [112, 186], + [113, 185], + [114, 185], + [115, 184], + [116, 183], + [117, 182], + [118, 182], + [119, 181], + [120, 180], + [121, 179], + [122, 179], + [123, 178], + [124, 177], + [125, 176], + [126, 176], + [127, 175], + [128, 174], +]; + +/// Max discount allowed +pub const BLS12_MULTIEXP_MAX_DISCOUNT: u64 = 174; +/// Max discount is reached at this number of pairs +pub const BLS12_MULTIEXP_PAIRS_FOR_MAX_DISCOUNT: usize = 128; +/// Divisor for discounts table +pub const BLS12_MULTIEXP_DISCOUNT_DIVISOR: u64 = 1000; +/// Length of single G1 + G2 points pair for pairing operation +pub const BLS12_G1_AND_G2_PAIR_LEN: usize = + SERIALIZED_G1_POINT_BYTE_LENGTH + SERIALIZED_G2_POINT_BYTE_LENGTH; + +/// Marter trait for length of input per one pair (point + scalar) +pub trait PointScalarLength: Copy + Clone + std::fmt::Debug + Send + Sync { + /// Length itself + const LENGTH: usize; +} +/// Marker trait that indicated that we perform operations in G1 +#[derive(Clone, Copy, Debug)] +pub struct G1Marker; +impl PointScalarLength for G1Marker { + const LENGTH: usize = SERIALIZED_G1_POINT_BYTE_LENGTH + SCALAR_BYTE_LENGTH; +} +/// Marker trait that indicated that we perform operations in G2 +#[derive(Clone, Copy, Debug)] +pub struct G2Marker; +impl PointScalarLength for G2Marker { + const LENGTH: usize = SERIALIZED_G2_POINT_BYTE_LENGTH + SCALAR_BYTE_LENGTH; +} + +/// Pricing for constant Bls12 operations (ADD and MUL in G1 and G2, as well as mappings) +#[derive(Debug, Copy, Clone)] +pub struct Bls12MultiexpPricer { + /// Base const of the operation (G1 or G2 multiplication) + pub base_price: Bls12ConstOperations, + + _marker: std::marker::PhantomData

, +} + +impl Pricer for Bls12ConstOperations { + fn cost(&self, _input: &[u8]) -> U256 { + self.price.into() + } +} + +impl Pricer for Bls12PairingPricer { + fn cost(&self, input: &[u8]) -> U256 { + U256::from(self.price.base) + + U256::from(self.price.pair) * U256::from(input.len() / BLS12_G1_AND_G2_PAIR_LEN) + } +} + +impl Pricer for Bls12MultiexpPricer

{ + fn cost(&self, input: &[u8]) -> U256 { + let num_pairs = input.len() / P::LENGTH; + if num_pairs == 0 { + return U256::zero(); + } + let discount = if num_pairs > BLS12_MULTIEXP_PAIRS_FOR_MAX_DISCOUNT { + BLS12_MULTIEXP_MAX_DISCOUNT + } else { + let table_entry = BLS12_MULTIEXP_DISCOUNTS_TABLE[num_pairs - 1]; + table_entry[1] + }; + U256::from(self.base_price.price) * U256::from(num_pairs) * U256::from(discount) + / U256::from(BLS12_MULTIEXP_DISCOUNT_DIVISOR) + } +} + +/// Multiexp pricer in G1 +pub type Bls12MultiexpPricerG1 = Bls12MultiexpPricer; + +/// Multiexp pricer in G2 +pub type Bls12MultiexpPricerG2 = Bls12MultiexpPricer; diff --git a/runtime/near-evm-runner/src/runner.rs b/runtime/near-evm-runner/src/runner.rs new file mode 100644 index 00000000000..4f6e5ba13ec --- /dev/null +++ b/runtime/near-evm-runner/src/runner.rs @@ -0,0 +1,802 @@ +use borsh::{BorshDeserialize, BorshSerialize}; +use ethereum_types::{Address, H160, U256}; +use evm::CreateContractAddress; +use vm::{ContractCreateResult, MessageCallResult}; + +use near_runtime_fees::{EvmCostConfig, RuntimeFeesConfig}; +use near_runtime_utils::is_account_id_64_len_hex; +use near_vm_errors::{EvmError, FunctionCallError, VMError}; +use near_vm_logic::gas_counter::GasCounter; +use near_vm_logic::types::{AccountId, Balance, Gas, ReturnData, StorageUsage}; +use near_vm_logic::{ActionCosts, External, VMConfig, VMLogicError, VMOutcome}; + +use crate::evm_state::{EvmAccount, EvmGasCounter, EvmState, StateStore}; +use crate::interpreter; +use crate::types::{ + AddressArg, DataKey, FunctionCallArgs, GetStorageAtArgs, Method, RawU256, Result, TransferArgs, + ViewCallArgs, WithdrawArgs, +}; +use crate::utils::{self, combine_data_key, near_erc721_domain, parse_meta_call}; +use near_vm_errors::InconsistentStateError::StorageError; + +pub struct EvmContext<'a> { + ext: &'a mut dyn External, + account_id: AccountId, + signer_id: AccountId, + predecessor_id: AccountId, + current_amount: Balance, + pub attached_deposit: Balance, + storage_usage: StorageUsage, + pub logs: Vec, + gas_counter: GasCounter, + pub evm_gas_counter: EvmGasCounter, + fees_config: &'a RuntimeFeesConfig, + chain_id: u128, + domain_separator: RawU256, +} + +// Different kind of evm operations that result in different gas calculation +pub enum EvmOpForGas { + // size of deployed evm contract after it's decoded from hex (0.5x) + Deploy(usize), + Funcall, + Other, +} + +enum KeyPrefix { + Account = 0, + Contract = 1, +} + +fn address_to_key(prefix: KeyPrefix, address: &H160) -> [u8; 21] { + let mut result = [0u8; 21]; + result[0] = prefix as u8; + result[1..].copy_from_slice(&address.0); + result +} + +impl<'a> EvmState for EvmContext<'a> { + fn code_at(&self, address: &H160) -> Result>> { + self.ext + .storage_get(&address_to_key(KeyPrefix::Contract, address)) + .map(|value| value.map(|x| x.deref().expect("Failed to deref"))) + } + + fn set_code(&mut self, address: &H160, bytecode: &[u8]) -> Result<()> { + self.ext.storage_set(&address_to_key(KeyPrefix::Contract, address), bytecode) + } + + fn get_account(&self, address: &Address) -> Result> { + match self.ext.storage_get(&address_to_key(KeyPrefix::Account, address)).map(|value| { + value.map(|x| EvmAccount::try_from_slice(&x.deref().expect("Failed to deref"))) + }) { + Ok(Some(Ok(value))) => Ok(Some(value)), + Ok(None) => Ok(None), + Ok(Some(Err(_))) => Err(VMLogicError::InconsistentStateError(StorageError( + "Failed to deserialize".to_string(), + ))), + Err(e) => Err(e), + } + } + + fn set_account(&mut self, address: &Address, account: &EvmAccount) -> Result<()> { + self.ext.storage_set( + &address_to_key(KeyPrefix::Account, address), + &account.try_to_vec().expect("Failed to serialize"), + ) + } + + fn _read_contract_storage(&self, key: &DataKey) -> Result> { + match self + .ext + .storage_get(key) + .map(|value| value.map(|x| utils::vec_to_arr_32(x.deref().expect("Failed to deref")))) + { + Ok(Some(Some(value))) => Ok(Some(value)), + Ok(Some(None)) => Err(VMLogicError::InconsistentStateError(StorageError( + "Must be 32 bytes".to_string(), + ))), + Ok(None) => Ok(None), + Err(err) => Err(err), + } + } + + fn _set_contract_storage(&mut self, key: &DataKey, value: RawU256) -> Result<()> { + self.ext.storage_set(key, &value) + } + + fn commit_changes(&mut self, other: &StateStore) -> Result<()> { + for address in other.self_destructs.iter() { + self.clear_contract_info(address)?; + } + for address in other.recreated.iter() { + self.clear_contract_info(address)?; + } + for (address, code) in other.code.iter() { + self.set_code(address, code)?; + } + for (address, account) in other.accounts.iter() { + self.set_account(address, account)?; + } + for (address, values) in other.storages.iter() { + for (key, value) in values.iter() { + let key = combine_data_key(address, key); + self._set_contract_storage(&key, *value)?; + } + } + self.logs.extend_from_slice(&other.logs); + Ok(()) + } + + fn recreate(&mut self, _address: Address) { + unreachable!() + } +} + +impl<'a> EvmContext<'a> { + pub fn new( + ext: &'a mut dyn External, + chain_id: u128, + config: &'a VMConfig, + fees_config: &'a RuntimeFeesConfig, + current_amount: Balance, + account_id: AccountId, + signer_id: AccountId, + predecessor_id: AccountId, + attached_deposit: Balance, + storage_usage: StorageUsage, + prepaid_gas: Gas, + is_view: bool, + evm_gas: U256, + ) -> Self { + let max_gas_burnt = if is_view { + config.limit_config.max_gas_burnt_view + } else { + config.limit_config.max_gas_burnt + }; + // TODO: pass chain id from ??? genesis / config. + let domain_separator = near_erc721_domain(U256::from(chain_id)); + Self { + ext, + account_id, + signer_id, + predecessor_id, + current_amount, + attached_deposit, + storage_usage, + logs: Vec::default(), + gas_counter: GasCounter::new( + config.ext_costs.clone(), + max_gas_burnt, + prepaid_gas, + is_view, + None, + ), + evm_gas_counter: EvmGasCounter::new(0.into(), evm_gas), + fees_config, + chain_id, + domain_separator, + } + } + + fn clear_contract_info(&mut self, other: &Address) -> Result<()> { + self.ext.storage_remove_subtree(&other.0) + } + + pub fn deploy_code(&mut self, bytecode: Vec) -> Result

{ + let sender = utils::near_account_id_to_evm_address(&self.predecessor_id); + self.add_balance(&sender, U256::from(self.attached_deposit))?; + match interpreter::deploy_code( + self, + &sender, + &sender, + U256::from(self.attached_deposit), + 0, + CreateContractAddress::FromSenderAndNonce, + false, + &bytecode, + &self.evm_gas_counter.gas_left(), + &self.fees_config.evm_config, + self.chain_id, + )? { + ContractCreateResult::Created(address, gas_left) => { + self.evm_gas_counter.set_gas_left(gas_left); + Ok(address) + } + ContractCreateResult::Reverted(gas_left, return_data) => { + self.evm_gas_counter.set_gas_left(gas_left); + Err(VMLogicError::EvmError(EvmError::DeployFail(return_data.to_vec()))) + } + _ => unreachable!(), + } + } + + /// Make an EVM transaction. Calls `contract_address` with RLP encoded `input`. Execution + /// continues until all EVM messages have been processed. We expect this to behave identically + /// to an Ethereum transaction, however there may be some edge cases. + pub fn call_function(&mut self, args: Vec) -> Result> { + let args = FunctionCallArgs::try_from_slice(&args) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + let contract_address = Address::from(&args.contract); + let input = args.input; + let _origin = utils::near_account_id_to_evm_address(&self.signer_id); + let sender = utils::near_account_id_to_evm_address(&self.predecessor_id); + self.add_balance(&sender, U256::from(self.attached_deposit))?; + let value = + if self.attached_deposit == 0 { None } else { Some(U256::from(self.attached_deposit)) }; + let result = interpreter::call( + self, + &sender, + &sender, + value, + 0, + &contract_address, + &input, + true, + &self.evm_gas_counter.gas_left(), + &self.fees_config.evm_config, + self.chain_id, + )?; + self.process_call_result(result) + } + + /// Make an EVM call via a meta transaction pattern. + /// Specifically, providing signature and NEAREvm message that determines which contract and arguments to be called. + /// See `parse_meta_call` for arguments format. + pub fn meta_call_function(&mut self, args: Vec) -> Result> { + let meta_call_args = parse_meta_call(&self.domain_separator, &self.account_id, args)?; + if self.next_nonce(&meta_call_args.sender)? != meta_call_args.nonce { + return Err(VMLogicError::EvmError(EvmError::InvalidNonce)); + } + self.add_balance(&meta_call_args.sender, U256::from(self.attached_deposit))?; + let value = + if self.attached_deposit == 0 { None } else { Some(U256::from(self.attached_deposit)) }; + let result = interpreter::call( + self, + &meta_call_args.sender, + &meta_call_args.sender, + value, + 0, + &meta_call_args.contract_address, + &meta_call_args.input, + true, + &self.evm_gas_counter.gas_left(), + &self.fees_config.evm_config, + self.chain_id, + )?; + self.process_call_result(result) + } + + /// Make an EVM transaction. Calls `contract_address` with `encoded_input`. Execution + /// continues until all EVM messages have been processed. We expect this to behave identically + /// to an Ethereum transaction, however there may be some edge cases. + /// + /// This function serves the eth_call functionality, and will NOT apply state changes. + pub fn view_call_function(&mut self, args: Vec) -> Result> { + let args = ViewCallArgs::try_from_slice(&args) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + let sender = Address::from(&args.sender); + let attached_amount = U256::from(args.amount); + self.add_balance(&sender, attached_amount)?; + // TODO: Verify we don't keep the balance in case `call` returns `Err` + let result = interpreter::call( + self, + &sender, + &sender, + Some(attached_amount), + 0, + &Address::from(&args.address), + &args.input, + false, + &self.evm_gas_counter.gas_left(), + &self.fees_config.evm_config, + self.chain_id, + )?; + let result = self.process_call_result(result); + // Need to subtract amount back, because if view call is called inside the transaction state will be applied. + // The interpreter call is not committing changes, but `add_balance` did, so need to revert that. + self.sub_balance(&sender, attached_amount)?; + result + } + + /// Processes `MessageCallResult` and charges gas. + fn process_call_result(&mut self, result: MessageCallResult) -> Result> { + match result { + MessageCallResult::Success(gas_left, data) => { + self.evm_gas_counter.set_gas_left(gas_left); + Ok(data.to_vec()) + } + MessageCallResult::Reverted(gas_left, data) => { + self.evm_gas_counter.set_gas_left(gas_left); + Err(VMLogicError::EvmError(EvmError::Revert(data.to_vec()))) + } + _ => unreachable!(), + } + } + + pub fn get_code(&self, args: Vec) -> Result> { + let args = AddressArg::try_from_slice(&args) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + Ok(self + .code_at(&Address::from_slice(&args.address)) + .unwrap_or(None) + .unwrap_or_else(Vec::new)) + } + + pub fn get_storage_at(&self, args: Vec) -> Result> { + let args = GetStorageAtArgs::try_from_slice(&args) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + Ok(self + .read_contract_storage(&Address::from_slice(&args.address), &args.key)? + .unwrap_or([0u8; 32]) + .to_vec()) + } + + pub fn get_balance(&self, args: Vec) -> Result { + let args = AddressArg::try_from_slice(&args) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + self.balance_of(&Address::from_slice(&args.address)) + } + + pub fn get_nonce(&self, args: Vec) -> Result { + let args = AddressArg::try_from_slice(&args) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + self.nonce_of(&Address::from_slice(&args.address)) + } + + pub fn deposit(&mut self, args: Vec) -> Result { + let args = AddressArg::try_from_slice(&args) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + if self.attached_deposit == 0 { + return Err(VMLogicError::EvmError(EvmError::MissingDeposit)); + } + let address = Address::from_slice(&args.address); + self.add_balance(&address, U256::from(self.attached_deposit))?; + self.balance_of(&address) + } + + pub fn withdraw(&mut self, args: Vec) -> Result<()> { + let args = WithdrawArgs::try_from_slice(&args) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + if args.account_id == self.account_id { + return Err(VMLogicError::EvmError(EvmError::FailSelfWithdraw)); + } + let sender = utils::near_account_id_to_evm_address(&self.predecessor_id); + let amount = U256::from(args.amount); + if amount > self.balance_of(&sender)? { + return Err(VMLogicError::EvmError(EvmError::InsufficientFunds)); + } + self.sub_balance(&sender, amount)?; + let receipt_index = self.ext.create_receipt(vec![], args.account_id.clone())?; + // We use low_u128, because NEAR native currency fits into u128. + let amount = amount.low_u128(); + self.current_amount = self + .current_amount + .checked_sub(amount) + .ok_or_else(|| VMLogicError::EvmError(EvmError::InsufficientFunds))?; + self.pay_gas_for_new_receipt(false, &[])?; + self.pay_gas_for_transfer(&args.account_id)?; + self.ext.append_action_transfer(receipt_index, amount) + } + + /// Transfer tokens from sender to given EVM address. + pub fn transfer(&mut self, args: Vec) -> Result<()> { + let args = TransferArgs::try_from_slice(&args) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + let sender = utils::near_account_id_to_evm_address(&self.predecessor_id); + let amount = U256::from(args.amount); + if amount > self.balance_of(&sender)? { + return Err(VMLogicError::EvmError(EvmError::InsufficientFunds)); + } + self.transfer_balance(&sender, &Address::from(args.address), amount) + } + + /// A helper function to pay gas fee for creating a new receipt without actions. + /// # Args: + /// * `sir`: whether contract call is addressed to itself; + /// * `data_dependencies`: other contracts that this execution will be waiting on (or rather + /// their data receipts), where bool indicates whether this is sender=receiver communication. + /// + /// # Cost + /// + /// This is a convenience function that encapsulates several costs: + /// `burnt_gas := dispatch cost of the receipt + base dispatch cost cost of the data receipt` + /// `used_gas := burnt_gas + exec cost of the receipt + base exec cost cost of the data receipt` + /// Notice that we prepay all base cost upon the creation of the data dependency, we are going to + /// pay for the content transmitted through the dependency upon the actual creation of the + /// DataReceipt. + fn pay_gas_for_new_receipt(&mut self, sir: bool, data_dependencies: &[bool]) -> Result<()> { + let fees_config_cfg = &self.fees_config; + let mut burn_gas = fees_config_cfg.action_receipt_creation_config.send_fee(sir); + let mut use_gas = fees_config_cfg.action_receipt_creation_config.exec_fee(); + for dep in data_dependencies { + // Both creation and execution for data receipts are considered burnt gas. + burn_gas = burn_gas + .checked_add(fees_config_cfg.data_receipt_creation_config.base_cost.send_fee(*dep)) + .ok_or(VMLogicError::EvmError(EvmError::IntegerOverflow))? + .checked_add(fees_config_cfg.data_receipt_creation_config.base_cost.exec_fee()) + .ok_or(VMLogicError::EvmError(EvmError::IntegerOverflow))?; + } + use_gas = use_gas + .checked_add(burn_gas) + .ok_or(VMLogicError::EvmError(EvmError::IntegerOverflow))?; + self.gas_counter.pay_action_accumulated(burn_gas, use_gas, ActionCosts::new_receipt) + } + + fn pay_gas_from_evm_gas(&mut self, op: EvmOpForGas) -> Result<()> { + let fee_cfg = &self.fees_config.evm_config; + let evm_gas = self.evm_gas_counter.used_gas.as_u64(); + self.gas_counter.inc_evm_gas_counter(evm_gas); + let gas = match op { + EvmOpForGas::Deploy(decoded_len) => { + // gas per byte is counting hex encoded contract size (solc output, 2x of decoded len) + (decoded_len as u64 * 2) * fee_cfg.deploy_cost_per_byte + + evm_gas * fee_cfg.deploy_cost_per_evm_gas + + fee_cfg.bootstrap_cost + } + EvmOpForGas::Funcall => { + evm_gas * fee_cfg.funcall_cost_per_evm_gas + + fee_cfg.funcall_cost_base + + fee_cfg.bootstrap_cost + } + EvmOpForGas::Other => fee_cfg.bootstrap_cost, + }; + self.gas_counter.pay_evm_gas(gas) + } + + fn pay_gas_for_transfer(&mut self, account_id: &AccountId) -> Result<()> { + if is_account_id_64_len_hex(&account_id) { + self.gas_counter.pay_action_base( + &self.fees_config.action_creation_config.create_account_cost, + false, + ActionCosts::transfer, + )?; + self.gas_counter.pay_action_base( + &self.fees_config.action_creation_config.add_key_cost.full_access_cost, + false, + ActionCosts::transfer, + )?; + } + self.gas_counter.pay_action_base( + &self.fees_config.action_creation_config.transfer_cost, + false, + ActionCosts::transfer, + ) + } +} + +fn max_evm_gas_from_near_gas( + near_gas: Gas, + evm_gas_config: &EvmCostConfig, + method: &Method, + decoded_code_size: Option, +) -> Option { + match method { + Method::DeployCode => { + if near_gas < evm_gas_config.bootstrap_cost { + return None; + } + Some( + ((near_gas + - evm_gas_config.bootstrap_cost + - evm_gas_config.deploy_cost_per_byte + * (2 * decoded_code_size.unwrap() as u64)) + / evm_gas_config.deploy_cost_per_evm_gas) + .into(), + ) + } + Method::Call | Method::ViewCall | Method::MetaCall => { + if near_gas < evm_gas_config.bootstrap_cost + evm_gas_config.funcall_cost_base { + return None; + } + Some( + ((near_gas - evm_gas_config.bootstrap_cost - evm_gas_config.funcall_cost_base) + / evm_gas_config.funcall_cost_per_evm_gas) + .into(), + ) + } + _ => { + if near_gas < evm_gas_config.bootstrap_cost { + return None; + } + Some(evm_gas_config.bootstrap_cost.into()) + } + } +} + +pub fn run_evm( + ext: &mut dyn External, + chain_id: u128, + config: &VMConfig, + fees_config: &RuntimeFeesConfig, + account_id: &AccountId, + signer_id: &AccountId, + predecessor_id: &AccountId, + amount: Balance, + attached_deposit: Balance, + storage_usage: StorageUsage, + method_name: String, + args: Vec, + prepaid_gas: Gas, + is_view: bool, +) -> (Option, Option) { + let method = match Method::parse(&method_name) { + Some(method) => method, + None => { + return ( + None, + Some(VMError::FunctionCallError(FunctionCallError::EvmError( + EvmError::MethodNotFound, + ))), + ); + } + }; + + let evm_gas_result = max_evm_gas_from_near_gas( + prepaid_gas, + &fees_config.evm_config, + &method, + if method == Method::DeployCode { Some(args.len()) } else { None }, + ); + + if evm_gas_result.is_none() { + return ( + None, + Some(VMError::FunctionCallError(FunctionCallError::EvmError(EvmError::OutOfGas))), + ); + } + let evm_gas = evm_gas_result.unwrap(); + let mut context = EvmContext::new( + ext, + chain_id, + config, + fees_config, + // This is total amount of all $NEAR inside this EVM. + // Should already validate that will not overflow external to this call. + amount.checked_add(attached_deposit).unwrap_or(amount), + account_id.clone(), + signer_id.clone(), + predecessor_id.clone(), + attached_deposit, + storage_usage, + prepaid_gas, + is_view, + evm_gas, + ); + + let result = match method { + // Change the state methods. + Method::DeployCode => { + let code_len = args.len(); + context.deploy_code(args).map(|address| { + context.pay_gas_from_evm_gas(EvmOpForGas::Deploy(code_len)).unwrap(); + utils::address_to_vec(&address) + }) + } + Method::Call => { + let r = context.call_function(args.clone()); + context.pay_gas_from_evm_gas(EvmOpForGas::Funcall).unwrap(); + r + } + // TODO: MetaCalls are currently disabled + Method::MetaCall => { + let r = context.meta_call_function(args); + context.pay_gas_from_evm_gas(EvmOpForGas::Funcall).unwrap(); + r + } + Method::Deposit => { + context.deposit(args).map(|balance| utils::u256_to_arr(&balance).to_vec()) + } + Method::Withdraw => context.withdraw(args).map(|_| vec![]), + Method::Transfer => context.transfer(args).map(|_| vec![]), + // View methods. + Method::ViewCall => { + let r = context.view_call_function(args); + context.pay_gas_from_evm_gas(EvmOpForGas::Funcall).unwrap(); + r + } + Method::GetCode => context.get_code(args), + Method::GetStorageAt => context.get_storage_at(args), + Method::GetNonce => { + context.get_nonce(args).map(|nonce| utils::u256_to_arr(&nonce).to_vec()) + } + Method::GetBalance => { + context.get_balance(args).map(|balance| utils::u256_to_arr(&balance).to_vec()) + } + }; + + match result { + Ok(value) => { + let outcome = VMOutcome { + balance: context.current_amount, + storage_usage: context.storage_usage, + return_data: ReturnData::Value(value), + burnt_gas: context.gas_counter.burnt_gas(), + used_gas: context.gas_counter.used_gas(), + logs: context.logs, + }; + (Some(outcome), None) + } + Err(VMLogicError::EvmError(err)) => { + (None, Some(VMError::FunctionCallError(FunctionCallError::EvmError(err)))) + } + Err(VMLogicError::InconsistentStateError(err)) => { + (None, Some(VMError::InconsistentStateError(err))) + } + Err(VMLogicError::HostError(_)) => { + unreachable!("EVM runner shouldn't get Wasm Errors"); + } + Err(VMLogicError::ExternalError(err)) => (None, Some(VMError::ExternalError(err))), + } +} + +#[cfg(test)] +mod tests { + use near_vm_logic::mocks::mock_external::MockedExternal; + + use crate::evm_state::SubState; + + use super::*; + + const CHAIN_ID: u128 = 0x99; + + fn setup() -> (MockedExternal, VMConfig, RuntimeFeesConfig) { + let vm_config = VMConfig::default(); + let fees_config = RuntimeFeesConfig::default(); + let fake_external = MockedExternal::new(); + (fake_external, vm_config, fees_config) + } + + fn create_context<'a>( + external: &'a mut MockedExternal, + vm_config: &'a VMConfig, + fees_config: &'a RuntimeFeesConfig, + account_id: &str, + ) -> EvmContext<'a> { + EvmContext::new( + external, + CHAIN_ID, + vm_config, + fees_config, + 0, + "evm".to_string(), + account_id.to_string(), + account_id.to_string(), + 0, + 0, + 0, + false, + 1_000_000_000.into(), + ) + } + + #[test] + fn state_management() { + let (mut fake_external, vm_config, fees_config) = setup(); + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, "alice"); + let addr_0 = Address::repeat_byte(0); + let addr_1 = Address::repeat_byte(1); + let addr_2 = Address::repeat_byte(2); + + let zero = U256::zero(); + let code: [u8; 3] = [0, 1, 2]; + let nonce = U256::from_dec_str("103030303").unwrap(); + let balance = U256::from_dec_str("3838209").unwrap(); + let storage_key_0 = [4u8; 32]; + let storage_key_1 = [5u8; 32]; + let storage_value_0 = [6u8; 32]; + let storage_value_1 = [7u8; 32]; + + context.set_code(&addr_0, &code).unwrap(); + assert_eq!(context.code_at(&addr_0).unwrap(), Some(code.to_vec())); + assert_eq!(context.code_at(&addr_1).unwrap(), None); + assert_eq!(context.code_at(&addr_2).unwrap(), None); + + context.set_nonce(&addr_0, nonce).unwrap(); + assert_eq!(context.nonce_of(&addr_0).unwrap(), nonce); + assert_eq!(context.nonce_of(&addr_1).unwrap(), zero); + assert_eq!(context.nonce_of(&addr_2).unwrap(), zero); + + context.set_balance(&addr_0, balance).unwrap(); + assert_eq!(context.balance_of(&addr_0).unwrap(), balance); + assert_eq!(context.balance_of(&addr_1).unwrap(), zero); + assert_eq!(context.balance_of(&addr_2).unwrap(), zero); + + context.set_contract_storage(&addr_0, &storage_key_0, storage_value_0).unwrap(); + assert_eq!( + context.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!(context.read_contract_storage(&addr_1, &storage_key_0).unwrap(), None); + assert_eq!(context.read_contract_storage(&addr_2, &storage_key_0).unwrap(), None); + + let next = { + // Open a new store + let mut next = StateStore::default(); + let mut sub1 = SubState::new(&addr_0, &mut next, &context); + + sub1.set_code(&addr_1, &code).unwrap(); + assert_eq!(sub1.code_at(&addr_0).unwrap(), Some(code.to_vec())); + assert_eq!(sub1.code_at(&addr_1).unwrap(), Some(code.to_vec())); + assert_eq!(sub1.code_at(&addr_2).unwrap(), None); + + sub1.set_nonce(&addr_1, nonce).unwrap(); + assert_eq!(sub1.nonce_of(&addr_0).unwrap(), nonce); + assert_eq!(sub1.nonce_of(&addr_1).unwrap(), nonce); + assert_eq!(sub1.nonce_of(&addr_2).unwrap(), zero); + + sub1.set_balance(&addr_1, balance).unwrap(); + assert_eq!(sub1.balance_of(&addr_0).unwrap(), balance); + assert_eq!(sub1.balance_of(&addr_1).unwrap(), balance); + assert_eq!(sub1.balance_of(&addr_2).unwrap(), zero); + + sub1.set_contract_storage(&addr_1, &storage_key_0, storage_value_0).unwrap(); + assert_eq!( + sub1.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + sub1.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!(sub1.read_contract_storage(&addr_2, &storage_key_0).unwrap(), None); + + sub1.set_contract_storage(&addr_1, &storage_key_0, storage_value_1).unwrap(); + assert_eq!( + sub1.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + sub1.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_1) + ); + assert_eq!(sub1.read_contract_storage(&addr_2, &storage_key_0).unwrap(), None); + + sub1.set_contract_storage(&addr_1, &storage_key_1, storage_value_1).unwrap(); + assert_eq!( + sub1.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_1) + ); + assert_eq!( + sub1.read_contract_storage(&addr_1, &storage_key_1).unwrap(), + Some(storage_value_1) + ); + + sub1.set_contract_storage(&addr_1, &storage_key_0, storage_value_0).unwrap(); + assert_eq!( + sub1.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + sub1.read_contract_storage(&addr_1, &storage_key_1).unwrap(), + Some(storage_value_1) + ); + + next + }; + + context.commit_changes(&next).unwrap(); + assert_eq!(context.code_at(&addr_0).unwrap(), Some(code.to_vec())); + assert_eq!(context.code_at(&addr_1).unwrap(), Some(code.to_vec())); + assert_eq!(context.code_at(&addr_2).unwrap(), None); + assert_eq!(context.nonce_of(&addr_0).unwrap(), nonce); + assert_eq!(context.nonce_of(&addr_1).unwrap(), nonce); + assert_eq!(context.nonce_of(&addr_2).unwrap(), zero); + assert_eq!(context.balance_of(&addr_0).unwrap(), balance); + assert_eq!(context.balance_of(&addr_1).unwrap(), balance); + assert_eq!(context.balance_of(&addr_2).unwrap(), zero); + assert_eq!( + context.read_contract_storage(&addr_0, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + context.read_contract_storage(&addr_1, &storage_key_0).unwrap(), + Some(storage_value_0) + ); + assert_eq!( + context.read_contract_storage(&addr_1, &storage_key_1).unwrap(), + Some(storage_value_1) + ); + assert_eq!(context.read_contract_storage(&addr_2, &storage_key_0).unwrap(), None); + } +} diff --git a/runtime/near-evm-runner/src/types.rs b/runtime/near-evm-runner/src/types.rs new file mode 100644 index 00000000000..04dc7b16db8 --- /dev/null +++ b/runtime/near-evm-runner/src/types.rs @@ -0,0 +1,159 @@ +use std::convert::TryInto; + +use borsh::{BorshDeserialize, BorshSerialize}; +use ethereum_types::{Address, U256}; + +use near_vm_errors::{EvmError, InconsistentStateError, VMLogicError}; +use near_vm_logic::types::AccountId; + +pub type RawAddress = [u8; 20]; +pub type RawHash = [u8; 32]; +pub type RawU256 = [u8; 32]; +pub type DataKey = [u8; 52]; + +pub type Result = std::result::Result; + +#[derive(Debug, Eq, PartialEq)] +pub enum Method { + DeployCode, + Call, + MetaCall, + Deposit, + Withdraw, + Transfer, + // View methods. + ViewCall, + GetCode, + GetStorageAt, + GetNonce, + GetBalance, +} + +impl Method { + pub fn parse(method_name: &str) -> Option { + Some(match method_name { + // Change the state methods. + "deploy_code" => Self::DeployCode, + "call_function" | "call" => Self::Call, + // TODO: Meta calls are temporary disabled. + // "meta_call" => Self::MetaCall, + "deposit" => Self::Deposit, + "withdraw" => Self::Withdraw, + "transfer" => Self::Transfer, + // View methods. + "view_function_call" | "view" => Self::ViewCall, + "get_code" => Self::GetCode, + "get_storage_at" => Self::GetStorageAt, + "get_nonce" => Self::GetNonce, + "get_balance" => Self::GetBalance, + _ => return None, + }) + } +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct AddressArg { + pub address: RawAddress, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct GetStorageAtArgs { + pub address: RawAddress, + pub key: RawHash, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct WithdrawArgs { + pub account_id: AccountId, + pub amount: RawU256, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct TransferArgs { + pub address: RawAddress, + pub amount: RawU256, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct FunctionCallArgs { + pub contract: RawAddress, + pub input: Vec, +} + +#[derive(BorshSerialize, BorshDeserialize, Debug, Eq, PartialEq)] +pub struct ViewCallArgs { + pub sender: RawAddress, + pub address: RawAddress, + pub amount: RawU256, + pub input: Vec, +} + +pub struct MetaCallArgs { + pub sender: Address, + pub nonce: U256, + pub fee_amount: U256, + pub fee_address: Address, + pub contract_address: Address, + pub input: Vec, +} + +pub fn convert_vm_error(err: vm::Error) -> VMLogicError { + match err { + vm::Error::OutOfGas => VMLogicError::EvmError(EvmError::OutOfGas), + vm::Error::BadJumpDestination { destination } => { + VMLogicError::EvmError(EvmError::BadJumpDestination { + destination: destination.try_into().unwrap_or(0), + }) + } + vm::Error::BadInstruction { instruction } => { + VMLogicError::EvmError(EvmError::BadInstruction { instruction }) + } + vm::Error::StackUnderflow { instruction, wanted, on_stack } => { + VMLogicError::EvmError(EvmError::StackUnderflow { + instruction: instruction.to_string(), + wanted: wanted.try_into().unwrap_or(0), + on_stack: on_stack.try_into().unwrap_or(0), + }) + } + vm::Error::OutOfStack { instruction, wanted, limit } => { + VMLogicError::EvmError(EvmError::OutOfStack { + instruction: instruction.to_string(), + wanted: wanted.try_into().unwrap_or(0), + limit: limit.try_into().unwrap_or(0), + }) + } + vm::Error::BuiltIn(msg) => VMLogicError::EvmError(EvmError::BuiltIn(msg.to_string())), + vm::Error::MutableCallInStaticContext => VMLogicError::EvmError(EvmError::OutOfBounds), + vm::Error::Internal(err) => { + VMLogicError::InconsistentStateError(InconsistentStateError::StorageError(err)) + } + // This should not happen ever, because NEAR EVM is not using WASM. + vm::Error::Wasm(_) => unreachable!(), + vm::Error::OutOfBounds => VMLogicError::EvmError(EvmError::OutOfBounds), + vm::Error::Reverted => VMLogicError::EvmError(EvmError::Reverted), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_roundtrip_view_call() { + let x = ViewCallArgs { + sender: [1; 20], + address: [2; 20], + amount: [3; 32], + input: vec![1, 2, 3], + }; + let bytes = x.try_to_vec().unwrap(); + let res = ViewCallArgs::try_from_slice(&bytes).unwrap(); + assert_eq!(x, res); + } + + #[test] + fn test_view_call_fail() { + let bytes = [0; 71]; + let _ = ViewCallArgs::try_from_slice(&bytes).unwrap_err(); + } +} diff --git a/runtime/near-evm-runner/src/utils.rs b/runtime/near-evm-runner/src/utils.rs new file mode 100644 index 00000000000..c98d1184021 --- /dev/null +++ b/runtime/near-evm-runner/src/utils.rs @@ -0,0 +1,317 @@ +use std::io::Write; + +use borsh::BorshSerialize; +use byteorder::WriteBytesExt; +use ethereum_types::{Address, H160, H256, U256}; +use keccak_hash::keccak; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use vm::CreateContractAddress; + +use crate::types::{ + DataKey, FunctionCallArgs, MetaCallArgs, RawAddress, RawHash, RawU256, Result, ViewCallArgs, +}; +use near_vm_errors::{EvmError, VMLogicError}; +use near_vm_logic::types::AccountId; + +pub fn saturating_next_address(addr: &RawAddress) -> RawAddress { + let mut expanded_addr = [255u8; 32]; + expanded_addr[12..].copy_from_slice(addr); + let mut result = [0u8; 32]; + U256::from_big_endian(&expanded_addr) + .saturating_add(U256::from(1u8)) + .to_big_endian(&mut result); + let mut address = [0u8; 20]; + address.copy_from_slice(&result[12..]); + address +} + +pub fn internal_storage_key(address: &Address, key: &RawU256) -> DataKey { + let mut k = [0u8; 52]; + k[..20].copy_from_slice(address.as_ref()); + k[20..].copy_from_slice(key); + k +} + +pub fn near_account_bytes_to_evm_address(addr: &[u8]) -> Address { + Address::from_slice(&keccak(addr)[12..]) +} + +pub fn near_account_id_to_evm_address(account_id: &str) -> Address { + near_account_bytes_to_evm_address(&account_id.as_bytes().to_vec()) +} + +pub fn encode_call_function_args(address: Address, input: Vec) -> Vec { + FunctionCallArgs { contract: address.into(), input }.try_to_vec().unwrap() +} + +pub fn split_data_key(key: &DataKey) -> (Address, RawU256) { + let mut addr = [0u8; 20]; + addr.copy_from_slice(&key[..20]); + let mut subkey = [0u8; 32]; + subkey.copy_from_slice(&key[20..]); + (H160(addr), subkey) +} + +pub fn combine_data_key(addr: &Address, subkey: &RawU256) -> DataKey { + let mut key = [0u8; 52]; + key[..20].copy_from_slice(&addr.0); + key[20..52].copy_from_slice(subkey); + key +} + +pub fn encode_view_call_function_args( + sender: Address, + address: Address, + amount: U256, + input: Vec, +) -> Vec { + ViewCallArgs { sender: sender.into(), address: address.into(), amount: amount.into(), input } + .try_to_vec() + .unwrap() +} + +pub fn address_from_arr(arr: &[u8]) -> Address { + assert_eq!(arr.len(), 20); + let mut address = [0u8; 20]; + address.copy_from_slice(&arr); + Address::from(address) +} + +pub fn u256_to_arr(val: &U256) -> RawU256 { + let mut result = [0u8; 32]; + val.to_big_endian(&mut result); + result +} + +pub fn address_to_vec(val: &Address) -> Vec { + val.to_fixed_bytes().to_vec() +} + +pub fn vec_to_arr_32(v: Vec) -> Option { + if v.len() != 32 { + return None; + } + let mut result = [0; 32]; + result.copy_from_slice(&v); + Some(result) +} + +/// Returns new address created from address, nonce, and code hash +/// Copied directly from the parity codebase +pub fn evm_contract_address( + address_scheme: CreateContractAddress, + sender: &Address, + nonce: &U256, + code: &[u8], +) -> (Address, Option) { + use rlp::RlpStream; + + match address_scheme { + CreateContractAddress::FromSenderAndNonce => { + let mut stream = RlpStream::new_list(2); + stream.append(sender); + stream.append(nonce); + (From::from(keccak(stream.as_raw())), None) + } + CreateContractAddress::FromSenderSaltAndCodeHash(salt) => { + let code_hash = keccak(code); + let mut buffer = [0u8; 1 + 20 + 32 + 32]; + buffer[0] = 0xff; + buffer[1..(1 + 20)].copy_from_slice(&sender[..]); + buffer[(1 + 20)..(1 + 20 + 32)].copy_from_slice(&salt[..]); + buffer[(1 + 20 + 32)..].copy_from_slice(&code_hash[..]); + (From::from(keccak(&buffer[..])), Some(code_hash)) + } + CreateContractAddress::FromSenderAndCodeHash => { + let code_hash = keccak(code); + let mut buffer = [0u8; 20 + 32]; + buffer[..20].copy_from_slice(&sender[..]); + buffer[20..].copy_from_slice(&code_hash[..]); + (From::from(keccak(&buffer[..])), Some(code_hash)) + } + } +} + +#[derive(Eq, PartialEq, Debug, Ord, PartialOrd)] +pub struct Balance(pub u128); + +impl Balance { + pub fn from_be_bytes(bytes: [u8; 16]) -> Self { + Balance(u128::from_be_bytes(bytes)) + } + + pub fn to_be_bytes(&self) -> [u8; 16] { + self.0.to_be_bytes() + } +} + +impl Serialize for Balance { + fn serialize( + &self, + serializer: S, + ) -> std::result::Result<::Ok, ::Error> + where + S: Serializer, + { + serializer.serialize_str(&format!("{}", &self.0)) + } +} + +impl<'de> Deserialize<'de> for Balance { + fn deserialize(deserializer: D) -> std::result::Result>::Error> + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + u128::from_str_radix(&s, 10).map(Balance).map_err(serde::de::Error::custom) + } +} + +impl From for u128 { + fn from(balance: Balance) -> Self { + balance.0 + } +} + +pub fn format_log(topics: Vec, data: &[u8]) -> std::result::Result, std::io::Error> { + let mut result = Vec::with_capacity(1 + topics.len() * 32 + data.len()); + result.write_u8(topics.len() as u8)?; + for topic in topics.iter() { + result.write(&topic.0)?; + } + result.write(data)?; + Ok(result) +} + +pub fn near_erc721_domain(chain_id: U256) -> RawU256 { + let mut bytes = Vec::with_capacity(70); + bytes.extend_from_slice( + &keccak("EIP712Domain(string name,string version,uint256 chainId)".as_bytes()).as_bytes(), + ); + bytes.extend_from_slice(b"NEAR"); + bytes.extend_from_slice(&[0x01]); + bytes.extend_from_slice(&u256_to_arr(&chain_id)); + keccak(&bytes).into() +} + +pub fn method_name_to_rlp(method_name: String) -> [u8; 4] { + let mut result = [0u8; 4]; + result.copy_from_slice(&keccak(method_name)[..4]); + result +} + +pub fn prepare_meta_call_args( + domain_separator: &RawU256, + account_id: &AccountId, + nonce: U256, + fee_amount: U256, + fee_address: Address, + contract_address: Address, + method_name: &str, + args: &[u8], +) -> RawU256 { + let mut bytes = Vec::with_capacity(32 + 32 + 20 + account_id.len() + 4 + args.len()); + bytes.extend_from_slice( + &keccak( + "NearTx(string evmId, uint256 nonce, uint256 feeAmount, uint256 feeAddress, address contractAddress, string contractMethod, Arguments arguments)" + .as_bytes(), + ) + .as_bytes(), + ); + bytes.extend_from_slice(account_id.as_bytes()); + bytes.extend_from_slice(&u256_to_arr(&nonce)); + bytes.extend_from_slice(&u256_to_arr(&fee_amount)); + bytes.extend_from_slice(&fee_address.0); + bytes.extend_from_slice(&contract_address.0); + bytes.extend_from_slice(&method_name.as_bytes()); + // TODO: hash? + bytes.extend_from_slice(args); + let message: RawU256 = keccak(&bytes).into(); + let mut bytes = Vec::with_capacity(2 + 32 + 32); + bytes.extend_from_slice(&[0x19, 0x01]); + bytes.extend_from_slice(domain_separator); + bytes.extend_from_slice(&message); + keccak(&bytes).into() +} + +/// Format +/// [0..65): signature: v - 1 byte, s - 32 bytes, r - 32 bytes +/// [65..97): nonce: nonce of the `signer` account of the `signature`. +/// : fee_amount +/// : fee_address +/// [97..117): contract_id: address for contract to call +/// : method_name_length +/// : method_name +/// 117..: RLP encoded rest of arguments. +pub fn parse_meta_call( + domain_separator: &RawU256, + account_id: &AccountId, + args: Vec, +) -> Result { + if args.len() <= 169 { + return Err(VMLogicError::EvmError(EvmError::ArgumentParseError)); + } + let mut signature: [u8; 65] = [0; 65]; + // Signatures coming from outside are srv but ecrecover takes vsr, so move last byte to first position. + // TODO: There is overflow. + signature[0] = args[64] + 27; + signature[1..].copy_from_slice(&args[..64]); + let nonce = U256::from_big_endian(&args[65..97]); + let fee_amount = U256::from_big_endian(&args[97..129]); + let fee_address = Address::from_slice(&args[129..149]); + let contract_address = Address::from_slice(&args[149..169]); + let method_name_len = args[169] as usize; + if args.len() < method_name_len + 170 { + return Err(VMLogicError::EvmError(EvmError::ArgumentParseError)); + } + let method_name = String::from_utf8(args[170..170 + method_name_len].to_vec()) + .map_err(|_| VMLogicError::EvmError(EvmError::ArgumentParseError))?; + let args = &args[170 + method_name_len..]; + + let msg = prepare_meta_call_args( + domain_separator, + account_id, + nonce, + fee_amount, + fee_address, + contract_address, + &method_name, + args, + ); + let sender = ecrecover_address(&msg, &signature); + if sender == Address::zero() { + return Err(VMLogicError::EvmError(EvmError::InvalidEcRecoverSignature)); + } + let method_name_rlp = method_name_to_rlp(method_name); + let input = [method_name_rlp.to_vec(), args.to_vec()].concat(); + Ok(MetaCallArgs { sender, nonce, fee_amount, fee_address, contract_address, input }) +} + +/// Given signature and data, validates that signature is valid for given data and returns ecrecover address. +/// If signature is invalid or doesn't match, returns 0x0 address. +pub fn ecrecover_address(hash: &RawHash, signature: &[u8; 65]) -> Address { + use sha3::Digest; + + let hash = secp256k1::Message::parse(&H256::from_slice(hash).0); + let v = &signature[0]; + let bit = match v { + 27..=30 => v - 27, + _ => { + // ?? + return Address::zero(); + } + }; + + let mut sig = [0u8; 64]; + sig.copy_from_slice(&signature[1..]); + let s = secp256k1::Signature::parse(&sig); + + if let Ok(rec_id) = secp256k1::RecoveryId::parse(bit) { + if let Ok(p) = secp256k1::recover(&hash, &s, &rec_id) { + // recover returns the 65-byte key, but addresses come from the raw 64-byte key + let r = sha3::Keccak256::digest(&p.serialize()[1..]); + return address_from_arr(&r[12..]); + } + } + Address::zero() +} diff --git a/runtime/near-evm-runner/tests/build.sh b/runtime/near-evm-runner/tests/build.sh new file mode 100755 index 00000000000..f6245fa2712 --- /dev/null +++ b/runtime/near-evm-runner/tests/build.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +contracts=( + "SolTests" + "SubContract" + "Create2Factory" + "SelfDestruct" + "ConstructorRevert" + "PrecompiledFunction" +) + +truffle compile || exit 1 +for contractName in "${contracts[@]}" + do + cat build/contracts/"$contractName".json | \ + jq .bytecode | \ + awk '{ print substr($1,4,length($1)-4) }' | \ + tr -d '\n' \ + > build/"$contractName".bin + + cat build/contracts/"$contractName".json | \ + jq .abi \ + > build/"$contractName".abi + done +rm -rf build/contracts diff --git a/runtime/near-evm-runner/tests/build/BBronze.abi b/runtime/near-evm-runner/tests/build/BBronze.abi new file mode 100644 index 00000000000..ff6c870a05c --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BBronze.abi @@ -0,0 +1,17 @@ +[ + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/BBronze.bin b/runtime/near-evm-runner/tests/build/BBronze.bin new file mode 100644 index 00000000000..9bbf2865e61 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BBronze.bin @@ -0,0 +1 @@ +6080604052348015600f57600080fd5b5060ba8061001e6000396000f3fe6080604052348015600f57600080fd5b50600436106044577c010000000000000000000000000000000000000000000000000000000060003504639a86139b81146049575b600080fd5b604f6061565b60408051918252519081900360200190f35b7f42524f4e5a4500000000000000000000000000000000000000000000000000009056fea265627a7a72315820d02b5140da771a0eb87c9231627fadfdca36c5c04f502cc3fe1163438b04bda664736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/BColor.abi b/runtime/near-evm-runner/tests/build/BColor.abi new file mode 100644 index 00000000000..ff6c870a05c --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BColor.abi @@ -0,0 +1,17 @@ +[ + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/BConst.abi b/runtime/near-evm-runner/tests/build/BConst.abi new file mode 100644 index 00000000000..42a7386d836 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BConst.abi @@ -0,0 +1,257 @@ +[ + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/BConst.bin b/runtime/near-evm-runner/tests/build/BConst.bin new file mode 100644 index 00000000000..df5ec05428b --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BConst.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b5061029c806100206000396000f3fe608060405234801561001057600080fd5b5060043610610108576000357c010000000000000000000000000000000000000000000000000000000090048063b0e0d136116100af578063b0e0d1361461015f578063b7b800a414610167578063ba019dab1461016f578063bc063e1a14610177578063bc694ea21461017f578063c36596a61461012f578063c6580d1214610187578063e4a28a521461010d578063ec0930211461018f57610108565b806309a3bbe41461010d578063189d00ca14610127578063218b53821461012f57806376c7a3c714610137578063867378c51461013f5780639381cd2b14610147578063992e2a921461014f5780639a86139b14610157575b600080fd5b610115610197565b60408051918252519081900360200190f35b6101156101a4565b6101156101b8565b6101156101c4565b6101156101d6565b6101156101ea565b6101156101f7565b610115610203565b610115610227565b61011561022c565b610115610231565b610115610236565b610115610246565b610115610252565b610115610257565b6802b5e3af16b188000081565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b620f4240670de0b6b3a76400006101b4565b64e8d4a51000670de0b6b3a76400006101b4565b68056bc75e2d6310000081565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600881565b600281565b600181565b600a670de0b6b3a76400006101b4565b671bc16d674ec7ffff81565b600081565b6002670de0b6b3a76400006101b456fea265627a7a72315820a3ed3e544d5a2480a4ca8e33cf23ff0c96b482b4cef52e564e7ba36b9ce3855064736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/BFactory.abi b/runtime/near-evm-runner/tests/build/BFactory.abi new file mode 100644 index 00000000000..2946beca8ae --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BFactory.abi @@ -0,0 +1,142 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "blabs", + "type": "address" + } + ], + "name": "LOG_BLABS", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "LOG_NEW_POOL", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "b", + "type": "address" + } + ], + "name": "isBPool", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "newBPool", + "outputs": [ + { + "internalType": "contract BPool", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getBLabs", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "b", + "type": "address" + } + ], + "name": "setBLabs", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "contract BPool", + "name": "pool", + "type": "address" + } + ], + "name": "collect", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/BFactory.bin b/runtime/near-evm-runner/tests/build/BFactory.bin new file mode 100644 index 00000000000..c025ffa35ec --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BFactory.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b5060018054600160a060020a03191633179055615fb1806100326000396000f3fe608060405234801561001057600080fd5b506004361061007e577c0100000000000000000000000000000000000000000000000000000000600035046306ec16f8811461008357806336ffb167146100ab5780639a86139b146100cf578063c2bb6dc2146100e9578063c6ce34fb14610123578063d556c5dc14610149575b600080fd5b6100a96004803603602081101561009957600080fd5b5035600160a060020a0316610151565b005b6100b361033e565b60408051600160a060020a039092168252519081900360200190f35b6100d761034d565b60408051918252519081900360200190f35b61010f600480360360208110156100ff57600080fd5b5035600160a060020a0316610371565b604080519115158252519081900360200190f35b6100a96004803603602081101561013957600080fd5b5035600160a060020a031661038f565b6100b3610456565b600154600160a060020a031633146101b3576040805160e560020a62461bcd02815260206004820152600d60248201527f4552525f4e4f545f424c41425300000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600091600160a060020a038416916370a0823191602480820192602092909190829003018186803b15801561021657600080fd5b505afa15801561022a573d6000803e3d6000fd5b505050506040513d602081101561024057600080fd5b5051600154604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a0392831660048201526024810184905290519293506000929185169163a9059cbb9160448082019260209290919082900301818787803b1580156102b657600080fd5b505af11580156102ca573d6000803e3d6000fd5b505050506040513d60208110156102e057600080fd5b5051905080610339576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f45524332305f4641494c454400000000000000000000000000000000604482015290519081900360640190fd5b505050565b600154600160a060020a031690565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600160a060020a031660009081526020819052604090205460ff1690565b600154600160a060020a031633146103f1576040805160e560020a62461bcd02815260206004820152600d60248201527f4552525f4e4f545f424c41425300000000000000000000000000000000000000604482015290519081900360640190fd5b604051600160a060020a0382169033907ff586fa6ee1fc42f5b727f3b214ccbd0b6d7e698c45d49ba32f224fbb8670155d90600090a36001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6000806040516104659061054f565b604051809103906000f080158015610481573d6000803e3d6000fd5b50600160a060020a038116600081815260208190526040808220805460ff1916600117905551929350909133917f8ccec77b0cb63ac2cafd0f5de8cdfadab91ce656d262240ba8a6343bccc5f94591a3604080517f92eefe9b0000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a038316916392eefe9b91602480830192600092919082900301818387803b15801561053157600080fd5b505af1158015610545573d6000803e3d6000fd5b5092935050505090565b615a208061055d8339019056fe60c0604052601360808190527f42616c616e63657220506f6f6c20546f6b656e0000000000000000000000000060a0908152620000409160039190620000f7565b506040805180820190915260038082527f425054000000000000000000000000000000000000000000000000000000000060209092019182526200008791600491620000f7565b506005805460ff19166012179055348015620000a257600080fd5b5060068054600580546201000060b060020a031916336201000081029190911790915564e8d4a51000600755600160a060020a03199091161760a060020a60ff02191690556008805460ff191690556200019c565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200013a57805160ff19168380011785556200016a565b828001600101855582156200016a579182015b828111156200016a5782518255916020019190600101906200014d565b50620001789291506200017c565b5090565b6200019991905b8082111562000178576000815560010162000183565b90565b61587480620001ac6000396000f3fe608060405234801561001057600080fd5b5060043610610378576000357c0100000000000000000000000000000000000000000000000000000000900480638d4e4083116101e7578063bc694ea211610122578063d73dd623116100c5578063d73dd62314610b7f578063dd62ed3e14610bab578063e4a28a521461047e578063e4e1e53814610bd9578063ec09302114610c0b578063f1b8a9b714610c13578063f8b2cb4f14610c39578063f8d6aed414610c5f578063fde924f714610c9a57610378565b8063bc694ea214610ad9578063be3bbd2e14610ae1578063c36596a6146104f2578063c6580d1214610b39578063cc77828d14610b41578063cd2ed8fb14610b49578063cf5e7bd314610b51578063d4cadf6814610b7757610378565b8063a221ee491161018a578063a221ee49146109a6578063a9059cbb146109db578063b02f0b7314610a07578063b0e0d13614610a7e578063b7b800a414610a86578063ba019dab14610a8e578063ba9530a614610a96578063bc063e1a14610ad157610378565b80638d4e40831461092a57806392eefe9b14610932578063936c3477146109585780639381cd2b14610960578063948d8ce61461096857806395d89b411461098e578063992e2a92146109965780639a86139b1461099e57610378565b806349b59552116102b757806376c7a3c71161025a57806376c7a3c7146107aa5780637c5e9ea4146107b25780638201aa3f1461080b57806382f652ad1461084b5780638656b65314610886578063867378c5146108c157806389298012146108c95780638c28cbe81461090457610378565b806349b595521461061b5780634bb278f31461063a5780634f69c0d4146106425780635c1bbaf7146106b95780635db34277146106f457806366188463146107265780636d06dfa01461075257806370a082311461078457610378565b8063218b53821161031f578063218b5382146104f257806323b872dd146104fa5780632f37b624146105305780633018205f14610556578063313ce5671461057a57806334e19907146105985780633fdddaa2146105b757806346ab38f1146105e957610378565b806302c967481461037d57806306fdde03146103c1578063095ea7b31461043e57806309a3bbe41461047e5780631446a7ff1461048657806315e84af9146104b457806318160ddd146104e2578063189d00ca146104ea575b600080fd5b6103af6004803603606081101561039357600080fd5b50600160a060020a038135169060208101359060400135610ca2565b60408051918252519081900360200190f35b6103c9610fef565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104035781810151838201526020016103eb565b50505050905090810190601f1680156104305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61046a6004803603604081101561045457600080fd5b50600160a060020a038135169060200135611085565b604080519115158252519081900360200190f35b6103af6110da565b6103af6004803603604081101561049c57600080fd5b50600160a060020a03813581169160200135166110e7565b6103af600480360360408110156104ca57600080fd5b50600160a060020a0381358116916020013516611241565b6103af611392565b6103af611398565b6103af6113ac565b61046a6004803603606081101561051057600080fd5b50600160a060020a038135811691602081013590911690604001356113b8565b61046a6004803603602081101561054657600080fd5b5035600160a060020a031661151d565b61055e61153b565b60408051600160a060020a039092168252519081900360200190f35b61058261159c565b6040805160ff9092168252519081900360200190f35b6105b5600480360360208110156105ae57600080fd5b50356115a5565b005b6105b5600480360360608110156105cd57600080fd5b50600160a060020a0381351690602081013590604001356117c9565b6103af600480360360608110156105ff57600080fd5b50600160a060020a038135169060208101359060400135611c15565b6105b56004803603602081101561063157600080fd5b50351515611f01565b6105b5612092565b6105b56004803603604081101561065857600080fd5b8135919081019060408101602082013564010000000081111561067a57600080fd5b82018360208201111561068c57600080fd5b803590602001918460208302840111640100000000831117156106ae57600080fd5b5090925090506122a9565b6103af600480360360c08110156106cf57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135612590565b6103af6004803603606081101561070a57600080fd5b50600160a060020a038135169060208101359060400135612648565b61046a6004803603604081101561073c57600080fd5b50600160a060020a038135169060200135612919565b6103af6004803603606081101561076857600080fd5b50600160a060020a0381351690602081013590604001356129f1565b6103af6004803603602081101561079a57600080fd5b5035600160a060020a0316612cf0565b6103af612d0b565b6107f2600480360360a08110156107c857600080fd5b50600160a060020a0381358116916020810135916040820135169060608101359060800135612d1d565b6040805192835260208301919091528051918290030190f35b6107f2600480360360a081101561082157600080fd5b50600160a060020a038135811691602081013591604082013516906060810135906080013561320d565b6103af600480360360c081101561086157600080fd5b5080359060208101359060408101359060608101359060808101359060a001356136e4565b6103af600480360360c081101561089c57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356137a3565b6103af613844565b6103af600480360360c08110156108df57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135613858565b6105b56004803603602081101561091a57600080fd5b5035600160a060020a0316613908565b61046a613ad9565b6105b56004803603602081101561094857600080fd5b5035600160a060020a0316613ae2565b6103af613c2c565b6103af613c84565b6103af6004803603602081101561097e57600080fd5b5035600160a060020a0316613c91565b6103c9613d5f565b6103af613dc0565b6103af613dcc565b6103af600480360360a08110156109bc57600080fd5b5080359060208101359060408101359060608101359060800135613df0565b61046a600480360360408110156109f157600080fd5b50600160a060020a038135169060200135613e55565b6105b560048036036040811015610a1d57600080fd5b81359190810190604081016020820135640100000000811115610a3f57600080fd5b820183602082011115610a5157600080fd5b80359060200191846020830284011164010000000083111715610a7357600080fd5b509092509050613e6b565b6103af61419f565b6103af6141a4565b6103af6141a9565b6103af600480360360c0811015610aac57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356141ae565b6103af61422f565b6103af61423f565b610ae961424b565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610b25578181015183820152602001610b0d565b505050509050019250505060405180910390f35b6103af614343565b610ae9614348565b6103af614399565b6105b560048036036020811015610b6757600080fd5b5035600160a060020a031661439f565b6103af61472c565b61046a60048036036040811015610b9557600080fd5b50600160a060020a038135169060200135614784565b6103af60048036036040811015610bc157600080fd5b50600160a060020a0381358116916020013516614805565b6105b560048036036060811015610bef57600080fd5b50600160a060020a038135169060208101359060400135614830565b6103af614ab4565b6103af60048036036020811015610c2957600080fd5b5035600160a060020a0316614ac4565b6103af60048036036020811015610c4f57600080fd5b5035600160a060020a0316614ba4565b6103af600480360360c0811015610c7557600080fd5b5080359060208101359060408101359060608101359060808101359060a00135614c72565b61046a614cf5565b600033600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615610d53576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16610daa576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a602052604090205460ff16610e08576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a60205260409020600390810154610e3d91670de0b6b3a76400005b04600101614d05565b831115610e82576040805160e560020a62461bcd02815260206004820152601160248201526000805160206156e0833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a6020526040902060038101546002808301549054600b54600754610ebc949392919089906136e4565b915081610f01576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b82821115610f47576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206156c0833981519152604482015290519081900360640190fd5b610f55816003015485614dee565b60038201556000610f668382614d05565b604080518781529051919250600160a060020a0388169133916000805160206157a0833981519152919081900360200190a3610fa23384614e5f565b610fb4610faf8483614dee565b614e6d565b600554610fd090620100009004600160a060020a031682614e79565b610fdb863387614e83565b50506005805461ff00191690559392505050565b60038054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561107b5780601f106110505761010080835404028352916020019161107b565b820191906000526020600020905b81548152906001019060200180831161105e57829003601f168201915b5050505050905090565b336000818152600160209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390926000805160206157c0833981519152928290030190a35060015b92915050565b6802b5e3af16b188000081565b600554600090610100900460ff1615611138576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090205460ff16611196576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff166111f4576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a038084166000908152600a602052604080822092851682528120600380840154600280860154928401549084015493946112389492939290613df0565b95945050505050565b600554600090610100900460ff1615611292576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090205460ff166112f0576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff1661134e576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a038084166000908152600a602052604080822092851682529020600380830154600280850154928401549084015460075461123894929190613df0565b60025490565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b600033600160a060020a03851614806113f45750600160a060020a03841660009081526001602090815260408083203384529091529020548211155b611448576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f42544f4b454e5f4241445f43414c4c45520000000000000000000000604482015290519081900360640190fd5b611453848484614f78565b33600160a060020a038516148015906114915750600160a060020a038416600090815260016020908152604080832033845290915290205460001914155b1561151357600160a060020a03841660009081526001602090815260408083203384529091529020546114c49083614dee565b600160a060020a03858116600090815260016020908152604080832033808552908352928190208590558051948552519287169391926000805160206157c08339815191529281900390910190a35b5060019392505050565b600160a060020a03166000908152600a602052604090205460ff1690565b600554600090610100900460ff161561158c576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b50600654600160a060020a031690565b60055460ff1690565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615611654576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16156116ac576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b600654600160a060020a031633146116fc576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b64e8d4a51000811015611759576040805160e560020a62461bcd02815260206004820152600b60248201527f4552525f4d494e5f464545000000000000000000000000000000000000000000604482015290519081900360640190fd5b67016345785d8a00008111156117b9576040805160e560020a62461bcd02815260206004820152600b60248201527f4552525f4d41585f464545000000000000000000000000000000000000000000604482015290519081900360640190fd5b6007556005805461ff0019169055565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615611878576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560065433600160a060020a03909116146118d9576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090205460ff16611937576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b60085460ff1615611980576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b670de0b6b3a76400008110156119e0576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f4d494e5f574549474854000000000000000000000000000000000000604482015290519081900360640190fd5b6802b5e3af16b1880000811115611a41576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f4d41585f574549474854000000000000000000000000000000000000604482015290519081900360640190fd5b620f4240821015611a9c576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4d494e5f42414c414e43450000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090206002015480821115611b3f57611ad5600b54611ad08484614dee565b615082565b600b8190556802b5e3af16b18800001015611b3a576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f4d41585f544f54414c5f574549474854000000000000000000000000604482015290519081900360640190fd5b611b60565b80821015611b6057611b5c600b54611b578385614dee565b614dee565b600b555b600160a060020a0384166000908152600a602052604090206002810183905560030180549084905580841115611ba957611ba48533611b9f8785614dee565b6150df565b611c03565b80841015611c03576000611bbd8286614dee565b90506000611bcc826000614d05565b9050611be28733611bdd8585614dee565b614e83565b600554611c00908890620100009004600160a060020a031683614e83565b50505b50506005805461ff0019169055505050565b600033600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615611cc6576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16611d1d576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a602052604090205460ff16611d7b576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a6020526040902060038101546002808301549054600b54600754611db594939291908990613858565b915082821015611dfd576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615800833981519152604482015290519081900360640190fd5b600160a060020a0385166000908152600a60205260409020600390810154611e2d91670de0b6b3a7640000610e34565b821115611e72576040805160e560020a62461bcd02815260206004820152601160248201526000805160206156e0833981519152604482015290519081900360640190fd5b611e80816003015483614dee565b60038201556000611e918582614d05565b604080518581529051919250600160a060020a0388169133916000805160206157a0833981519152919081900360200190a3611ecd3386614e5f565b611eda610faf8683614dee565b600554611ef690620100009004600160a060020a031682614e79565b610fdb863385614e83565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615611fb0576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff1615612008576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b600654600160a060020a03163314612058576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b6006805491151560a060020a0274ff0000000000000000000000000000000000000000199092169190911790556005805461ff0019169055565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615612141576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560065433600160a060020a03909116146121a2576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b60085460ff16156121eb576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b60095460021115612246576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f4d494e5f544f4b454e53000000000000000000000000000000000000604482015290519081900360640190fd5b6008805460ff191660011790556006805474ff0000000000000000000000000000000000000000191660a060020a17905561228968056bc75e2d63100000615151565b61229c3368056bc75e2d63100000614e79565b6005805461ff0019169055565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615612358576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff166123af576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b60006123b9611392565b905060006123c7858361515a565b90508061240c576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b60005b60095481101561257c5760006009828154811061242857fe5b6000918252602080832090910154600160a060020a0316808352600a90915260408220600301549092509061245d8583614d05565b9050806124a2576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b8787858181106124ae57fe5b905060200201358111156124fa576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206156c0833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a60205260409020600301546125209082615082565b600160a060020a0384166000818152600a60209081526040918290206003019390935580518481529051919233926000805160206157008339815191529281900390910190a36125718333836150df565b50505060010161240f565b5061258685615151565b611c033386614e79565b60008061259d878661515a565b905060006125ab8786615082565b905060006125b9828961515a565b905060006125cf670de0b6b3a76400008561515a565b905060006125dd8383615296565b905060006125eb828e614d05565b905060006125f9828f614dee565b90506000612618612612670de0b6b3a76400008a614dee565b8b614d05565b905061263582612630670de0b6b3a764000084614dee565b61515a565b9f9e505050505050505050505050505050565b600033600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff16156126f9576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16612750576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a602052604090205460ff166127ae576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a60205260409020600301546127e0906002670de0b6b3a76400005b04614d05565b831115612825576040805160e560020a62461bcd0281526020600482015260106024820152600080516020615740833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a6020526040902060038101546002808301549054600b5460075461285f949392919089906137a3565b9150828210156128a7576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615800833981519152604482015290519081900360640190fd5b6128b5816003015485615082565b6003820155604080518581529051600160a060020a0387169133916000805160206157008339815191529181900360200190a36128f182615151565b6128fb3383614e79565b6129068533866150df565b506005805461ff00191690559392505050565b336000908152600160209081526040808320600160a060020a03861684529091528120548083111561296e57336000908152600160209081526040808320600160a060020a038816845290915281205561299d565b6129788184614dee565b336000908152600160209081526040808320600160a060020a03891684529091529020555b336000818152600160209081526040808320600160a060020a0389168085529083529281902054815190815290519293926000805160206157c0833981519152929181900390910190a35060019392505050565b600033600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615612aa2576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16612af9576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a602052604090205460ff16612b57576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a6020526040902060038101546002808301549054600b54600754612b9194939291908990612590565b915081612bd6576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b82821115612c1c576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206156c0833981519152604482015290519081900360640190fd5b600160a060020a0385166000908152600a6020526040902060030154612c4c906002670de0b6b3a76400006127da565b821115612c91576040805160e560020a62461bcd0281526020600482015260106024820152600080516020615740833981519152604482015290519081900360640190fd5b612c9f816003015483615082565b6003820155604080518381529051600160a060020a0387169133916000805160206157008339815191529181900360200190a3612cdb84615151565b612ce53385614e79565b6129068533846150df565b600160a060020a031660009081526020819052604090205490565b620f4240670de0b6b3a76400006113a8565b6040805160208082523690820181905260009283923392600160e060020a03198535169285929081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615612dbd576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff001916610100179055600160a060020a0387166000908152600a602052604090205460ff16612e2a576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0385166000908152600a602052604090205460ff16612e88576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b60065460a060020a900460ff16612ee9576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f535741505f4e4f545f5055424c494300000000000000000000000000604482015290519081900360640190fd5b600160a060020a038088166000908152600a602052604080822092881682529020600380820154612f2291670de0b6b3a7640000610e34565b861115612f67576040805160e560020a62461bcd02815260206004820152601160248201526000805160206156e0833981519152604482015290519081900360640190fd5b6000612f888360030154846002015484600301548560020154600754613df0565b905085811115612fe2576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f4241445f4c494d49545f505249434500000000000000000000000000604482015290519081900360640190fd5b61300283600301548460020154846003015485600201548b600754614c72565b94508885111561304a576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206156c0833981519152604482015290519081900360640190fd5b613058836003015486615082565b836003018190555061306e826003015488614dee565b600380840182905584015460028086015490850154600754613091949190613df0565b9350808410156130d9576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b85841115613131576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4c494d49545f50524943450000000000000000000000000000000000604482015290519081900360640190fd5b61313b858861515a565b811115613180576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b87600160a060020a03168a600160a060020a031633600160a060020a03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378888b604051808381526020018281526020019250505060405180910390a46131e88a33876150df565b6131f3883389614e83565b5050506005805461ff001916905590969095509350505050565b6040805160208082523690820181905260009283923392600160e060020a03198535169285929081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff16156132ad576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff001916610100179055600160a060020a0387166000908152600a602052604090205460ff1661331a576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0385166000908152600a602052604090205460ff16613378576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b60065460a060020a900460ff166133d9576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f535741505f4e4f545f5055424c494300000000000000000000000000604482015290519081900360640190fd5b600160a060020a038088166000908152600a6020526040808220928816825290206003820154613413906002670de0b6b3a76400006127da565b881115613458576040805160e560020a62461bcd0281526020600482015260106024820152600080516020615740833981519152604482015290519081900360640190fd5b60006134798360030154846002015484600301548560020154600754613df0565b9050858111156134d3576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f4241445f4c494d49545f505249434500000000000000000000000000604482015290519081900360640190fd5b6134f383600301548460020154846003015485600201548d6007546141ae565b94508685101561353b576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615800833981519152604482015290519081900360640190fd5b61354983600301548a615082565b836003018190555061355f826003015486614dee565b600380840182905584015460028086015490850154600754613582949190613df0565b9350808410156135ca576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b85841115613622576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4c494d49545f50524943450000000000000000000000000000000000604482015290519081900360640190fd5b61362c898661515a565b811115613671576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b87600160a060020a03168a600160a060020a031633600160a060020a03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d433788c89604051808381526020018281526020019250505060405180910390a46136d98a338b6150df565b6131f3883387614e83565b6000806136f1878661515a565b90506000613707670de0b6b3a764000083614dee565b905060006137158286614d05565b9050600061372f87612630670de0b6b3a764000085614dee565b9050600061373d8c83614dee565b9050600061374b828e61515a565b905060006137598288615296565b90506000613767828e614d05565b905060006137758e83614dee565b905061378e81612630670de0b6b3a76400006000614dee565b99505050505050505050509695505050505050565b6000806137b0878661515a565b905060006137cf6137c9670de0b6b3a764000084614dee565b85614d05565b905060006137ee866137e9670de0b6b3a764000085614dee565b614d05565b905060006137fc8b83615082565b9050600061380a828d61515a565b905060006138188287615296565b90506000613826828d614d05565b9050613832818d614dee565b9e9d5050505050505050505050505050565b64e8d4a51000670de0b6b3a76400006113a8565b600080613865878661515a565b90506000613880856137e9670de0b6b3a76400006000614dee565b9050600061388e8883614dee565b9050600061389c828a61515a565b905060006138bb826138b6670de0b6b3a76400008861515a565b615296565b905060006138c9828e614d05565b905060006138d78e83614dee565b905060006138f0612612670de0b6b3a76400008a614dee565b9050612635826137e9670de0b6b3a764000084614dee565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff16156139b7576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff001916610100179055600160a060020a0381166000908152600a602052604090205460ff16613a24576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038316916370a08231916024808301926020929190829003018186803b158015613a8357600080fd5b505afa158015613a97573d6000803e3d6000fd5b505050506040513d6020811015613aad57600080fd5b5051600160a060020a039091166000908152600a60205260409020600301556005805461ff0019169055565b60085460ff1690565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615613b91576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560065433600160a060020a0390911614613bf2576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790556005805461ff0019169055565b600554600090610100900460ff1615613c7d576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b50600b5490565b68056bc75e2d6310000081565b600554600090610100900460ff1615613ce2576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff16613d40576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b50600160a060020a03166000908152600a602052604090206002015490565b60048054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561107b5780601f106110505761010080835404028352916020019161107b565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600080613dfd878761515a565b90506000613e0b868661515a565b90506000613e19838361515a565b90506000613e3b670de0b6b3a7640000612630670de0b6b3a764000089614dee565b9050613e478282614d05565b9a9950505050505050505050565b6000613e62338484614f78565b50600192915050565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615613f1a576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16613f71576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b6000613f7b611392565b90506000613f8a856000614d05565b90506000613f988683614dee565b90506000613fa6828561515a565b905080613feb576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b613ff53388614e5f565b60055461401190620100009004600160a060020a031684614e79565b61401a82614e6d565b60005b60095481101561418a5760006009828154811061403657fe5b6000918252602080832090910154600160a060020a0316808352600a90915260408220600301549092509061406b8583614d05565b9050806140b0576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b8989858181106140bc57fe5b90506020020135811015614108576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615800833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090206003015461412e9082614dee565b600160a060020a0384166000818152600a60209081526040918290206003019390935580518481529051919233926000805160206157a08339815191529281900390910190a361417f833383614e83565b50505060010161401d565b50506005805461ff0019169055505050505050565b600881565b600281565b600181565b6000806141bb878661515a565b905060006141d1670de0b6b3a764000085614dee565b90506141dd8582614d05565b905060006141ef8a6126308c85615082565b905060006141fd8285615296565b90506000614213670de0b6b3a764000083614dee565b905061421f8a82614d05565b9c9b505050505050505050505050565b600a670de0b6b3a76400006113a8565b671bc16d674ec7ffff81565b600554606090610100900460ff161561429c576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b60085460ff166142e4576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600980548060200260200160405190810160405280929190818152602001828054801561107b57602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161431c575050505050905090565b600081565b600554606090610100900460ff16156142e4576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b60095490565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff161561444e576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560065433600160a060020a03909116146144af576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b600160a060020a0381166000908152600a602052604090205460ff1661450d576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b60085460ff1615614556576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b600160a060020a0381166000908152600a60205260408120600301549061457d8282614d05565b600b54600160a060020a0385166000908152600a60205260409020600201549192506145a891614dee565b600b55600160a060020a0383166000908152600a60205260409020600101546009805460001981019190829081106145dc57fe5b60009182526020909120015460098054600160a060020a03909216918490811061460257fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a0316021790555081600a60006009858154811061464257fe5b6000918252602080832090910154600160a060020a03168352820192909252604001902060010155600980548061467557fe5b600082815260208082206000199084018101805473ffffffffffffffffffffffffffffffffffffffff191690559092019092556040805160808101825283815280830184815281830185815260608301868152600160a060020a038c168752600a909552929094209051815460ff1916901515178155925160018401555160028301555160039091015561470e8533611bdd8787614dee565b600554611c03908690620100009004600160a060020a031685614e83565b600554600090610100900460ff161561477d576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b5060075490565b336000908152600160209081526040808320600160a060020a03861684529091528120546147b29083615082565b336000818152600160209081526040808320600160a060020a0389168085529083529281902085905580519485525191936000805160206157c0833981519152929081900390910190a350600192915050565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600654600160a060020a031633146148e1576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090205460ff1615614952576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f49535f424f554e440000000000000000000000000000000000000000604482015290519081900360640190fd5b60085460ff161561499b576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b6009546008116149f5576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f4d41585f544f4b454e53000000000000000000000000000000000000604482015290519081900360640190fd5b604080516080810182526001808252600980546020808501918252600085870181815260608701828152600160a060020a038c16808452600a9094529782209651875460ff1916901515178755925186860155915160028601559451600390940193909355805491820181559091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af01805473ffffffffffffffffffffffffffffffffffffffff19169091179055614aaf8383836117c9565b505050565b6002670de0b6b3a76400006113a8565b600554600090610100900460ff1615614b15576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff16614b73576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a6020526040902060020154600b54614b9d90829061515a565b9392505050565b600554600090610100900460ff1615614bf5576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff16614c53576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b50600160a060020a03166000908152600a602052604090206003015490565b600080614c7f858861515a565b90506000614c8d8786614dee565b90506000614c9b888361515a565b90506000614ca98285615296565b9050614cbd81670de0b6b3a7640000614dee565b9050614cd1670de0b6b3a764000087614dee565b9450614ce6614ce08c83614d05565b8661515a565b9b9a5050505050505050505050565b60065460a060020a900460ff1690565b6000828202831580614d1f575082848281614d1c57fe5b04145b614d73576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6706f05b59d3b20000810181811015614dd6576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6000670de0b6b3a7640000825b049695505050505050565b6000806000614dfd85856153b9565b915091508015614e57576040805160e560020a62461bcd02815260206004820152601160248201527f4552525f5355425f554e444552464c4f57000000000000000000000000000000604482015290519081900360640190fd5b509392505050565b614e6982826153de565b5050565b614e76816153e9565b50565b614e6982826154b3565b604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015260248201849052915160009286169163a9059cbb91604480830192602092919082900301818787803b158015614eef57600080fd5b505af1158015614f03573d6000803e3d6000fd5b505050506040513d6020811015614f1957600080fd5b5051905080614f72576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f45524332305f46414c53450000000000000000000000000000000000604482015290519081900360640190fd5b50505050565b600160a060020a038316600090815260208190526040902054811115614fe8576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e53554646494349454e545f42414c000000000000000000000000604482015290519081900360640190fd5b600160a060020a03831660009081526020819052604090205461500b9082614dee565b600160a060020a03808516600090815260208190526040808220939093559084168152205461503a9082615082565b600160a060020a0380841660008181526020818152604091829020949094558051858152905191939287169260008051602061576083398151915292918290030190a3505050565b600082820183811015614b9d576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4144445f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b604080517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301523060248301526044820184905291516000928616916323b872dd91606480830192602092919082900301818787803b158015614eef57600080fd5b614e76816154be565b6000816151b1576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4449565f5a45524f0000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a764000083028315806151d95750670de0b6b3a76400008482816151d657fe5b04145b61522d576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b6002830481018181101561528b576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b6000848281614de357fe5b600060018310156152f1576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f42504f575f424153455f544f4f5f4c4f570000000000000000000000604482015290519081900360640190fd5b671bc16d674ec7ffff831115615351576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f42504f575f424153455f544f4f5f4849474800000000000000000000604482015290519081900360640190fd5b600061535c83615521565b9050600061536a8483614dee565b905060006153808661537b8561553c565b61554a565b9050816153915792506110d4915050565b60006153a287846305f5e1006155a1565b90506153ae8282614d05565b979650505050505050565b6000808284106153cf57505080820360006153d7565b505081810360015b9250929050565b614e69823083614f78565b30600090815260208190526040902054811115615450576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e53554646494349454e545f42414c000000000000000000000000604482015290519081900360640190fd5b3060009081526020819052604090205461546a9082614dee565b306000908152602081905260409020556002546154879082614dee565b60025560408051828152905160009130916000805160206157608339815191529181900360200190a350565b614e69308383614f78565b306000908152602081905260409020546154d89082615082565b306000908152602081905260409020556002546154f59082615082565b60025560408051828152905130916000916000805160206157608339815191529181900360200190a350565b6000670de0b6b3a76400006155358361553c565b0292915050565b670de0b6b3a7640000900490565b6000806002830661556357670de0b6b3a7640000615565565b835b90506002830492505b8215614b9d5761557e8485614d05565b93506002830615615596576155938185614d05565b90505b60028304925061556e565b60008281806155b887670de0b6b3a76400006153b9565b9092509050670de0b6b3a764000080600060015b888410615670576000670de0b6b3a7640000820290506000806156008a6155fb85670de0b6b3a7640000614dee565b6153b9565b91509150615612876137e9848c614d05565b965061561e878461515a565b96508661562d57505050615670565b8715615637579315935b8015615641579315935b8415615658576156518688614dee565b9550615665565b6156628688615082565b95505b5050506001016155cc565b5090999850505050505050505056fe4552525f4e4f545f46494e414c495a45440000000000000000000000000000004552525f5245454e5452590000000000000000000000000000000000000000004552525f4c494d49545f494e00000000000000000000000000000000000000004552525f4d41585f4f55545f524154494f00000000000000000000000000000063982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a4552525f4e4f545f434f4e54524f4c4c455200000000000000000000000000004552525f4d41585f494e5f524154494f00000000000000000000000000000000ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef4552525f4e4f545f424f554e4400000000000000000000000000000000000000e74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9254552525f49535f46494e414c495a4544000000000000000000000000000000004552525f4c494d49545f4f5554000000000000000000000000000000000000004552525f4d4154485f415050524f580000000000000000000000000000000000a265627a7a72315820a6ed20be58469dda7b96f5cd85dbd70406a753a02b645704241ab59bf33344fe64736f6c634300050c0032a265627a7a723158201fb7c2c80fbc145fbafa4fbc21af09d0d3faf8acf13673c5517de0883d91e5f564736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/BMath.abi b/runtime/near-evm-runner/tests/build/BMath.abi new file mode 100644 index 00000000000..6df234eb16b --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BMath.abi @@ -0,0 +1,574 @@ +[ + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcSpotPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "spotPrice", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcOutGivenIn", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcInGivenOut", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcPoolOutGivenSingleIn", + "outputs": [ + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcSingleInGivenPoolOut", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcSingleOutGivenPoolIn", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcPoolInGivenSingleOut", + "outputs": [ + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/BMath.bin b/runtime/near-evm-runner/tests/build/BMath.bin new file mode 100644 index 00000000000..73ade7f2077 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BMath.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50610e77806100206000396000f3fe608060405234801561001057600080fd5b5060043610610175576000357c010000000000000000000000000000000000000000000000000000000090048063a221ee49116100e0578063bc694ea211610099578063bc694ea214610348578063c36596a61461019c578063c6580d1214610350578063e4a28a521461017a578063ec09302114610358578063f8d6aed41461036057610175565b8063a221ee49146102b8578063b0e0d136146102ed578063b7b800a4146102f5578063ba019dab146102fd578063ba9530a614610305578063bc063e1a1461034057610175565b80638656b653116101325780638656b65314610222578063867378c51461025d57806389298012146102655780639381cd2b146102a0578063992e2a92146102a85780639a86139b146102b057610175565b806309a3bbe41461017a578063189d00ca14610194578063218b53821461019c5780635c1bbaf7146101a457806376c7a3c7146101df57806382f652ad146101e7575b600080fd5b61018261039b565b60408051918252519081900360200190f35b6101826103a8565b6101826103bc565b610182600480360360c08110156101ba57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356103c8565b610182610480565b610182600480360360c08110156101fd57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135610492565b610182600480360360c081101561023857600080fd5b5080359060208101359060408101359060608101359060808101359060a00135610551565b6101826105f2565b610182600480360360c081101561027b57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135610606565b6101826106b6565b6101826106c3565b6101826106cf565b610182600480360360a08110156102ce57600080fd5b50803590602081013590604081013590606081013590608001356106f3565b610182610758565b61018261075d565b610182610762565b610182600480360360c081101561031b57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135610767565b6101826107e8565b6101826107f8565b610182610804565b610182610809565b610182600480360360c081101561037657600080fd5b5080359060208101359060408101359060608101359060808101359060a00135610819565b6802b5e3af16b188000081565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b6000806103d5878661089c565b905060006103e387866109e5565b905060006103f1828961089c565b90506000610407670de0b6b3a76400008561089c565b905060006104158383610a49565b90506000610423828e610b6c565b90506000610431828f610c4e565b9050600061045061044a670de0b6b3a76400008a610c4e565b8b610b6c565b905061046d82610468670de0b6b3a764000084610c4e565b61089c565b9f9e505050505050505050505050505050565b620f4240670de0b6b3a76400006103b8565b60008061049f878661089c565b905060006104b5670de0b6b3a764000083610c4e565b905060006104c38286610b6c565b905060006104dd87610468670de0b6b3a764000085610c4e565b905060006104eb8c83610c4e565b905060006104f9828e61089c565b905060006105078288610a49565b90506000610515828e610b6c565b905060006105238e83610c4e565b905061053c81610468670de0b6b3a76400006000610c4e565b99505050505050505050509695505050505050565b60008061055e878661089c565b9050600061057d610577670de0b6b3a764000084610c4e565b85610b6c565b9050600061059c86610597670de0b6b3a764000085610c4e565b610b6c565b905060006105aa8b836109e5565b905060006105b8828d61089c565b905060006105c68287610a49565b905060006105d4828d610b6c565b90506105e0818d610c4e565b9e9d5050505050505050505050505050565b64e8d4a51000670de0b6b3a76400006103b8565b600080610613878661089c565b9050600061062e85610597670de0b6b3a76400006000610c4e565b9050600061063c8883610c4e565b9050600061064a828a61089c565b9050600061066982610664670de0b6b3a76400008861089c565b610a49565b90506000610677828e610b6c565b905060006106858e83610c4e565b9050600061069e61044a670de0b6b3a76400008a610c4e565b905061046d82610597670de0b6b3a764000084610c4e565b68056bc75e2d6310000081565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600080610700878761089c565b9050600061070e868661089c565b9050600061071c838361089c565b9050600061073e670de0b6b3a7640000610468670de0b6b3a764000089610c4e565b905061074a8282610b6c565b9a9950505050505050505050565b600881565b600281565b600181565b600080610774878661089c565b9050600061078a670de0b6b3a764000085610c4e565b90506107968582610b6c565b905060006107a88a6104688c856109e5565b905060006107b68285610a49565b905060006107cc670de0b6b3a764000083610c4e565b90506107d88a82610b6c565b9c9b505050505050505050505050565b600a670de0b6b3a76400006103b8565b671bc16d674ec7ffff81565b600081565b6002670de0b6b3a76400006103b8565b600080610826858861089c565b905060006108348786610c4e565b90506000610842888361089c565b905060006108508285610a49565b905061086481670de0b6b3a7640000610c4e565b9050610878670de0b6b3a764000087610c4e565b945061088d6108878c83610b6c565b8661089c565b9b9a5050505050505050505050565b6000816108f3576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4449565f5a45524f0000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a7640000830283158061091b5750670de0b6b3a764000084828161091857fe5b04145b61096f576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b600283048101818110156109cd576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b60008482816109d857fe5b0493505050505b92915050565b600082820183811015610a42576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4144445f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b9392505050565b60006001831015610aa4576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f42504f575f424153455f544f4f5f4c4f570000000000000000000000604482015290519081900360640190fd5b671bc16d674ec7ffff831115610b04576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f42504f575f424153455f544f4f5f4849474800000000000000000000604482015290519081900360640190fd5b6000610b0f83610cbf565b90506000610b1d8483610c4e565b90506000610b3386610b2e85610cda565b610ce8565b905081610b445792506109df915050565b6000610b5587846305f5e100610d3f565b9050610b618282610b6c565b979650505050505050565b6000828202831580610b86575082848281610b8357fe5b04145b610bda576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6706f05b59d3b20000810181811015610c3d576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6000670de0b6b3a7640000826109d8565b6000806000610c5d8585610e1d565b915091508015610cb7576040805160e560020a62461bcd02815260206004820152601160248201527f4552525f5355425f554e444552464c4f57000000000000000000000000000000604482015290519081900360640190fd5b509392505050565b6000670de0b6b3a7640000610cd383610cda565b0292915050565b670de0b6b3a7640000900490565b60008060028306610d0157670de0b6b3a7640000610d03565b835b90506002830492505b8215610a4257610d1c8485610b6c565b93506002830615610d3457610d318185610b6c565b90505b600283049250610d0c565b6000828180610d5687670de0b6b3a7640000610e1d565b9092509050670de0b6b3a764000080600060015b888410610e0e576000670de0b6b3a764000082029050600080610d9e8a610d9985670de0b6b3a7640000610c4e565b610e1d565b91509150610db087610597848c610b6c565b9650610dbc878461089c565b965086610dcb57505050610e0e565b8715610dd5579315935b8015610ddf579315935b8415610df657610def8688610c4e565b9550610e03565b610e0086886109e5565b95505b505050600101610d6a565b50909998505050505050505050565b600080828410610e335750508082036000610e3b565b505081810360015b925092905056fea265627a7a723158205ed1b22832c14cf9e2efe6ea235b597639d6738dd598d3ea8203c58103f244c964736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/BNum.abi b/runtime/near-evm-runner/tests/build/BNum.abi new file mode 100644 index 00000000000..42a7386d836 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BNum.abi @@ -0,0 +1,257 @@ +[ + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/BNum.bin b/runtime/near-evm-runner/tests/build/BNum.bin new file mode 100644 index 00000000000..aac89837d18 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BNum.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b5061029c806100206000396000f3fe608060405234801561001057600080fd5b5060043610610108576000357c010000000000000000000000000000000000000000000000000000000090048063b0e0d136116100af578063b0e0d1361461015f578063b7b800a414610167578063ba019dab1461016f578063bc063e1a14610177578063bc694ea21461017f578063c36596a61461012f578063c6580d1214610187578063e4a28a521461010d578063ec0930211461018f57610108565b806309a3bbe41461010d578063189d00ca14610127578063218b53821461012f57806376c7a3c714610137578063867378c51461013f5780639381cd2b14610147578063992e2a921461014f5780639a86139b14610157575b600080fd5b610115610197565b60408051918252519081900360200190f35b6101156101a4565b6101156101b8565b6101156101c4565b6101156101d6565b6101156101ea565b6101156101f7565b610115610203565b610115610227565b61011561022c565b610115610231565b610115610236565b610115610246565b610115610252565b610115610257565b6802b5e3af16b188000081565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b620f4240670de0b6b3a76400006101b4565b64e8d4a51000670de0b6b3a76400006101b4565b68056bc75e2d6310000081565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600881565b600281565b600181565b600a670de0b6b3a76400006101b4565b671bc16d674ec7ffff81565b600081565b6002670de0b6b3a76400006101b456fea265627a7a7231582089365996d164956921d5302db8b5bd223216993fe8eda62ec774fd5ff6d7c3f164736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/BPool.abi b/runtime/near-evm-runner/tests/build/BPool.abi new file mode 100644 index 00000000000..10600139942 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BPool.abi @@ -0,0 +1,1630 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": true, + "inputs": [ + { + "indexed": true, + "internalType": "bytes4", + "name": "sig", + "type": "bytes4" + }, + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "LOG_CALL", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + } + ], + "name": "LOG_EXIT", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + } + ], + "name": "LOG_JOIN", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + } + ], + "name": "LOG_SWAP", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "whom", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcInGivenOut", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcOutGivenIn", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcPoolInGivenSingleOut", + "outputs": [ + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcPoolOutGivenSingleIn", + "outputs": [ + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcSingleInGivenPoolOut", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcSingleOutGivenPoolIn", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcSpotPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "spotPrice", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "decreaseApproval", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "increaseApproval", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isPublicSwap", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isFinalized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "t", + "type": "address" + } + ], + "name": "isBound", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getNumTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getCurrentTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getFinalTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getDenormalizedWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getTotalDenormalizedWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getNormalizedWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getSwapFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getController", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "setSwapFee", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setController", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bool", + "name": "public_", + "type": "bool" + } + ], + "name": "setPublicSwap", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "finalize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "denorm", + "type": "uint256" + } + ], + "name": "bind", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "denorm", + "type": "uint256" + } + ], + "name": "rebind", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "unbind", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "gulp", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + } + ], + "name": "getSpotPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "spotPrice", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + } + ], + "name": "getSpotPriceSansFee", + "outputs": [ + { + "internalType": "uint256", + "name": "spotPrice", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "maxAmountsIn", + "type": "uint256[]" + } + ], + "name": "joinPool", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "minAmountsOut", + "type": "uint256[]" + } + ], + "name": "exitPool", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPrice", + "type": "uint256" + } + ], + "name": "swapExactAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "spotPriceAfter", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxAmountIn", + "type": "uint256" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPrice", + "type": "uint256" + } + ], + "name": "swapExactAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "spotPriceAfter", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minPoolAmountOut", + "type": "uint256" + } + ], + "name": "joinswapExternAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxAmountIn", + "type": "uint256" + } + ], + "name": "joinswapPoolAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minAmountOut", + "type": "uint256" + } + ], + "name": "exitswapPoolAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPoolAmountIn", + "type": "uint256" + } + ], + "name": "exitswapExternAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/BPool.bin b/runtime/near-evm-runner/tests/build/BPool.bin new file mode 100644 index 00000000000..ed434055d39 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BPool.bin @@ -0,0 +1 @@ +60c0604052601360808190527f42616c616e63657220506f6f6c20546f6b656e0000000000000000000000000060a0908152620000409160039190620000f7565b506040805180820190915260038082527f425054000000000000000000000000000000000000000000000000000000000060209092019182526200008791600491620000f7565b506005805460ff19166012179055348015620000a257600080fd5b5060068054600580546201000060b060020a031916336201000081029190911790915564e8d4a51000600755600160a060020a03199091161760a060020a60ff02191690556008805460ff191690556200019c565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200013a57805160ff19168380011785556200016a565b828001600101855582156200016a579182015b828111156200016a5782518255916020019190600101906200014d565b50620001789291506200017c565b5090565b6200019991905b8082111562000178576000815560010162000183565b90565b61587480620001ac6000396000f3fe608060405234801561001057600080fd5b5060043610610378576000357c0100000000000000000000000000000000000000000000000000000000900480638d4e4083116101e7578063bc694ea211610122578063d73dd623116100c5578063d73dd62314610b7f578063dd62ed3e14610bab578063e4a28a521461047e578063e4e1e53814610bd9578063ec09302114610c0b578063f1b8a9b714610c13578063f8b2cb4f14610c39578063f8d6aed414610c5f578063fde924f714610c9a57610378565b8063bc694ea214610ad9578063be3bbd2e14610ae1578063c36596a6146104f2578063c6580d1214610b39578063cc77828d14610b41578063cd2ed8fb14610b49578063cf5e7bd314610b51578063d4cadf6814610b7757610378565b8063a221ee491161018a578063a221ee49146109a6578063a9059cbb146109db578063b02f0b7314610a07578063b0e0d13614610a7e578063b7b800a414610a86578063ba019dab14610a8e578063ba9530a614610a96578063bc063e1a14610ad157610378565b80638d4e40831461092a57806392eefe9b14610932578063936c3477146109585780639381cd2b14610960578063948d8ce61461096857806395d89b411461098e578063992e2a92146109965780639a86139b1461099e57610378565b806349b59552116102b757806376c7a3c71161025a57806376c7a3c7146107aa5780637c5e9ea4146107b25780638201aa3f1461080b57806382f652ad1461084b5780638656b65314610886578063867378c5146108c157806389298012146108c95780638c28cbe81461090457610378565b806349b595521461061b5780634bb278f31461063a5780634f69c0d4146106425780635c1bbaf7146106b95780635db34277146106f457806366188463146107265780636d06dfa01461075257806370a082311461078457610378565b8063218b53821161031f578063218b5382146104f257806323b872dd146104fa5780632f37b624146105305780633018205f14610556578063313ce5671461057a57806334e19907146105985780633fdddaa2146105b757806346ab38f1146105e957610378565b806302c967481461037d57806306fdde03146103c1578063095ea7b31461043e57806309a3bbe41461047e5780631446a7ff1461048657806315e84af9146104b457806318160ddd146104e2578063189d00ca146104ea575b600080fd5b6103af6004803603606081101561039357600080fd5b50600160a060020a038135169060208101359060400135610ca2565b60408051918252519081900360200190f35b6103c9610fef565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104035781810151838201526020016103eb565b50505050905090810190601f1680156104305780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61046a6004803603604081101561045457600080fd5b50600160a060020a038135169060200135611085565b604080519115158252519081900360200190f35b6103af6110da565b6103af6004803603604081101561049c57600080fd5b50600160a060020a03813581169160200135166110e7565b6103af600480360360408110156104ca57600080fd5b50600160a060020a0381358116916020013516611241565b6103af611392565b6103af611398565b6103af6113ac565b61046a6004803603606081101561051057600080fd5b50600160a060020a038135811691602081013590911690604001356113b8565b61046a6004803603602081101561054657600080fd5b5035600160a060020a031661151d565b61055e61153b565b60408051600160a060020a039092168252519081900360200190f35b61058261159c565b6040805160ff9092168252519081900360200190f35b6105b5600480360360208110156105ae57600080fd5b50356115a5565b005b6105b5600480360360608110156105cd57600080fd5b50600160a060020a0381351690602081013590604001356117c9565b6103af600480360360608110156105ff57600080fd5b50600160a060020a038135169060208101359060400135611c15565b6105b56004803603602081101561063157600080fd5b50351515611f01565b6105b5612092565b6105b56004803603604081101561065857600080fd5b8135919081019060408101602082013564010000000081111561067a57600080fd5b82018360208201111561068c57600080fd5b803590602001918460208302840111640100000000831117156106ae57600080fd5b5090925090506122a9565b6103af600480360360c08110156106cf57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135612590565b6103af6004803603606081101561070a57600080fd5b50600160a060020a038135169060208101359060400135612648565b61046a6004803603604081101561073c57600080fd5b50600160a060020a038135169060200135612919565b6103af6004803603606081101561076857600080fd5b50600160a060020a0381351690602081013590604001356129f1565b6103af6004803603602081101561079a57600080fd5b5035600160a060020a0316612cf0565b6103af612d0b565b6107f2600480360360a08110156107c857600080fd5b50600160a060020a0381358116916020810135916040820135169060608101359060800135612d1d565b6040805192835260208301919091528051918290030190f35b6107f2600480360360a081101561082157600080fd5b50600160a060020a038135811691602081013591604082013516906060810135906080013561320d565b6103af600480360360c081101561086157600080fd5b5080359060208101359060408101359060608101359060808101359060a001356136e4565b6103af600480360360c081101561089c57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356137a3565b6103af613844565b6103af600480360360c08110156108df57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135613858565b6105b56004803603602081101561091a57600080fd5b5035600160a060020a0316613908565b61046a613ad9565b6105b56004803603602081101561094857600080fd5b5035600160a060020a0316613ae2565b6103af613c2c565b6103af613c84565b6103af6004803603602081101561097e57600080fd5b5035600160a060020a0316613c91565b6103c9613d5f565b6103af613dc0565b6103af613dcc565b6103af600480360360a08110156109bc57600080fd5b5080359060208101359060408101359060608101359060800135613df0565b61046a600480360360408110156109f157600080fd5b50600160a060020a038135169060200135613e55565b6105b560048036036040811015610a1d57600080fd5b81359190810190604081016020820135640100000000811115610a3f57600080fd5b820183602082011115610a5157600080fd5b80359060200191846020830284011164010000000083111715610a7357600080fd5b509092509050613e6b565b6103af61419f565b6103af6141a4565b6103af6141a9565b6103af600480360360c0811015610aac57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356141ae565b6103af61422f565b6103af61423f565b610ae961424b565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610b25578181015183820152602001610b0d565b505050509050019250505060405180910390f35b6103af614343565b610ae9614348565b6103af614399565b6105b560048036036020811015610b6757600080fd5b5035600160a060020a031661439f565b6103af61472c565b61046a60048036036040811015610b9557600080fd5b50600160a060020a038135169060200135614784565b6103af60048036036040811015610bc157600080fd5b50600160a060020a0381358116916020013516614805565b6105b560048036036060811015610bef57600080fd5b50600160a060020a038135169060208101359060400135614830565b6103af614ab4565b6103af60048036036020811015610c2957600080fd5b5035600160a060020a0316614ac4565b6103af60048036036020811015610c4f57600080fd5b5035600160a060020a0316614ba4565b6103af600480360360c0811015610c7557600080fd5b5080359060208101359060408101359060608101359060808101359060a00135614c72565b61046a614cf5565b600033600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615610d53576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16610daa576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a602052604090205460ff16610e08576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a60205260409020600390810154610e3d91670de0b6b3a76400005b04600101614d05565b831115610e82576040805160e560020a62461bcd02815260206004820152601160248201526000805160206156e0833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a6020526040902060038101546002808301549054600b54600754610ebc949392919089906136e4565b915081610f01576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b82821115610f47576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206156c0833981519152604482015290519081900360640190fd5b610f55816003015485614dee565b60038201556000610f668382614d05565b604080518781529051919250600160a060020a0388169133916000805160206157a0833981519152919081900360200190a3610fa23384614e5f565b610fb4610faf8483614dee565b614e6d565b600554610fd090620100009004600160a060020a031682614e79565b610fdb863387614e83565b50506005805461ff00191690559392505050565b60038054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561107b5780601f106110505761010080835404028352916020019161107b565b820191906000526020600020905b81548152906001019060200180831161105e57829003601f168201915b5050505050905090565b336000818152600160209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390926000805160206157c0833981519152928290030190a35060015b92915050565b6802b5e3af16b188000081565b600554600090610100900460ff1615611138576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090205460ff16611196576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff166111f4576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a038084166000908152600a602052604080822092851682528120600380840154600280860154928401549084015493946112389492939290613df0565b95945050505050565b600554600090610100900460ff1615611292576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090205460ff166112f0576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff1661134e576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a038084166000908152600a602052604080822092851682529020600380830154600280850154928401549084015460075461123894929190613df0565b60025490565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b600033600160a060020a03851614806113f45750600160a060020a03841660009081526001602090815260408083203384529091529020548211155b611448576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f42544f4b454e5f4241445f43414c4c45520000000000000000000000604482015290519081900360640190fd5b611453848484614f78565b33600160a060020a038516148015906114915750600160a060020a038416600090815260016020908152604080832033845290915290205460001914155b1561151357600160a060020a03841660009081526001602090815260408083203384529091529020546114c49083614dee565b600160a060020a03858116600090815260016020908152604080832033808552908352928190208590558051948552519287169391926000805160206157c08339815191529281900390910190a35b5060019392505050565b600160a060020a03166000908152600a602052604090205460ff1690565b600554600090610100900460ff161561158c576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b50600654600160a060020a031690565b60055460ff1690565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615611654576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16156116ac576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b600654600160a060020a031633146116fc576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b64e8d4a51000811015611759576040805160e560020a62461bcd02815260206004820152600b60248201527f4552525f4d494e5f464545000000000000000000000000000000000000000000604482015290519081900360640190fd5b67016345785d8a00008111156117b9576040805160e560020a62461bcd02815260206004820152600b60248201527f4552525f4d41585f464545000000000000000000000000000000000000000000604482015290519081900360640190fd5b6007556005805461ff0019169055565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615611878576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560065433600160a060020a03909116146118d9576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090205460ff16611937576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b60085460ff1615611980576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b670de0b6b3a76400008110156119e0576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f4d494e5f574549474854000000000000000000000000000000000000604482015290519081900360640190fd5b6802b5e3af16b1880000811115611a41576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f4d41585f574549474854000000000000000000000000000000000000604482015290519081900360640190fd5b620f4240821015611a9c576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4d494e5f42414c414e43450000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090206002015480821115611b3f57611ad5600b54611ad08484614dee565b615082565b600b8190556802b5e3af16b18800001015611b3a576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f4d41585f544f54414c5f574549474854000000000000000000000000604482015290519081900360640190fd5b611b60565b80821015611b6057611b5c600b54611b578385614dee565b614dee565b600b555b600160a060020a0384166000908152600a602052604090206002810183905560030180549084905580841115611ba957611ba48533611b9f8785614dee565b6150df565b611c03565b80841015611c03576000611bbd8286614dee565b90506000611bcc826000614d05565b9050611be28733611bdd8585614dee565b614e83565b600554611c00908890620100009004600160a060020a031683614e83565b50505b50506005805461ff0019169055505050565b600033600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615611cc6576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16611d1d576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a602052604090205460ff16611d7b576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a6020526040902060038101546002808301549054600b54600754611db594939291908990613858565b915082821015611dfd576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615800833981519152604482015290519081900360640190fd5b600160a060020a0385166000908152600a60205260409020600390810154611e2d91670de0b6b3a7640000610e34565b821115611e72576040805160e560020a62461bcd02815260206004820152601160248201526000805160206156e0833981519152604482015290519081900360640190fd5b611e80816003015483614dee565b60038201556000611e918582614d05565b604080518581529051919250600160a060020a0388169133916000805160206157a0833981519152919081900360200190a3611ecd3386614e5f565b611eda610faf8683614dee565b600554611ef690620100009004600160a060020a031682614e79565b610fdb863385614e83565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615611fb0576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff1615612008576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b600654600160a060020a03163314612058576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b6006805491151560a060020a0274ff0000000000000000000000000000000000000000199092169190911790556005805461ff0019169055565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615612141576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560065433600160a060020a03909116146121a2576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b60085460ff16156121eb576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b60095460021115612246576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f4d494e5f544f4b454e53000000000000000000000000000000000000604482015290519081900360640190fd5b6008805460ff191660011790556006805474ff0000000000000000000000000000000000000000191660a060020a17905561228968056bc75e2d63100000615151565b61229c3368056bc75e2d63100000614e79565b6005805461ff0019169055565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615612358576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff166123af576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b60006123b9611392565b905060006123c7858361515a565b90508061240c576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b60005b60095481101561257c5760006009828154811061242857fe5b6000918252602080832090910154600160a060020a0316808352600a90915260408220600301549092509061245d8583614d05565b9050806124a2576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b8787858181106124ae57fe5b905060200201358111156124fa576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206156c0833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a60205260409020600301546125209082615082565b600160a060020a0384166000818152600a60209081526040918290206003019390935580518481529051919233926000805160206157008339815191529281900390910190a36125718333836150df565b50505060010161240f565b5061258685615151565b611c033386614e79565b60008061259d878661515a565b905060006125ab8786615082565b905060006125b9828961515a565b905060006125cf670de0b6b3a76400008561515a565b905060006125dd8383615296565b905060006125eb828e614d05565b905060006125f9828f614dee565b90506000612618612612670de0b6b3a76400008a614dee565b8b614d05565b905061263582612630670de0b6b3a764000084614dee565b61515a565b9f9e505050505050505050505050505050565b600033600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff16156126f9576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16612750576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a602052604090205460ff166127ae576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a60205260409020600301546127e0906002670de0b6b3a76400005b04614d05565b831115612825576040805160e560020a62461bcd0281526020600482015260106024820152600080516020615740833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a6020526040902060038101546002808301549054600b5460075461285f949392919089906137a3565b9150828210156128a7576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615800833981519152604482015290519081900360640190fd5b6128b5816003015485615082565b6003820155604080518581529051600160a060020a0387169133916000805160206157008339815191529181900360200190a36128f182615151565b6128fb3383614e79565b6129068533866150df565b506005805461ff00191690559392505050565b336000908152600160209081526040808320600160a060020a03861684529091528120548083111561296e57336000908152600160209081526040808320600160a060020a038816845290915281205561299d565b6129788184614dee565b336000908152600160209081526040808320600160a060020a03891684529091529020555b336000818152600160209081526040808320600160a060020a0389168085529083529281902054815190815290519293926000805160206157c0833981519152929181900390910190a35060019392505050565b600033600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615612aa2576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16612af9576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a602052604090205460ff16612b57576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0384166000908152600a6020526040902060038101546002808301549054600b54600754612b9194939291908990612590565b915081612bd6576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b82821115612c1c576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206156c0833981519152604482015290519081900360640190fd5b600160a060020a0385166000908152600a6020526040902060030154612c4c906002670de0b6b3a76400006127da565b821115612c91576040805160e560020a62461bcd0281526020600482015260106024820152600080516020615740833981519152604482015290519081900360640190fd5b612c9f816003015483615082565b6003820155604080518381529051600160a060020a0387169133916000805160206157008339815191529181900360200190a3612cdb84615151565b612ce53385614e79565b6129068533846150df565b600160a060020a031660009081526020819052604090205490565b620f4240670de0b6b3a76400006113a8565b6040805160208082523690820181905260009283923392600160e060020a03198535169285929081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615612dbd576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff001916610100179055600160a060020a0387166000908152600a602052604090205460ff16612e2a576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0385166000908152600a602052604090205460ff16612e88576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b60065460a060020a900460ff16612ee9576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f535741505f4e4f545f5055424c494300000000000000000000000000604482015290519081900360640190fd5b600160a060020a038088166000908152600a602052604080822092881682529020600380820154612f2291670de0b6b3a7640000610e34565b861115612f67576040805160e560020a62461bcd02815260206004820152601160248201526000805160206156e0833981519152604482015290519081900360640190fd5b6000612f888360030154846002015484600301548560020154600754613df0565b905085811115612fe2576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f4241445f4c494d49545f505249434500000000000000000000000000604482015290519081900360640190fd5b61300283600301548460020154846003015485600201548b600754614c72565b94508885111561304a576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206156c0833981519152604482015290519081900360640190fd5b613058836003015486615082565b836003018190555061306e826003015488614dee565b600380840182905584015460028086015490850154600754613091949190613df0565b9350808410156130d9576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b85841115613131576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4c494d49545f50524943450000000000000000000000000000000000604482015290519081900360640190fd5b61313b858861515a565b811115613180576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b87600160a060020a03168a600160a060020a031633600160a060020a03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d43378888b604051808381526020018281526020019250505060405180910390a46131e88a33876150df565b6131f3883389614e83565b5050506005805461ff001916905590969095509350505050565b6040805160208082523690820181905260009283923392600160e060020a03198535169285929081908101848480828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff16156132ad576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff001916610100179055600160a060020a0387166000908152600a602052604090205460ff1661331a576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0385166000908152600a602052604090205460ff16613378576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b60065460a060020a900460ff166133d9576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f535741505f4e4f545f5055424c494300000000000000000000000000604482015290519081900360640190fd5b600160a060020a038088166000908152600a6020526040808220928816825290206003820154613413906002670de0b6b3a76400006127da565b881115613458576040805160e560020a62461bcd0281526020600482015260106024820152600080516020615740833981519152604482015290519081900360640190fd5b60006134798360030154846002015484600301548560020154600754613df0565b9050858111156134d3576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f4241445f4c494d49545f505249434500000000000000000000000000604482015290519081900360640190fd5b6134f383600301548460020154846003015485600201548d6007546141ae565b94508685101561353b576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615800833981519152604482015290519081900360640190fd5b61354983600301548a615082565b836003018190555061355f826003015486614dee565b600380840182905584015460028086015490850154600754613582949190613df0565b9350808410156135ca576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b85841115613622576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4c494d49545f50524943450000000000000000000000000000000000604482015290519081900360640190fd5b61362c898661515a565b811115613671576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b87600160a060020a03168a600160a060020a031633600160a060020a03167f908fb5ee8f16c6bc9bc3690973819f32a4d4b10188134543c88706e0e1d433788c89604051808381526020018281526020019250505060405180910390a46136d98a338b6150df565b6131f3883387614e83565b6000806136f1878661515a565b90506000613707670de0b6b3a764000083614dee565b905060006137158286614d05565b9050600061372f87612630670de0b6b3a764000085614dee565b9050600061373d8c83614dee565b9050600061374b828e61515a565b905060006137598288615296565b90506000613767828e614d05565b905060006137758e83614dee565b905061378e81612630670de0b6b3a76400006000614dee565b99505050505050505050509695505050505050565b6000806137b0878661515a565b905060006137cf6137c9670de0b6b3a764000084614dee565b85614d05565b905060006137ee866137e9670de0b6b3a764000085614dee565b614d05565b905060006137fc8b83615082565b9050600061380a828d61515a565b905060006138188287615296565b90506000613826828d614d05565b9050613832818d614dee565b9e9d5050505050505050505050505050565b64e8d4a51000670de0b6b3a76400006113a8565b600080613865878661515a565b90506000613880856137e9670de0b6b3a76400006000614dee565b9050600061388e8883614dee565b9050600061389c828a61515a565b905060006138bb826138b6670de0b6b3a76400008861515a565b615296565b905060006138c9828e614d05565b905060006138d78e83614dee565b905060006138f0612612670de0b6b3a76400008a614dee565b9050612635826137e9670de0b6b3a764000084614dee565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff16156139b7576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff001916610100179055600160a060020a0381166000908152600a602052604090205460ff16613a24576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038316916370a08231916024808301926020929190829003018186803b158015613a8357600080fd5b505afa158015613a97573d6000803e3d6000fd5b505050506040513d6020811015613aad57600080fd5b5051600160a060020a039091166000908152600a60205260409020600301556005805461ff0019169055565b60085460ff1690565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615613b91576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560065433600160a060020a0390911614613bf2576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790556005805461ff0019169055565b600554600090610100900460ff1615613c7d576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b50600b5490565b68056bc75e2d6310000081565b600554600090610100900460ff1615613ce2576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff16613d40576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b50600160a060020a03166000908152600a602052604090206002015490565b60048054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561107b5780601f106110505761010080835404028352916020019161107b565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600080613dfd878761515a565b90506000613e0b868661515a565b90506000613e19838361515a565b90506000613e3b670de0b6b3a7640000612630670de0b6b3a764000089614dee565b9050613e478282614d05565b9a9950505050505050505050565b6000613e62338484614f78565b50600192915050565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff1615613f1a576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560085460ff16613f71576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b6000613f7b611392565b90506000613f8a856000614d05565b90506000613f988683614dee565b90506000613fa6828561515a565b905080613feb576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b613ff53388614e5f565b60055461401190620100009004600160a060020a031684614e79565b61401a82614e6d565b60005b60095481101561418a5760006009828154811061403657fe5b6000918252602080832090910154600160a060020a0316808352600a90915260408220600301549092509061406b8583614d05565b9050806140b0576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020615820833981519152604482015290519081900360640190fd5b8989858181106140bc57fe5b90506020020135811015614108576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615800833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090206003015461412e9082614dee565b600160a060020a0384166000818152600a60209081526040918290206003019390935580518481529051919233926000805160206157a08339815191529281900390910190a361417f833383614e83565b50505060010161401d565b50506005805461ff0019169055505050505050565b600881565b600281565b600181565b6000806141bb878661515a565b905060006141d1670de0b6b3a764000085614dee565b90506141dd8582614d05565b905060006141ef8a6126308c85615082565b905060006141fd8285615296565b90506000614213670de0b6b3a764000083614dee565b905061421f8a82614d05565b9c9b505050505050505050505050565b600a670de0b6b3a76400006113a8565b671bc16d674ec7ffff81565b600554606090610100900460ff161561429c576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b60085460ff166142e4576040805160e560020a62461bcd0281526020600482015260116024820152600080516020615680833981519152604482015290519081900360640190fd5b600980548060200260200160405190810160405280929190818152602001828054801561107b57602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161431c575050505050905090565b600081565b600554606090610100900460ff16156142e4576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b60095490565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600554610100900460ff161561444e576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b6005805461ff00191661010017905560065433600160a060020a03909116146144af576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b600160a060020a0381166000908152600a602052604090205460ff1661450d576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b60085460ff1615614556576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b600160a060020a0381166000908152600a60205260408120600301549061457d8282614d05565b600b54600160a060020a0385166000908152600a60205260409020600201549192506145a891614dee565b600b55600160a060020a0383166000908152600a60205260409020600101546009805460001981019190829081106145dc57fe5b60009182526020909120015460098054600160a060020a03909216918490811061460257fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a0316021790555081600a60006009858154811061464257fe5b6000918252602080832090910154600160a060020a03168352820192909252604001902060010155600980548061467557fe5b600082815260208082206000199084018101805473ffffffffffffffffffffffffffffffffffffffff191690559092019092556040805160808101825283815280830184815281830185815260608301868152600160a060020a038c168752600a909552929094209051815460ff1916901515178155925160018401555160028301555160039091015561470e8533611bdd8787614dee565b600554611c03908690620100009004600160a060020a031685614e83565b600554600090610100900460ff161561477d576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b5060075490565b336000908152600160209081526040808320600160a060020a03861684529091528120546147b29083615082565b336000818152600160209081526040808320600160a060020a0389168085529083529281902085905580519485525191936000805160206157c0833981519152929081900390910190a350600192915050565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b33600160a060020a0316600035600160e060020a031916600160e060020a03191660003660405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a2600654600160a060020a031633146148e1576040805160e560020a62461bcd0281526020600482015260126024820152600080516020615720833981519152604482015290519081900360640190fd5b600160a060020a0383166000908152600a602052604090205460ff1615614952576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f49535f424f554e440000000000000000000000000000000000000000604482015290519081900360640190fd5b60085460ff161561499b576040805160e560020a62461bcd02815260206004820152601060248201526000805160206157e0833981519152604482015290519081900360640190fd5b6009546008116149f5576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f4d41585f544f4b454e53000000000000000000000000000000000000604482015290519081900360640190fd5b604080516080810182526001808252600980546020808501918252600085870181815260608701828152600160a060020a038c16808452600a9094529782209651875460ff1916901515178755925186860155915160028601559451600390940193909355805491820181559091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af01805473ffffffffffffffffffffffffffffffffffffffff19169091179055614aaf8383836117c9565b505050565b6002670de0b6b3a76400006113a8565b600554600090610100900460ff1615614b15576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff16614b73576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a6020526040902060020154600b54614b9d90829061515a565b9392505050565b600554600090610100900460ff1615614bf5576040805160e560020a62461bcd02815260206004820152600b60248201526000805160206156a0833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600a602052604090205460ff16614c53576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615780833981519152604482015290519081900360640190fd5b50600160a060020a03166000908152600a602052604090206003015490565b600080614c7f858861515a565b90506000614c8d8786614dee565b90506000614c9b888361515a565b90506000614ca98285615296565b9050614cbd81670de0b6b3a7640000614dee565b9050614cd1670de0b6b3a764000087614dee565b9450614ce6614ce08c83614d05565b8661515a565b9b9a5050505050505050505050565b60065460a060020a900460ff1690565b6000828202831580614d1f575082848281614d1c57fe5b04145b614d73576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6706f05b59d3b20000810181811015614dd6576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6000670de0b6b3a7640000825b049695505050505050565b6000806000614dfd85856153b9565b915091508015614e57576040805160e560020a62461bcd02815260206004820152601160248201527f4552525f5355425f554e444552464c4f57000000000000000000000000000000604482015290519081900360640190fd5b509392505050565b614e6982826153de565b5050565b614e76816153e9565b50565b614e6982826154b3565b604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015260248201849052915160009286169163a9059cbb91604480830192602092919082900301818787803b158015614eef57600080fd5b505af1158015614f03573d6000803e3d6000fd5b505050506040513d6020811015614f1957600080fd5b5051905080614f72576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f45524332305f46414c53450000000000000000000000000000000000604482015290519081900360640190fd5b50505050565b600160a060020a038316600090815260208190526040902054811115614fe8576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e53554646494349454e545f42414c000000000000000000000000604482015290519081900360640190fd5b600160a060020a03831660009081526020819052604090205461500b9082614dee565b600160a060020a03808516600090815260208190526040808220939093559084168152205461503a9082615082565b600160a060020a0380841660008181526020818152604091829020949094558051858152905191939287169260008051602061576083398151915292918290030190a3505050565b600082820183811015614b9d576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4144445f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b604080517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301523060248301526044820184905291516000928616916323b872dd91606480830192602092919082900301818787803b158015614eef57600080fd5b614e76816154be565b6000816151b1576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4449565f5a45524f0000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a764000083028315806151d95750670de0b6b3a76400008482816151d657fe5b04145b61522d576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b6002830481018181101561528b576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b6000848281614de357fe5b600060018310156152f1576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f42504f575f424153455f544f4f5f4c4f570000000000000000000000604482015290519081900360640190fd5b671bc16d674ec7ffff831115615351576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f42504f575f424153455f544f4f5f4849474800000000000000000000604482015290519081900360640190fd5b600061535c83615521565b9050600061536a8483614dee565b905060006153808661537b8561553c565b61554a565b9050816153915792506110d4915050565b60006153a287846305f5e1006155a1565b90506153ae8282614d05565b979650505050505050565b6000808284106153cf57505080820360006153d7565b505081810360015b9250929050565b614e69823083614f78565b30600090815260208190526040902054811115615450576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e53554646494349454e545f42414c000000000000000000000000604482015290519081900360640190fd5b3060009081526020819052604090205461546a9082614dee565b306000908152602081905260409020556002546154879082614dee565b60025560408051828152905160009130916000805160206157608339815191529181900360200190a350565b614e69308383614f78565b306000908152602081905260409020546154d89082615082565b306000908152602081905260409020556002546154f59082615082565b60025560408051828152905130916000916000805160206157608339815191529181900360200190a350565b6000670de0b6b3a76400006155358361553c565b0292915050565b670de0b6b3a7640000900490565b6000806002830661556357670de0b6b3a7640000615565565b835b90506002830492505b8215614b9d5761557e8485614d05565b93506002830615615596576155938185614d05565b90505b60028304925061556e565b60008281806155b887670de0b6b3a76400006153b9565b9092509050670de0b6b3a764000080600060015b888410615670576000670de0b6b3a7640000820290506000806156008a6155fb85670de0b6b3a7640000614dee565b6153b9565b91509150615612876137e9848c614d05565b965061561e878461515a565b96508661562d57505050615670565b8715615637579315935b8015615641579315935b8415615658576156518688614dee565b9550615665565b6156628688615082565b95505b5050506001016155cc565b5090999850505050505050505056fe4552525f4e4f545f46494e414c495a45440000000000000000000000000000004552525f5245454e5452590000000000000000000000000000000000000000004552525f4c494d49545f494e00000000000000000000000000000000000000004552525f4d41585f4f55545f524154494f00000000000000000000000000000063982df10efd8dfaaaa0fcc7f50b2d93b7cba26ccc48adee2873220d485dc39a4552525f4e4f545f434f4e54524f4c4c455200000000000000000000000000004552525f4d41585f494e5f524154494f00000000000000000000000000000000ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef4552525f4e4f545f424f554e4400000000000000000000000000000000000000e74c91552b64c2e2e7bd255639e004e693bd3e1d01cc33e65610b86afcc1ffed8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9254552525f49535f46494e414c495a4544000000000000000000000000000000004552525f4c494d49545f4f5554000000000000000000000000000000000000004552525f4d4154485f415050524f580000000000000000000000000000000000a265627a7a72315820a6ed20be58469dda7b96f5cd85dbd70406a753a02b645704241ab59bf33344fe64736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/BToken.abi b/runtime/near-evm-runner/tests/build/BToken.abi new file mode 100644 index 00000000000..bd685b01c12 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BToken.abi @@ -0,0 +1,549 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "whom", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "increaseApproval", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "decreaseApproval", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/BToken.bin b/runtime/near-evm-runner/tests/build/BToken.bin new file mode 100644 index 00000000000..3126375860d --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BToken.bin @@ -0,0 +1 @@ +60c0604052601360808190527f42616c616e63657220506f6f6c20546f6b656e0000000000000000000000000060a090815261003e91600391906100a3565b506040805180820190915260038082527f42505400000000000000000000000000000000000000000000000000000000006020909201918252610083916004916100a3565b506005805460ff1916601217905534801561009d57600080fd5b5061013e565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100e457805160ff1916838001178555610111565b82800160010185558215610111579182015b828111156101115782518255916020019190600101906100f6565b5061011d929150610121565b5090565b61013b91905b8082111561011d5760008155600101610127565b90565b610bd88061014d6000396000f3fe608060405234801561001057600080fd5b50600436106101a1576000357c010000000000000000000000000000000000000000000000000000000090048063992e2a92116100f6578063bc694ea2116100a4578063bc694ea2146103b7578063c36596a61461028d578063c6580d12146103bf578063d73dd623146103c7578063dd62ed3e146103f3578063e4a28a5214610263578063ec09302114610421576101a1565b8063992e2a921461035b5780639a86139b14610363578063a9059cbb1461036b578063b0e0d13614610397578063b7b800a41461039f578063ba019dab146103a7578063bc063e1a146103af576101a1565b8063313ce56711610153578063313ce567146102cb57806366188463146102e957806370a082311461031557806376c7a3c71461033b578063867378c5146103435780639381cd2b1461034b57806395d89b4114610353576101a1565b806306fdde03146101a6578063095ea7b31461022357806309a3bbe41461026357806318160ddd1461027d578063189d00ca14610285578063218b53821461028d57806323b872dd14610295575b600080fd5b6101ae610429565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101e85781810151838201526020016101d0565b50505050905090810190601f1680156102155780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61024f6004803603604081101561023957600080fd5b50600160a060020a0381351690602001356104bf565b604080519115158252519081900360200190f35b61026b610513565b60408051918252519081900360200190f35b61026b610520565b61026b610526565b61026b61053a565b61024f600480360360608110156102ab57600080fd5b50600160a060020a03813581169160208101359091169060400135610546565b6102d36106ab565b6040805160ff9092168252519081900360200190f35b61024f600480360360408110156102ff57600080fd5b50600160a060020a0381351690602001356106b4565b61026b6004803603602081101561032b57600080fd5b5035600160a060020a031661078c565b61026b6107a7565b61026b6107b9565b61026b6107cd565b6101ae6107da565b61026b61083b565b61026b610847565b61024f6004803603604081101561038157600080fd5b50600160a060020a03813516906020013561086b565b61026b610881565b61026b610886565b61026b61088b565b61026b610890565b61026b6108a0565b61026b6108ac565b61024f600480360360408110156103dd57600080fd5b50600160a060020a0381351690602001356108b1565b61026b6004803603604081101561040957600080fd5b50600160a060020a0381358116916020013516610932565b61026b61095d565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104b55780601f1061048a576101008083540402835291602001916104b5565b820191906000526020600020905b81548152906001019060200180831161049857829003601f168201915b5050505050905090565b336000818152600160209081526040808320600160a060020a03871680855290835281842086905581518681529151939490939092600080516020610b84833981519152928290030190a350600192915050565b6802b5e3af16b188000081565b60025490565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b600033600160a060020a03851614806105825750600160a060020a03841660009081526001602090815260408083203384529091529020548211155b6105d6576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f42544f4b454e5f4241445f43414c4c45520000000000000000000000604482015290519081900360640190fd5b6105e184848461096d565b33600160a060020a0385161480159061061f5750600160a060020a038416600090815260016020908152604080832033845290915290205460001914155b156106a157600160a060020a03841660009081526001602090815260408083203384529091529020546106529083610a89565b600160a060020a0385811660009081526001602090815260408083203380855290835292819020859055805194855251928716939192600080516020610b848339815191529281900390910190a35b5060019392505050565b60055460ff1690565b336000908152600160209081526040808320600160a060020a03861684529091528120548083111561070957336000908152600160209081526040808320600160a060020a0388168452909152812055610738565b6107138184610a89565b336000908152600160209081526040808320600160a060020a03891684529091529020555b336000818152600160209081526040808320600160a060020a038916808552908352928190205481519081529051929392600080516020610b84833981519152929181900390910190a35060019392505050565b600160a060020a031660009081526020819052604090205490565b620f4240670de0b6b3a7640000610536565b64e8d4a51000670de0b6b3a7640000610536565b68056bc75e2d6310000081565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104b55780601f1061048a576101008083540402835291602001916104b5565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600061087833848461096d565b50600192915050565b600881565b600281565b600181565b600a670de0b6b3a7640000610536565b671bc16d674ec7ffff81565b600081565b336000908152600160209081526040808320600160a060020a03861684529091528120546108df9083610afa565b336000818152600160209081526040808320600160a060020a038916808552908352928190208590558051948552519193600080516020610b84833981519152929081900390910190a350600192915050565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b6002670de0b6b3a7640000610536565b600160a060020a0383166000908152602081905260409020548111156109dd576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e53554646494349454e545f42414c000000000000000000000000604482015290519081900360640190fd5b600160a060020a038316600090815260208190526040902054610a009082610a89565b600160a060020a038085166000908152602081905260408082209390935590841681522054610a2f9082610afa565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000806000610a988585610b5e565b915091508015610af2576040805160e560020a62461bcd02815260206004820152601160248201527f4552525f5355425f554e444552464c4f57000000000000000000000000000000604482015290519081900360640190fd5b509392505050565b600082820183811015610b57576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4144445f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b9392505050565b600080828410610b745750508082036000610b7c565b505081810360015b925092905056fe8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a265627a7a72315820a87af892d69e40e2c034544393d3427651f6eae9f394257394f44f1bd9738fdf64736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/BTokenBase.abi b/runtime/near-evm-runner/tests/build/BTokenBase.abi new file mode 100644 index 00000000000..96908e29e8b --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BTokenBase.abi @@ -0,0 +1,307 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/BTokenBase.bin b/runtime/near-evm-runner/tests/build/BTokenBase.bin new file mode 100644 index 00000000000..ff5c54e21c4 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/BTokenBase.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b5061029c806100206000396000f3fe608060405234801561001057600080fd5b5060043610610108576000357c010000000000000000000000000000000000000000000000000000000090048063b0e0d136116100af578063b0e0d1361461015f578063b7b800a414610167578063ba019dab1461016f578063bc063e1a14610177578063bc694ea21461017f578063c36596a61461012f578063c6580d1214610187578063e4a28a521461010d578063ec0930211461018f57610108565b806309a3bbe41461010d578063189d00ca14610127578063218b53821461012f57806376c7a3c714610137578063867378c51461013f5780639381cd2b14610147578063992e2a921461014f5780639a86139b14610157575b600080fd5b610115610197565b60408051918252519081900360200190f35b6101156101a4565b6101156101b8565b6101156101c4565b6101156101d6565b6101156101ea565b6101156101f7565b610115610203565b610115610227565b61011561022c565b610115610231565b610115610236565b610115610246565b610115610252565b610115610257565b6802b5e3af16b188000081565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b620f4240670de0b6b3a76400006101b4565b64e8d4a51000670de0b6b3a76400006101b4565b68056bc75e2d6310000081565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600881565b600281565b600181565b600a670de0b6b3a76400006101b4565b671bc16d674ec7ffff81565b600081565b6002670de0b6b3a76400006101b456fea265627a7a7231582008760bf61cf90a4adde4f0558f43bdcd8f3e5cdf97aca2d1957bb4fef5289a1764736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/ConstructorRevert.abi b/runtime/near-evm-runner/tests/build/ConstructorRevert.abi new file mode 100644 index 00000000000..924c382d804 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/ConstructorRevert.abi @@ -0,0 +1,8 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } +] diff --git a/runtime/near-evm-runner/tests/build/Create2Factory.abi b/runtime/near-evm-runner/tests/build/Create2Factory.abi new file mode 100644 index 00000000000..0147fe22194 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/Create2Factory.abi @@ -0,0 +1,59 @@ +[ + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bytes32", + "name": "_salt", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_contractBytecode", + "type": "bytes" + } + ], + "name": "deploy", + "outputs": [ + { + "internalType": "address payable", + "name": "addr", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bytes32", + "name": "_salt", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_contractBytecode", + "type": "bytes" + } + ], + "name": "testDoubleDeploy", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/Create2Factory.bin b/runtime/near-evm-runner/tests/build/Create2Factory.bin new file mode 100644 index 00000000000..5c18234a6ab --- /dev/null +++ b/runtime/near-evm-runner/tests/build/Create2Factory.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50610758806100206000396000f3fe6080604052600436106100295760003560e01c80639f45e8151461002b578063cdcb760a14610108575b005b6100ee6004803603604081101561004157600080fd5b81019080803590602001909291908035906020019064010000000081111561006857600080fd5b82018360208201111561007a57600080fd5b8035906020019184600183028401116401000000008311171561009c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061021a565b604051808215151515815260200191505060405180910390f35b34801561011457600080fd5b506101d86004803603604081101561012b57600080fd5b81019080803590602001909291908035906020019064010000000081111561015257600080fd5b82018360208201111561016457600080fd5b8035906020019184600183028401116401000000008311171561018657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506106c7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008061022784846106c7565b905060008190508073ffffffffffffffffffffffffffffffffffffffff1663eef4c90f60056040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561028257600080fd5b505af1158015610296573d6000803e3d6000fd5b5050505060058173ffffffffffffffffffffffffffffffffffffffff16636e4d2a346040518163ffffffff1660e01b815260040160206040518083038186803b1580156102e257600080fd5b505afa1580156102f6573d6000803e3d6000fd5b505050506040513d602081101561030c57600080fd5b810190808051906020019092919050505014610390576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f7072652d6465737472756374696f6e2077726f6e672075696e7400000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663d37c6c9e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156103d857600080fd5b505af11580156103ec573d6000803e3d6000fd5b5050505060606103fb826106db565b90506000815114610474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f706f73742d6465737472756374696f6e20636f6465206c656e6774680000000081525060200191505060405180910390fd5b61047e86866106c7565b5060008273ffffffffffffffffffffffffffffffffffffffff16636e4d2a346040518163ffffffff1660e01b815260040160206040518083038186803b1580156104c757600080fd5b505afa1580156104db573d6000803e3d6000fd5b505050506040513d60208110156104f157600080fd5b810190808051906020019092919050505014610575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f706f73742d6465737472756374696f6e2077726f6e672075696e74000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663eef4c90f60036040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b5050505060038273ffffffffffffffffffffffffffffffffffffffff16636e4d2a346040518163ffffffff1660e01b815260040160206040518083038186803b15801561062957600080fd5b505afa15801561063d573d6000803e3d6000fd5b505050506040513d602081101561065357600080fd5b8101908080519060200190929190505050146106ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806107026022913960400191505060405180910390fd5b6001935050505092915050565b6000828251602084016000f5905092915050565b60606040519050813b8082526020820181600082863c818352818101604052505091905056fe706f73742d6465737472756374696f6e2073746f7265642077726f6e672075696e74a265627a7a72315820e8aa482dbb1ad5a50769172bb326b40795aaa96e6340d1443c2ce7fdf22f071564736f6c63430005100032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/IERC20.abi b/runtime/near-evm-runner/tests/build/IERC20.abi new file mode 100644 index 00000000000..a8a6512c554 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/IERC20.abi @@ -0,0 +1,197 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "whom", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/Migrations.abi b/runtime/near-evm-runner/tests/build/Migrations.abi new file mode 100644 index 00000000000..bc177e8cb7a --- /dev/null +++ b/runtime/near-evm-runner/tests/build/Migrations.abi @@ -0,0 +1,68 @@ +[ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "constant": true, + "inputs": [], + "name": "lastCompletedMigration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "completed", + "type": "uint256" + } + ], + "name": "setCompleted", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "new_address", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/Migrations.bin b/runtime/near-evm-runner/tests/build/Migrations.bin new file mode 100644 index 00000000000..30bf5398e99 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/Migrations.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b5060008054600160a060020a031916331790556101b9806100326000396000f3fe608060405234801561001057600080fd5b506004361061004f5760e060020a60003504630900f01081146100545780638da5cb5b1461007c578063fbdbad3c146100a0578063fdacd576146100ba575b600080fd5b61007a6004803603602081101561006a57600080fd5b5035600160a060020a03166100d7565b005b610084610157565b60408051600160a060020a039092168252519081900360200190f35b6100a8610166565b60408051918252519081900360200190f35b61007a600480360360208110156100d057600080fd5b503561016c565b600054600160a060020a031633141561015457600081905080600160a060020a031663fdacd5766001546040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b15801561013a57600080fd5b505af115801561014e573d6000803e3d6000fd5b50505050505b50565b600054600160a060020a031681565b60015481565b600054600160a060020a03163314156101545760015556fea265627a7a7231582023ed50b526b6a1b0948c964d1041e7f84e7a132d4284b38755f775875359435d64736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/PrecompiledFunction.abi b/runtime/near-evm-runner/tests/build/PrecompiledFunction.abi new file mode 100644 index 00000000000..98369784154 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/PrecompiledFunction.abi @@ -0,0 +1,204 @@ +[ + { + "inputs": [], + "payable": true, + "stateMutability": "payable", + "type": "constructor" + }, + { + "constant": true, + "inputs": [], + "name": "noop", + "outputs": [], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "testSha256", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "testSha256_100bytes", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "testEcrecover", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "testRipemd160", + "outputs": [ + { + "internalType": "bytes20", + "name": "", + "type": "bytes20" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "testRipemd160_1kb", + "outputs": [ + { + "internalType": "bytes20", + "name": "", + "type": "bytes20" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "identity", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "test_identity", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "test_identity_100bytes", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "base", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "e", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "m", + "type": "uint256" + } + ], + "name": "modexp", + "outputs": [ + { + "internalType": "uint256", + "name": "o", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "testModExp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "testBn128Add", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/PrecompiledFunction.bin b/runtime/near-evm-runner/tests/build/PrecompiledFunction.bin new file mode 100644 index 00000000000..198e45d143f --- /dev/null +++ b/runtime/near-evm-runner/tests/build/PrecompiledFunction.bin @@ -0,0 +1 @@ +6080604052610c2c806100136000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063840f612011610071578063840f61201461026d5780638a6fa9da146103a1578063a449e8eb146103bf578063a7d4bbe6146103dd578063b7a0961a14610433578063e96cc75c1461046f576100b4565b806304e87187146100b9578063080e99331461013c5780631d82afc71461015a578063494236eb146101dd57806351163670146102195780635dfc2e4a14610263575b600080fd5b6100c161048d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101015780820151818401526020810190506100e6565b50505050905090810190601f16801561012e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101446104b5565b6040518082815260200191505060405180910390f35b610162610512565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101a2578082015181840152602081019050610187565b50505050905090810190601f1680156101cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101e5610531565b60405180826bffffffffffffffffffffffff19166bffffffffffffffffffffffff1916815260200191505060405180910390f35b610221610574565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61026b610640565b005b6103266004803603602081101561028357600080fd5b81019080803590602001906401000000008111156102a057600080fd5b8201836020820111156102b257600080fd5b803590602001918460018302840111640100000000831117156102d457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610642565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561036657808201518184015260208101905061034b565b50505050905090810190601f1680156103935780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a961069e565b6040518082815260200191505060405180910390f35b6103c76106a3565b6040518082815260200191505060405180910390f35b61041d600480360360608110156103f357600080fd5b810190808035906020019092919080359060200190929190803590602001909291905050506106f8565b6040518082815260200191505060405180910390f35b61043b610743565b60405180826bffffffffffffffffffffffff19166bffffffffffffffffffffffff1916815260200191505060405180910390f35b61047761077c565b6040518082815260200191505060405180910390f35b60606104b06040518060a0016040528060658152602001610b9360659139610642565b905090565b600060026040518080610b93606591396065019050602060405180830381855afa1580156104e7573d6000803e3d6000fd5b5050506040513d60208110156104fc57600080fd5b8101908080519060200190929190505050905090565b606061052c60405180602001604052806000815250610642565b905090565b6000600360405180806107936104009139610400019050602060405180830381855afa158015610565573d6000803e3d6000fd5b5050506040515160601b905090565b60006001601b6040516000815260200160405260405180807f11111111111111111111111111111111111111111111111111111111111111118152506020018260ff168152602001807fb9f0bb08640d3c1c00761cdd0121209268f6fd3816bc98b9e6f3cc77bf82b698815250602001807f12ac7a61788a0fdc0e19180f14c945a8e1088a27d92a74dce81c0981fb6447448152506020019150506020604051602081039080840390855afa158015610631573d6000803e3d6000fd5b50505060206040510351905090565b565b60608082516040519080825280601f01601f1916602001820160405280156106795781602001600182028038833980820191505090505b509050825180602083018260208701600060045af161069457fe5b5080915050919050565b600090565b60006002604051806000019050602060405180830381855afa1580156106cd573d6000803e3d6000fd5b5050506040513d60208110156106e257600080fd5b8101908080519060200190929190505050905090565b600060405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360056107d05a03fa61073757600080fd5b80519150509392505050565b60006003604051806000019050602060405180830381855afa15801561076d573d6000803e3d6000fd5b5050506040515160601b905090565b600061078d61303960ad60656106f8565b90509056fe6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f707172737475767778797a6162636465666768696a6b6c6d6e6f7071727374757677a265627a7a723158205d2c2b792d903870209e310c124cea57de9949e98fa1104d789ef0f5fea175cd64736f6c63430005100032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/SelfDestruct.abi b/runtime/near-evm-runner/tests/build/SelfDestruct.abi new file mode 100644 index 00000000000..b9d714edbba --- /dev/null +++ b/runtime/near-evm-runner/tests/build/SelfDestruct.abi @@ -0,0 +1,70 @@ +[ + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": true, + "inputs": [], + "name": "storedAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "storedUint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "storeAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "_number", + "type": "uint256" + } + ], + "name": "storeUint", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "destruction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/SelfDestruct.bin b/runtime/near-evm-runner/tests/build/SelfDestruct.bin new file mode 100644 index 00000000000..176353f70ea --- /dev/null +++ b/runtime/near-evm-runner/tests/build/SelfDestruct.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506101fc806100206000396000f3fe60806040526004361061004a5760003560e01c80636e4d2a341461004c5780638f63640e14610077578063d37c6c9e146100ce578063eef4c90f146100e5578063f2c4da9314610120575b005b34801561005857600080fd5b50610061610137565b6040518082815260200191505060405180910390f35b34801561008357600080fd5b5061008c61013d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100da57600080fd5b506100e3610162565b005b3480156100f157600080fd5b5061011e6004803603602081101561010857600080fd5b810190808035906020019092919050505061017b565b005b34801561012c57600080fd5b50610135610185565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b8060018190555050565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555056fea265627a7a72315820bc2518d7325b1a42a627271a1c315221090ec42188a01825fcea78176392f4c164736f6c63430005100032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/SolTests.abi b/runtime/near-evm-runner/tests/build/SolTests.abi new file mode 100644 index 00000000000..94ded1f86dd --- /dev/null +++ b/runtime/near-evm-runner/tests/build/SolTests.abi @@ -0,0 +1,188 @@ +[ + { + "inputs": [], + "payable": true, + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_contract", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "DeployEvent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_number", + "type": "uint256" + } + ], + "name": "SomeEvent", + "type": "event" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": true, + "inputs": [], + "name": "balance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "transferTo", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "_aNumber", + "type": "uint256" + } + ], + "name": "deployNewGuy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "_aNumber", + "type": "uint256" + } + ], + "name": "payNewGuy", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "returnSomeFunds", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "_aNumber", + "type": "uint256" + } + ], + "name": "emitIt", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "precompileTest", + "outputs": [], + "payable": false, + "stateMutability": "pure", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/SolTests.bin b/runtime/near-evm-runner/tests/build/SolTests.bin new file mode 100644 index 00000000000..b7bacad4583 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/SolTests.bin @@ -0,0 +1 @@ +6080604052610a87806100136000396000f3fe6080604052600436106100705760003560e01c8063299fb0431161004e578063299fb043146101af5780632ccb1b30146101c65780639d9f9a6e14610235578063b69ef8a81461028657610070565b80630a84cba514610072578063111e0b12146100e757806314d54f541461015c575b005b61009e6004803603602081101561008857600080fd5b81019080803590602001909291905050506102b1565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b610113600480360360208110156100fd57600080fd5b8101908080359060200190929190505050610390565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b34801561016857600080fd5b506101956004803603602081101561017f57600080fd5b81019080803590602001909291905050506103dc565b604051808215151515815260200191505060405180910390f35b3480156101bb57600080fd5b506101c461041e565b005b3480156101d257600080fd5b5061021f600480360360408110156101e957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610756565b6040518082815260200191505060405180910390f35b61023d6107af565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b34801561029257600080fd5b5061029b610810565b6040518082815260200191505060405180910390f35b6000806000836040516102c390610818565b80828152602001915050604051809103906000f0801580156102e9573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015610332573d6000803e3d6000fd5b508073ffffffffffffffffffffffffffffffffffffffff167fa53ffc4fb91f5ca8287e168fc73db3b0b384a6ca275650f885a1740ef7a0bc1c346040518082815260200191505060405180910390a280348191509250925050915091565b600080600034846040516103a390610818565b808281526020019150506040518091039082f0801580156103c8573d6000803e3d6000fd5b509050905080348191509250925050915091565b60007f379340f64b65a8890c7ea4f6d86d2359beaf41080f36a7ea64b78a2c06eee3f0826040518082815260200191505060405180910390a160019050919050565b7fe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8556002604051806000019050602060405180830381855afa158015610467573d6000803e3d6000fd5b5050506040513d602081101561047c57600080fd5b810190808051906020019092919050505014610500576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f7368613220646967657374206d69736d6174636800000000000000000000000081525060200191505060405180910390fd5b7f9c1185a5c5e9fc54612808977ee8f548b2258d310000000000000000000000006003604051806000019050602060405180830381855afa158015610549573d6000803e3d6000fd5b5050506040515160601b6bffffffffffffffffffffffff1916146105d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f726d6431363020646967657374206d69736d617463680000000000000000000081525060200191505060405180910390fd5b60006001601b6040516000815260200160405260405180807f11111111111111111111111111111111111111111111111111111111111111118152506020018260ff168152602001807fb9f0bb08640d3c1c00761cdd0121209268f6fd3816bc98b9e6f3cc77bf82b698815250602001807f12ac7a61788a0fdc0e19180f14c945a8e1088a27d92a74dce81c0981fb6447448152506020019150506020604051602081039080840390855afa158015610692573d6000803e3d6000fd5b505050602060405103519050731563915e194d8cfba1943570603f7606a311550873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610753576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f65637265636f766572206d69736d61746368000000000000000000000000000081525060200191505060405180910390fd5b50565b60008273ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f1935050505015801561079e573d6000803e3d6000fd5b506107a7610810565b905092915050565b6000803373ffffffffffffffffffffffffffffffffffffffff166108fc600234816107d657fe5b049081150290604051600060405180830381858888f19350505050158015610802573d6000803e3d6000fd5b503334819150915091509091565b600047905090565b61022d806108268339019056fe6080604052600660005560405161022d38038061022d8339818101604052602081101561002b57600080fd5b810190808051906020019092919050505080600081905550506101da806100536000396000f3fe60806040526004361061003f5760003560e01c80632ccb1b301461004157806339c117a4146100b0578063b69ef8a8146100df578063e6a899b61461010a575b005b34801561004d57600080fd5b5061009a6004803603604081101561006457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610135565b6040518082815260200191505060405180910390f35b3480156100bc57600080fd5b506100c561018e565b604051808215151515815260200191505060405180910390f35b3480156100eb57600080fd5b506100f4610197565b6040518082815260200191505060405180910390f35b34801561011657600080fd5b5061011f61019f565b6040518082815260200191505060405180910390f35b60008273ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f1935050505015801561017d573d6000803e3d6000fd5b50610186610197565b905092915050565b60006001905090565b600047905090565b6000548156fea265627a7a72315820e36da559b208b35510871048d70a0d6e8f4b25035fff6508b43b8eb718e4959e64736f6c63430005100032a265627a7a72315820d93d617e67411c892e102bf050987a9d89de3c461d600c727f04c59dc88f078864736f6c63430005100032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/StandardPrecompiles.abi b/runtime/near-evm-runner/tests/build/StandardPrecompiles.abi new file mode 100644 index 00000000000..b67026e373c --- /dev/null +++ b/runtime/near-evm-runner/tests/build/StandardPrecompiles.abi @@ -0,0 +1,137 @@ +[ + { + "inputs" : [], + "type" : "constructor", + "stateMutability" : "payable" + }, + { + "type" : "function", + "inputs" : [], + "name" : "test_all", + "stateMutability" : "view", + "outputs" : [ + { + "type" : "bool", + "internalType" : "bool", + "name" : "" + } + ] + }, + { + "outputs" : [ + { + "type" : "bool", + "internalType" : "bool", + "name" : "" + } + ], + "stateMutability" : "view", + "name" : "test_blake2f", + "inputs" : [], + "type" : "function" + }, + { + "inputs" : [], + "type" : "function", + "stateMutability" : "view", + "name" : "test_ecadd", + "outputs" : [ + { + "name" : "", + "internalType" : "bool", + "type" : "bool" + } + ] + }, + { + "inputs" : [], + "type" : "function", + "stateMutability" : "view", + "name" : "test_ecmul", + "outputs" : [ + { + "internalType" : "bool", + "type" : "bool", + "name" : "" + } + ] + }, + { + "type" : "function", + "inputs" : [], + "name" : "test_ecpair", + "stateMutability" : "view", + "outputs" : [ + { + "type" : "bool", + "internalType" : "bool", + "name" : "" + } + ] + }, + { + "type" : "function", + "inputs" : [], + "outputs" : [ + { + "internalType" : "bool", + "type" : "bool", + "name" : "" + } + ], + "stateMutability" : "pure", + "name" : "test_ecrecover" + }, + { + "inputs" : [], + "type" : "function", + "outputs" : [ + { + "name" : "", + "type" : "bool", + "internalType" : "bool" + } + ], + "name" : "test_identity", + "stateMutability" : "view" + }, + { + "outputs" : [ + { + "type" : "bool", + "internalType" : "bool", + "name" : "" + } + ], + "stateMutability" : "view", + "name" : "test_modexp", + "inputs" : [], + "type" : "function" + }, + { + "stateMutability" : "pure", + "name" : "test_ripemd160", + "outputs" : [ + { + "type" : "bool", + "internalType" : "bool", + "name" : "" + } + ], + "inputs" : [], + "type" : "function" + }, + { + "stateMutability" : "pure", + "name" : "test_sha256", + "outputs" : [ + { + "type" : "bool", + "internalType" : "bool", + "name" : "" + } + ], + "inputs" : [], + "type" : "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/StandardPrecompiles.bin b/runtime/near-evm-runner/tests/build/StandardPrecompiles.bin new file mode 100644 index 00000000000..0648ee6a8cd --- /dev/null +++ b/runtime/near-evm-runner/tests/build/StandardPrecompiles.bin @@ -0,0 +1 @@ +60806040526113b5806100136000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063aefff86311610066578063aefff86314610143578063d06d2a3114610163578063d7d4430414610183578063da726c1b146101a3578063ff71b530146101c35761009e565b8063166f2a2f146100a35780631d82afc7146100c35780633ae57cb6146100e357806341d5e54514610103578063a7465fca14610123575b600080fd5b6100ab6101e3565b60405180821515815260200191505060405180910390f35b6100cb610303565b60405180821515815260200191505060405180910390f35b6100eb61035e565b60405180821515815260200191505060405180910390f35b61010b6103d5565b60405180821515815260200191505060405180910390f35b61012b6104b9565b60405180821515815260200191505060405180910390f35b61014b61090c565b60405180821515815260200191505060405180910390f35b61016b61097b565b60405180821515815260200191505060405180910390f35b61018b6109e2565b60405180821515815260200191505060405180910390f35b6101ab610a4c565b60405180821515815260200191505060405180910390f35b6101cb610caf565b60405180821515815260200191505060405180910390f35b60006101ed611136565b6102857f18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc960001b7f063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726660001b7f07c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed60001b7f06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d760001b610ce5565b90507f2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee20283970360001b816000600281106102b857fe5b60200201511480156102fd57507f301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c91560001b816001600281106102f657fe5b6020020151145b91505090565b600060606040518060400160405280602081526020017f11111111111111111111111111111111111111111111111111111111111111118152509050808051906020012061035082610d40565b805190602001201491505090565b60007fe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8556002604051806000019050602060405180830381855afa1580156103a9573d6000803e3d6000fd5b5050506040513d60208110156103be57600080fd5b810190808051906020019092919050505014905090565b60006103df611136565b61043b7f2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb760001b7f21611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb20460001b6711138ce750fa15c260001b610dc0565b90507f070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c60001b8160006002811061046e57fe5b60200201511480156104b357507f031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc60001b816001600281106104ac57fe5b6020020151145b91505090565b60006104c361090c565b610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f6572726f6e656f75732065637265636f76657220707265636f6d70696c65000081525060200191505060405180910390fd5b61053d61035e565b6105af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f6572726f6e656f75732073686132353620707265636f6d70696c65000000000081525060200191505060405180910390fd5b6105b76109e2565b610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f6572726f6e656f757320726970656d6431363020707265636f6d70696c65000081525060200191505060405180910390fd5b610631610303565b6106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f6572726f6e656f7573206964656e7469747920707265636f6d70696c6500000081525060200191505060405180910390fd5b6106ab61097b565b61071d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f6572726f6e656f7573206d6f6465787020707265636f6d70696c65000000000081525060200191505060405180910390fd5b6107256101e3565b610797576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6572726f6e656f757320656361646420707265636f6d70696c6500000000000081525060200191505060405180910390fd5b61079f6103d5565b610811576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6572726f6e656f75732065636d756c20707265636f6d70696c6500000000000081525060200191505060405180910390fd5b610819610caf565b61088b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f6572726f6e656f75732065637061697220707265636f6d70696c65000000000081525060200191505060405180910390fd5b610893610a4c565b610905576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6572726f6e656f757320626c616b65326620707265636f6d70696c650000000081525060200191505060405180910390fd5b6001905090565b6000807f11111111111111111111111111111111111111111111111111111111111111119050606060405180608001604052806041815260200161133f6041913990506000731563915e194d8cfba1943570603f7606a31155089050610973838383610e14565b935050505090565b6000806003905060007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e905060007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f905060016109d9848484610e6e565b14935050505090565b60007f9c1185a5c5e9fc54612808977ee8f548b2258d310000000000000000000000006003604051806000019050602060405180830381855afa158015610a2d573d6000803e3d6000fd5b5050506040515160601b6bffffffffffffffffffffffff191614905090565b600080600c9050610a5b611136565b7f48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa581600060028110610a8957fe5b6020020181815250507fd182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b81600160028110610ac057fe5b602002018181525050610ad1611158565b7f616263000000000000000000000000000000000000000000000000000000000081600060048110610aff57fe5b602002018181525050600081600160048110610b1757fe5b602002018181525050600081600260048110610b2f57fe5b602002018181525050600081600360048110610b4757fe5b602002018181525050610b5861117a565b7f030000000000000000000000000000000000000000000000000000000000000081600060028110610b8657fe5b602002019077ffffffffffffffffffffffffffffffffffffffffffffffff1916908177ffffffffffffffffffffffffffffffffffffffffffffffff191681525050600081600160028110610bd657fe5b602002019077ffffffffffffffffffffffffffffffffffffffffffffffff1916908177ffffffffffffffffffffffffffffffffffffffffffffffff191681525050600060019050610c25611136565b610c328686868686610ec1565b90507fba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d181600060028110610c6257fe5b6020020151148015610ca457507f7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd400992381600160028110610c9d57fe5b6020020151145b965050505050505090565b600080610cd6604051806101a0016040528061018081526020016111bf6101809139611039565b9050600160001b811491505090565b610ced611136565b610cf5611158565b604051806080016040528087815260200186815260200185815260200184815250905060408260808360065afa8060008114610d3057610d35565b600080fd5b505050949350505050565b606080825167ffffffffffffffff81118015610d5b57600080fd5b506040519080825280601f01601f191660200182016040528015610d8e5781602001600182028036833780820191505090505b50905082518060208301826020870160045afa8060008114610daf57610db4565b600080fd5b50505080915050919050565b610dc8611136565b610dd061119c565b604051806060016040528086815260200185815260200184815250905060408260608360075afa8060008114610e0557610e0a565b600080fd5b5050509392505050565b6000806000610e238686611086565b8092508193505050818015610e6357508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b925050509392505050565b600060405160208152602080820152602060408201528460608201528360808201528260a082015260208160c08360055afa8060008114610eb25782519350610eb7565b600080fd5b5050509392505050565b610ec9611136565b610ed1611136565b60608787600060028110610ee157fe5b602002015188600160028110610ef357fe5b602002015188600060048110610f0557fe5b602002015189600160048110610f1757fe5b60200201518a600260048110610f2957fe5b60200201518b600360048110610f3b57fe5b60200201518b600060028110610f4d57fe5b60200201518c600160028110610f5f57fe5b60200201518c604051602001808b63ffffffff1660e01b81526004018a81526020018981526020018881526020018781526020018681526020018581526020018477ffffffffffffffffffffffffffffffffffffffffffffffff191681526008018377ffffffffffffffffffffffffffffffffffffffffffffffff1916815260080182151560f81b81526001019a5050505050505050505050604051602081830303815290604052905060408260d56020840160095afa806000811461102457611029565b600080fd5b5050819250505095945050505050565b60008082519050600060c0828161104c57fe5b061461105757600080fd5b604051602081836020870160085afa8060008114611078578251945061107d565b600080fd5b50505050919050565b600080604183511461109e576000809150915061112f565b60008060006020860151925060408601519150606086015160001a9050600060018883868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611117573d6000803e3d6000fd5b50505060206040510351905060018195509550505050505b9250929050565b6040518060400160405280600290602082028036833780820191505090505090565b6040518060800160405280600490602082028036833780820191505090505090565b6040518060400160405280600290602082028036833780820191505090505090565b604051806060016040528060039060208202803683378082019150509050509056fe1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daab9f0bb08640d3c1c00761cdd0121209268f6fd3816bc98b9e6f3cc77bf82b69812ac7a61788a0fdc0e19180f14c945a8e1088a27d92a74dce81c0981fb6447441ba26469706673582212203acf67adc69694b9cae057a502d5c1741f3f0e71a7bd73034e88327c199996da64736f6c63430007030033 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/SubContract.abi b/runtime/near-evm-runner/tests/build/SubContract.abi new file mode 100644 index 00000000000..c3933cb84ba --- /dev/null +++ b/runtime/near-evm-runner/tests/build/SubContract.abi @@ -0,0 +1,90 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_aNumber", + "type": "uint256" + } + ], + "payable": true, + "stateMutability": "payable", + "type": "constructor" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": true, + "inputs": [], + "name": "aNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "balance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "transferTo", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "aFunction", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/TBPoolJoinExit.abi b/runtime/near-evm-runner/tests/build/TBPoolJoinExit.abi new file mode 100644 index 00000000000..8a33cf7ccaf --- /dev/null +++ b/runtime/near-evm-runner/tests/build/TBPoolJoinExit.abi @@ -0,0 +1,302 @@ +[ + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "echidna_no_bug_found", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolTotal", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_records_t_balance", + "type": "uint256" + } + ], + "name": "joinAndExitPool", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/TBPoolJoinExit.bin b/runtime/near-evm-runner/tests/build/TBPoolJoinExit.bin new file mode 100644 index 00000000000..268dfee4a38 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/TBPoolJoinExit.bin @@ -0,0 +1 @@ +60806040526000805460ff1916600117905534801561001d57600080fd5b506108298061002d6000396000f3fe608060405234801561001057600080fd5b506004361061012e576000357c0100000000000000000000000000000000000000000000000000000000900480639a86139b116100ca578063bc694ea21161008e578063bc694ea2146101f2578063c36596a614610171578063c6580d12146101fa578063e4a28a5214610133578063ec093021146102025761012e565b80639a86139b146101ca578063b0e0d136146101d2578063b7b800a4146101da578063ba019dab146101e2578063bc063e1a146101ea5761012e565b806309a3bbe4146101335780631819aa421461014d578063189d00ca14610169578063218b5382146101715780632370e3a41461017957806376c7a3c7146101aa578063867378c5146101b25780639381cd2b146101ba578063992e2a92146101c2575b600080fd5b61013b61020a565b60408051918252519081900360200190f35b610155610217565b604080519115158252519081900360200190f35b61013b610220565b61013b610234565b6101a86004803603608081101561018f57600080fd5b5080359060208101359060408101359060600135610240565b005b61013b610317565b61013b610329565b61013b61033d565b61013b61034a565b61013b610356565b61013b61037a565b61013b61037f565b61013b610384565b61013b610389565b61013b610399565b61013b6103a5565b61013b6103aa565b6802b5e3af16b188000081565b60005460ff1681565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b600061024d8584846103ba565b905068056bc75e2d6310000083111561026557600080fd5b670de0b6b3a764000083101561027a57600080fd5b678ac7230489e8000082111561028f57600080fd5b620f424082101561029f57600080fd5b6102a98386610436565b92506102b58282610436565b9150600081116102c457600080fd5b838310156102d157600080fd5b60006102de85858561049a565b9050808310156102ed57600080fd5b8486116102f957600080fd5b81811461030557600080fd5b50506000805460ff1916905550505050565b620f4240670de0b6b3a7640000610230565b64e8d4a51000670de0b6b3a7640000610230565b68056bc75e2d6310000081565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600881565b600281565b600181565b600a670de0b6b3a7640000610230565b671bc16d674ec7ffff81565b600081565b6002670de0b6b3a7640000610230565b6000806103c78585610535565b90508061041e576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4d4154485f415050524f580000000000000000000000000000000000604482015290519081900360640190fd5b82600061042b838361067c565b979650505050505050565b600082820183811015610493576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4144445f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b9392505050565b6000806104a885600061067c565b905060006104b6868361075e565b905060006104c48287610535565b90508061051b576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4d4154485f415050524f580000000000000000000000000000000000604482015290519081900360640190fd5b846000610528838361067c565b9998505050505050505050565b60008161058c576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4449565f5a45524f0000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a764000083028315806105b45750670de0b6b3a76400008482816105b157fe5b04145b610608576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b60028304810181811015610666576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b600084828161067157fe5b049695505050505050565b600082820283158061069657508284828161069357fe5b04145b6106ea576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6706f05b59d3b2000081018181101561074d576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6000670de0b6b3a764000082610671565b600080600061076d85856107cf565b9150915080156107c7576040805160e560020a62461bcd02815260206004820152601160248201527f4552525f5355425f554e444552464c4f57000000000000000000000000000000604482015290519081900360640190fd5b509392505050565b6000808284106107e557505080820360006107ed565b505081810360015b925092905056fea265627a7a723158201790844e1e2552cec4a67cc6ca52dd783178e8f791461ba35e1a0422e236dca664736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/TBPoolJoinExitNoFee.abi b/runtime/near-evm-runner/tests/build/TBPoolJoinExitNoFee.abi new file mode 100644 index 00000000000..f47c54d1493 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/TBPoolJoinExitNoFee.abi @@ -0,0 +1,302 @@ +[ + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "echidna_no_bug_found", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolTotal", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_records_t_balance", + "type": "uint256" + } + ], + "name": "joinAndExitNoFeePool", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/TBPoolJoinExitNoFee.bin b/runtime/near-evm-runner/tests/build/TBPoolJoinExitNoFee.bin new file mode 100644 index 00000000000..a42713dc1ac --- /dev/null +++ b/runtime/near-evm-runner/tests/build/TBPoolJoinExitNoFee.bin @@ -0,0 +1 @@ +60806040526000805460ff1916600117905534801561001d57600080fd5b506106f88061002d6000396000f3fe608060405234801561001057600080fd5b506004361061012e576000357c010000000000000000000000000000000000000000000000000000000090048063b0e0d136116100ca578063c36596a61161008e578063c36596a614610171578063c6580d12146101c9578063e15c7d42146101d1578063e4a28a5214610133578063ec093021146102025761012e565b8063b0e0d136146101a1578063b7b800a4146101a9578063ba019dab146101b1578063bc063e1a146101b9578063bc694ea2146101c15761012e565b806309a3bbe4146101335780631819aa421461014d578063189d00ca14610169578063218b53821461017157806376c7a3c714610179578063867378c5146101815780639381cd2b14610189578063992e2a92146101915780639a86139b14610199575b600080fd5b61013b61020a565b60408051918252519081900360200190f35b610155610217565b604080519115158252519081900360200190f35b61013b610220565b61013b610234565b61013b610240565b61013b610252565b61013b610266565b61013b610273565b61013b61027f565b61013b6102a3565b61013b6102a8565b61013b6102ad565b61013b6102b2565b61013b6102c2565b61013b6102ce565b610200600480360360808110156101e757600080fd5b50803590602081013590604081013590606001356102d3565b005b61013b6103aa565b6802b5e3af16b188000081565b60005460ff1681565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b620f4240670de0b6b3a7640000610230565b64e8d4a51000670de0b6b3a7640000610230565b68056bc75e2d6310000081565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600881565b600281565b600181565b600a670de0b6b3a7640000610230565b671bc16d674ec7ffff81565b600081565b60006102e08584846103ba565b905068056bc75e2d631000008311156102f857600080fd5b670de0b6b3a764000083101561030d57600080fd5b678ac7230489e8000082111561032257600080fd5b620f424082101561033257600080fd5b61033c8386610436565b92506103488282610436565b91506000811161035757600080fd5b8383101561036457600080fd5b60006103718585856103ba565b90508083101561038057600080fd5b84861161038c57600080fd5b81811461039857600080fd5b50506000805460ff1916905550505050565b6002670de0b6b3a7640000610230565b6000806103c7858561049a565b90508061041e576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4d4154485f415050524f580000000000000000000000000000000000604482015290519081900360640190fd5b82600061042b83836105e1565b979650505050505050565b600082820183811015610493576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4144445f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b9392505050565b6000816104f1576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4449565f5a45524f0000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a764000083028315806105195750670de0b6b3a764000084828161051657fe5b04145b61056d576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b600283048101818110156105cb576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b60008482816105d657fe5b049695505050505050565b60008282028315806105fb5750828482816105f857fe5b04145b61064f576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6706f05b59d3b200008101818110156106b2576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6000670de0b6b3a7640000826105d656fea265627a7a72315820ed2924388694d36bdbe4d7941a0e87d38ab5eeb0b511a244b36f45486e75febf64736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/TBPoolJoinPool.abi b/runtime/near-evm-runner/tests/build/TBPoolJoinPool.abi new file mode 100644 index 00000000000..6f3372807ae --- /dev/null +++ b/runtime/near-evm-runner/tests/build/TBPoolJoinPool.abi @@ -0,0 +1,303 @@ +[ + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "echidna_no_bug_found", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolTotal", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_records_t_balance", + "type": "uint256" + } + ], + "name": "joinPool", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/TBPoolJoinPool.bin b/runtime/near-evm-runner/tests/build/TBPoolJoinPool.bin new file mode 100644 index 00000000000..65ea9d6ab16 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/TBPoolJoinPool.bin @@ -0,0 +1 @@ +60806040526000805460ff1916600117905534801561001d57600080fd5b506106298061002d6000396000f3fe608060405234801561001057600080fd5b506004361061012e576000357c0100000000000000000000000000000000000000000000000000000000900480639a86139b116100ca578063bc694ea21161008e578063bc694ea2146101ea578063c36596a614610171578063c6580d12146101f2578063e4a28a5214610133578063ec093021146101fa5761012e565b80639a86139b146101c2578063b0e0d136146101ca578063b7b800a4146101d2578063ba019dab146101da578063bc063e1a146101e25761012e565b806309a3bbe4146101335780631819aa421461014d578063189d00ca14610169578063218b5382146101715780632e6884451461017957806376c7a3c7146101a2578063867378c5146101aa5780639381cd2b146101b2578063992e2a92146101ba575b600080fd5b61013b610202565b60408051918252519081900360200190f35b61015561020f565b604080519115158252519081900360200190f35b61013b610218565b61013b61022c565b61013b6004803603606081101561018f57600080fd5b5080359060208101359060400135610238565b61013b610328565b61013b61033a565b61013b61034e565b61013b61035b565b61013b610367565b61013b61038b565b61013b610390565b61013b610395565b61013b61039a565b61013b6103aa565b61013b6103b6565b61013b6103bb565b6802b5e3af16b188000081565b60005460ff1681565b6402540be400670de0b6b3a76400005b0481565b670de0b6b3a764000081565b600068056bc75e2d6310000083111561025057600080fd5b670de0b6b3a764000083101561026557600080fd5b678ac7230489e8000082111561027a57600080fd5b620f424082101561028a57600080fd5b600061029685856103cb565b9050806102ed576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f4d4154485f415050524f580000000000000000000000000000000000604482015290519081900360640190fd5b8260006102fa8383610512565b90506000871161030957600080fd5b801561031457600080fd5b50506000805460ff19169055509392505050565b620f4240670de0b6b3a7640000610228565b64e8d4a51000670de0b6b3a7640000610228565b68056bc75e2d6310000081565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b600881565b600281565b600181565b600a670de0b6b3a7640000610228565b671bc16d674ec7ffff81565b600081565b6002670de0b6b3a7640000610228565b600081610422576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4449565f5a45524f0000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a7640000830283158061044a5750670de0b6b3a764000084828161044757fe5b04145b61049e576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b600283048101818110156104fc576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b600084828161050757fe5b049695505050505050565b600082820283158061052c57508284828161052957fe5b04145b610580576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6706f05b59d3b200008101818110156105e3576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6000670de0b6b3a76400008261050756fea265627a7a72315820f0f26278e3fc3369c41e852dd72450e07aafa81526408f333ccee8c0e34ee4c364736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/TMath.abi b/runtime/near-evm-runner/tests/build/TMath.abi new file mode 100644 index 00000000000..14a08506688 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/TMath.abi @@ -0,0 +1,834 @@ +[ + { + "constant": true, + "inputs": [], + "name": "BONE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "BPOW_PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "EXIT_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "INIT_POOL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_IN_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_OUT_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_TOTAL_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BALANCE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BOUND_TOKENS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_BPOW_BASE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_FEE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MIN_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcInGivenOut", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcOutGivenIn", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcPoolInGivenSingleOut", + "outputs": [ + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcPoolOutGivenSingleIn", + "outputs": [ + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolAmountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcSingleInGivenPoolOut", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountIn", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcSingleOutGivenPoolIn", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenAmountOut", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "tokenBalanceIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenBalanceOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "tokenWeightOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "swapFee", + "type": "uint256" + } + ], + "name": "calcSpotPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "spotPrice", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getColor", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + } + ], + "name": "calc_btoi", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + } + ], + "name": "calc_bfloor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "name": "calc_badd", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "name": "calc_bsub", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "name": "calc_bsubSign", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "name": "calc_bmul", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "name": "calc_bdiv", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "n", + "type": "uint256" + } + ], + "name": "calc_bpowi", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "base", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exp", + "type": "uint256" + } + ], + "name": "calc_bpow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "base", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "precision", + "type": "uint256" + } + ], + "name": "calc_bpowApprox", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/TMath.bin b/runtime/near-evm-runner/tests/build/TMath.bin new file mode 100644 index 00000000000..4a14f446467 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/TMath.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506110df806100206000396000f3fe608060405234801561001057600080fd5b50600436106101e3576000357c010000000000000000000000000000000000000000000000000000000090048063b0e0d13611610117578063c36596a6116100ba578063c36596a614610250578063c6580d12146104a9578063c6b3199d146104b1578063cd094b14146104ce578063e4a28a52146101e8578063ec093021146104f1578063f5f5b148146104f9578063f760324b1461051c578063f8d6aed41461053f576101e3565b8063b0e0d136146103ed578063b58d3e70146103f5578063b65fcf4014610412578063b7b800a41461044e578063ba019dab14610456578063ba9530a61461045e578063bc063e1a14610499578063bc694ea2146104a1576101e3565b806382f652ad1161018a57806382f652ad146102c45780638656b653146102ff578063867378c51461033a578063872289ab1461034257806389298012146103655780639381cd2b146103a0578063992e2a92146103a85780639a86139b146103b0578063a221ee49146103b8576101e3565b806309a3bbe4146101e8578063189d00ca146102025780631bcaf56f1461020a5780631fdee4071461022d578063218b53821461025057806331124372146102585780635c1bbaf71461028157806376c7a3c7146102bc575b600080fd5b6101f061057a565b60408051918252519081900360200190f35b6101f0610587565b6101f06004803603604081101561022057600080fd5b508035906020013561059b565b6101f06004803603604081101561024357600080fd5b50803590602001356105b0565b6101f06105bc565b6101f06004803603606081101561026e57600080fd5b50803590602081013590604001356105c8565b6101f0600480360360c081101561029757600080fd5b5080359060208101359060408101359060608101359060808101359060a001356105dd565b6101f0610695565b6101f0600480360360c08110156102da57600080fd5b5080359060208101359060408101359060608101359060808101359060a001356106a7565b6101f0600480360360c081101561031557600080fd5b5080359060208101359060408101359060608101359060808101359060a00135610766565b6101f0610807565b6101f06004803603604081101561035857600080fd5b508035906020013561081b565b6101f0600480360360c081101561037b57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135610827565b6101f06108d7565b6101f06108e4565b6101f06108f0565b6101f0600480360360a08110156103ce57600080fd5b5080359060208101359060408101359060608101359060800135610914565b6101f0610979565b6101f06004803603602081101561040b57600080fd5b503561097e565b6104356004803603604081101561042857600080fd5b5080359060200135610989565b6040805192835290151560208301528051918290030190f35b6101f06109a2565b6101f06109a7565b6101f0600480360360c081101561047457600080fd5b5080359060208101359060408101359060608101359060808101359060a001356109ac565b6101f0610a2d565b6101f0610a3d565b6101f0610a49565b6101f0600480360360208110156104c757600080fd5b5035610a4e565b6101f0600480360360408110156104e457600080fd5b5080359060200135610a59565b6101f0610a65565b6101f06004803603604081101561050f57600080fd5b5080359060200135610a75565b6101f06004803603604081101561053257600080fd5b5080359060200135610a81565b6101f0600480360360c081101561055557600080fd5b5080359060208101359060408101359060608101359060808101359060a00135610a8d565b6802b5e3af16b188000081565b6402540be400670de0b6b3a76400005b0481565b60006105a78383610b10565b90505b92915050565b60006105a78383610b81565b670de0b6b3a764000081565b60006105d5848484610cc8565b949350505050565b6000806105ea8786610b81565b905060006105f88786610da6565b905060006106068289610b81565b9050600061061c670de0b6b3a764000085610b81565b9050600061062a8383610e03565b90506000610638828e610f26565b90506000610646828f610b10565b9050600061066561065f670de0b6b3a76400008a610b10565b8b610f26565b90506106828261067d670de0b6b3a764000084610b10565b610b81565b9f9e505050505050505050505050505050565b620f4240670de0b6b3a7640000610597565b6000806106b48786610b81565b905060006106ca670de0b6b3a764000083610b10565b905060006106d88286610f26565b905060006106f28761067d670de0b6b3a764000085610b10565b905060006107008c83610b10565b9050600061070e828e610b81565b9050600061071c8288610e03565b9050600061072a828e610f26565b905060006107388e83610b10565b90506107518161067d670de0b6b3a76400006000610b10565b99505050505050505050509695505050505050565b6000806107738786610b81565b9050600061079261078c670de0b6b3a764000084610b10565b85610f26565b905060006107b1866107ac670de0b6b3a764000085610b10565b610f26565b905060006107bf8b83610da6565b905060006107cd828d610b81565b905060006107db8287610e03565b905060006107e9828d610f26565b90506107f5818d610b10565b9e9d5050505050505050505050505050565b64e8d4a51000670de0b6b3a7640000610597565b60006105a78383610da6565b6000806108348786610b81565b9050600061084f856107ac670de0b6b3a76400006000610b10565b9050600061085d8883610b10565b9050600061086b828a610b81565b9050600061088a82610885670de0b6b3a764000088610b81565b610e03565b90506000610898828e610f26565b905060006108a68e83610b10565b905060006108bf61065f670de0b6b3a76400008a610b10565b9050610682826107ac670de0b6b3a764000084610b10565b68056bc75e2d6310000081565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b6000806109218787610b81565b9050600061092f8686610b81565b9050600061093d8383610b81565b9050600061095f670de0b6b3a764000061067d670de0b6b3a764000089610b10565b905061096b8282610f26565b9a9950505050505050505050565b600881565b60006105aa82611008565b6000806109968484611023565b915091505b9250929050565b600281565b600181565b6000806109b98786610b81565b905060006109cf670de0b6b3a764000085610b10565b90506109db8582610f26565b905060006109ed8a61067d8c85610da6565b905060006109fb8285610e03565b90506000610a11670de0b6b3a764000083610b10565b9050610a1d8a82610f26565b9c9b505050505050505050505050565b600a670de0b6b3a7640000610597565b671bc16d674ec7ffff81565b600081565b60006105aa82611045565b60006105a78383610f26565b6002670de0b6b3a7640000610597565b60006105a78383610e03565b60006105a78383611053565b600080610a9a8588610b81565b90506000610aa88786610b10565b90506000610ab68883610b81565b90506000610ac48285610e03565b9050610ad881670de0b6b3a7640000610b10565b9050610aec670de0b6b3a764000087610b10565b9450610b01610afb8c83610f26565b86610b81565b9b9a5050505050505050505050565b6000806000610b1f8585611023565b915091508015610b79576040805160e560020a62461bcd02815260206004820152601160248201527f4552525f5355425f554e444552464c4f57000000000000000000000000000000604482015290519081900360640190fd5b509392505050565b600081610bd8576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4449565f5a45524f0000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a76400008302831580610c005750670de0b6b3a7640000848281610bfd57fe5b04145b610c54576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b60028304810181811015610cb2576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4449565f494e5445524e414c00000000000000000000000000000000604482015290519081900360640190fd5b6000848281610cbd57fe5b049695505050505050565b6000828180610cdf87670de0b6b3a7640000611023565b9092509050670de0b6b3a764000080600060015b888410610d97576000670de0b6b3a764000082029050600080610d278a610d2285670de0b6b3a7640000610b10565b611023565b91509150610d39876107ac848c610f26565b9650610d458784610b81565b965086610d5457505050610d97565b8715610d5e579315935b8015610d68579315935b8415610d7f57610d788688610b10565b9550610d8c565b610d898688610da6565b95505b505050600101610cf3565b50909998505050505050505050565b6000828201838110156105a7576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4144445f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b60006001831015610e5e576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f42504f575f424153455f544f4f5f4c4f570000000000000000000000604482015290519081900360640190fd5b671bc16d674ec7ffff831115610ebe576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f42504f575f424153455f544f4f5f4849474800000000000000000000604482015290519081900360640190fd5b6000610ec983611008565b90506000610ed78483610b10565b90506000610eed86610ee885611045565b611053565b905081610efe5792506105aa915050565b6000610f0f87846305f5e100610cc8565b9050610f1b8282610f26565b979650505050505050565b6000828202831580610f40575082848281610f3d57fe5b04145b610f94576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6706f05b59d3b20000810181811015610ff7576040805160e560020a62461bcd02815260206004820152601060248201527f4552525f4d554c5f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b6000670de0b6b3a764000082610cbd565b6000670de0b6b3a764000061101c83611045565b0292915050565b600080828410611039575050808203600061099b565b5050818103600161099b565b670de0b6b3a7640000900490565b6000806002830661106c57670de0b6b3a764000061106e565b835b90506002830492505b82156105a7576110878485610f26565b9350600283061561109f5761109c8185610f26565b90505b60028304925061107756fea265627a7a72315820ba5c88696fa9a89794667fd441404d301fffcf81987230fc5eda2a8253a37e0a64736f6c634300050c0032 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/build/TToken.abi b/runtime/near-evm-runner/tests/build/TToken.abi new file mode 100644 index 00000000000..12a64cc0432 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/TToken.abi @@ -0,0 +1,311 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "whom", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amt", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/runtime/near-evm-runner/tests/build/zombieAttack.abi b/runtime/near-evm-runner/tests/build/zombieAttack.abi new file mode 100644 index 00000000000..a0ced0c7c78 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/zombieAttack.abi @@ -0,0 +1 @@ +[{"constant":false,"inputs":[{"name":"_zombieId","type":"uint256"}],"name":"levelUp","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_zombieId","type":"uint256"},{"name":"_kittyId","type":"uint256"}],"name":"feedOnKitty","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"zombies","outputs":[{"name":"name","type":"string"},{"name":"dna","type":"uint256"},{"name":"level","type":"uint32"},{"name":"readyTime","type":"uint32"},{"name":"winCount","type":"uint16"},{"name":"lossCount","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"getZombiesByOwner","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"zombieToOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setKittyContractAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_zombieId","type":"uint256"},{"name":"_newDna","type":"uint256"}],"name":"changeDna","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"createRandomZombie","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_zombieId","type":"uint256"},{"name":"_newName","type":"string"}],"name":"changeName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_fee","type":"uint256"}],"name":"setLevelUpFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_zombieId","type":"uint256"},{"name":"_targetId","type":"uint256"}],"name":"attack","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"zombieId","type":"uint256"},{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"dna","type":"uint256"}],"name":"NewZombie","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}] diff --git a/runtime/near-evm-runner/tests/build/zombieAttack.bin b/runtime/near-evm-runner/tests/build/zombieAttack.bin new file mode 100644 index 00000000000..3e21cb25c22 --- /dev/null +++ b/runtime/near-evm-runner/tests/build/zombieAttack.bin @@ -0,0 +1 @@ +60606040526010600155600154600a0a6002556201518060035566038d7ea4c6800060085560006009556046600a55336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506119d28061007d6000396000f3006060604052600436106100d0576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630ce90ec2146100d557806317a7f4cc146100ed5780632052465e146101195780633ccfd60b1461021d5780634412e10414610232578063528b7b8f146102c05780635f4623f1146103235780635faf28801461035c5780637bff0a01146103885780638da5cb5b146103e5578063c39cbef11461043a578063ccf670f814610471578063e1fa763814610494578063f2fde38b146104c0575b600080fd5b6100eb60048080359060200190919050506104f9565b005b34156100f857600080fd5b6101176004808035906020019091908035906020019091905050610565565b005b341561012457600080fd5b61013a60048080359060200190919050506106d2565b60405180806020018781526020018663ffffffff1663ffffffff1681526020018563ffffffff1663ffffffff1681526020018461ffff1661ffff1681526020018361ffff1661ffff1681526020018281038252888181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156102095780601f106101de57610100808354040283529160200191610209565b820191906000526020600020905b8154815290600101906020018083116101ec57829003601f168201915b505097505050505050505060405180910390f35b341561022857600080fd5b610230610758565b005b341561023d57600080fd5b610269600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061082d565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ac578082015181840152602081019050610291565b505050509050019250505060405180910390f35b34156102cb57600080fd5b6102e1600480803590602001909190505061095b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032e57600080fd5b61035a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061098e565b005b341561036757600080fd5b6103866004808035906020019091908035906020019091905050610a2d565b005b341561039357600080fd5b6103e3600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610b0f565b005b34156103f057600080fd5b6103f8610b88565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561044557600080fd5b61046f60048080359060200190919080359060200190820180359060200191909192905050610bad565b005b341561047c57600080fd5b6104926004808035906020019091905050610c9b565b005b341561049f57600080fd5b6104be6004808035906020019091908035906020019091905050610d00565b005b34156104cb57600080fd5b6104f7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610f93565b005b6008543414151561050957600080fd5b60048181548110151561051857fe5b9060005260206000209060030201600201600081819054906101000a900463ffffffff168092919060010191906101000a81548163ffffffff021916908363ffffffff1602179055505050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e98b7f4d83600060405161014001526040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082815260200191505061014060405180830381600087803b151561060257600080fd5b6102c65a03f1151561061357600080fd5b50505060405180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519050909192939495969798509091929394959697509091929394959650909192939495509091929394509091929350909192509091509050809150506106cd83826040805190810160405280600581526020017f6b697474790000000000000000000000000000000000000000000000000000008152506110e8565b505050565b6004818154811015156106e157fe5b906000526020600020906003020160009150905080600001908060010154908060020160009054906101000a900463ffffffff16908060020160049054906101000a900463ffffffff16908060020160089054906101000a900461ffff169080600201600a9054906101000a900461ffff16905086565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156107b357600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561082b57600080fd5b565b610835611764565b61083d611764565b600080600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460405180591061088d5750595b9080825280602002602001820160405250925060009150600090505b600480549050811015610950578473ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156109435780838381518110151561092c57fe5b906020019060200201818152505081806001019250505b80806001019150506108a9565b829350505050919050565b60056020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109e957600080fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60148281600482815481101515610a4057fe5b906000526020600020906003020160020160009054906101000a900463ffffffff1663ffffffff1610151515610a7557600080fd5b836005600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ae357600080fd5b83600486815481101515610af357fe5b9060005260206000209060030201600101819055505050505050565b600080600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141515610b5e57600080fd5b610b67826112bd565b9050606481811515610b7557fe5b0681039050610b84828261133f565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60028381600482815481101515610bc057fe5b906000526020600020906003020160020160009054906101000a900463ffffffff1663ffffffff1610151515610bf557600080fd5b846005600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610c6357600080fd5b8484600488815481101515610c7457fe5b90600052602060002090600302016000019190610c92929190611778565b50505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610cf657600080fd5b8060088190555050565b6000806000846005600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b600486815481101515610d8257fe5b90600052602060002090600302019350600485815481101515610da157fe5b90600052602060002090600302019250610dbb606461160e565b9150600a5482111515610ef157610df260018560020160089054906101000a900461ffff1661ffff166116a590919063ffffffff16565b8460020160086101000a81548161ffff021916908361ffff160217905550610e3e60018560020160009054906101000a900463ffffffff1663ffffffff166116cb90919063ffffffff16565b8460020160006101000a81548163ffffffff021916908363ffffffff160217905550610e8a600184600201600a9054906101000a900461ffff1661ffff166116a590919063ffffffff16565b83600201600a6101000a81548161ffff021916908361ffff160217905550610eec8684600101546040805190810160405280600681526020017f7a6f6d62696500000000000000000000000000000000000000000000000000008152506110e8565b610f8b565b610f1b600185600201600a9054906101000a900461ffff1661ffff166116a590919063ffffffff16565b84600201600a6101000a81548161ffff021916908361ffff160217905550610f6360018460020160089054906101000a900461ffff1661ffff166116a590919063ffffffff16565b8360020160086101000a81548161ffff021916908361ffff160217905550610f8a846116f5565b5b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610fee57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561102a57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080846005600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561115957600080fd5b60048681548110151561116857fe5b906000526020600020906003020192506111818361171f565b151561118c57600080fd5b6002548581151561119957fe5b0694506002858460010154018115156111ae57fe5b04915060405180807f6b697474790000000000000000000000000000000000000000000000000000008152506005019050604051809103902060001916846040518082805190602001908083835b60208310151561122157805182526020820191506020810190506020830392506111fc565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916141561126d57606360648381151561126657fe5b0683030191505b6112ac6040805190810160405280600681526020017f4e6f4e616d6500000000000000000000000000000000000000000000000000008152508361133f565b6112b5836116f5565b505050505050565b600080826040518082805190602001908083835b6020831015156112f657805182526020820191506020810190506020830392506112d1565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206001900490506002548181151561133657fe5b06915050919050565b600060016004805480600101828161135791906117f8565b9160005260206000209060030201600060c060405190810160405280888152602001878152602001600163ffffffff168152602001600354420163ffffffff168152602001600061ffff168152602001600061ffff16815250909190915060008201518160000190805190602001906113d192919061182a565b506020820151816001015560408201518160020160006101000a81548163ffffffff021916908363ffffffff16021790555060608201518160020160046101000a81548163ffffffff021916908363ffffffff16021790555060808201518160020160086101000a81548161ffff021916908361ffff16021790555060a082015181600201600a6101000a81548161ffff021916908361ffff1602179055505050039050336005600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061151a6001600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461174690919063ffffffff16565b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f88f026aacbbecc90c18411df4b1185fd8d9be2470f1962f192bf84a27d0704b78184846040518084815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156115cd5780820151818401526020810190506115b2565b50505050905090810190601f1680156115fa5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a1505050565b6000611626600160095461174690919063ffffffff16565b600981905550814233600954604051808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c01000000000000000000000000028152601401828152602001935050505060405180910390206001900481151561169d57fe5b069050919050565b60008082840190508361ffff168161ffff16101515156116c157fe5b8091505092915050565b60008082840190508363ffffffff168163ffffffff16101515156116eb57fe5b8091505092915050565b60035442018160020160046101000a81548163ffffffff021916908363ffffffff16021790555050565b6000428260020160049054906101000a900463ffffffff1663ffffffff1611159050919050565b600080828401905083811015151561175a57fe5b8091505092915050565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106117b957803560ff19168380011785556117e7565b828001600101855582156117e7579182015b828111156117e65782358255916020019190600101906117cb565b5b5090506117f491906118aa565b5090565b8154818355818115116118255760030281600302836000526020600020918201910161182491906118cf565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061186b57805160ff1916838001178555611899565b82800160010185558215611899579182015b8281111561189857825182559160200191906001019061187d565b5b5090506118a691906118aa565b5090565b6118cc91905b808211156118c85760008160009055506001016118b0565b5090565b90565b61195b91905b8082111561195757600080820160006118ee919061195e565b60018201600090556002820160006101000a81549063ffffffff02191690556002820160046101000a81549063ffffffff02191690556002820160086101000a81549061ffff021916905560028201600a6101000a81549061ffff0219169055506003016118d5565b5090565b90565b50805460018160011615610100020316600290046000825580601f1061198457506119a3565b601f0160209004906000526020600020908101906119a291906118aa565b5b505600a165627a7a72305820132b51da42f560f7184ac5aae47f26c9658881610ed4c49b0c5c00f7456864e60029 \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/contracts/ConstructorRevert.sol b/runtime/near-evm-runner/tests/contracts/ConstructorRevert.sol new file mode 100644 index 00000000000..4b67a7311ce --- /dev/null +++ b/runtime/near-evm-runner/tests/contracts/ConstructorRevert.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.5.8; + +contract ConstructorRevert { + constructor() public { + require(2 + 2 == 5, "Error Deploying Contract"); + } +} diff --git a/runtime/near-evm-runner/tests/contracts/Create2.sol b/runtime/near-evm-runner/tests/contracts/Create2.sol new file mode 100644 index 00000000000..d217352750b --- /dev/null +++ b/runtime/near-evm-runner/tests/contracts/Create2.sol @@ -0,0 +1,66 @@ +pragma solidity ^0.5.8; + +contract Create2Factory { + function deploy(bytes32 _salt, bytes memory _contractBytecode) public returns (address payable addr) { + assembly { + addr := create2(0, add(_contractBytecode, 0x20), mload(_contractBytecode), _salt) + } + } + + function testDoubleDeploy(bytes32 _salt, bytes memory _contractBytecode) public payable returns (bool) { + // deploy + address payable addr = deploy(_salt, _contractBytecode); + SelfDestruct other = SelfDestruct(addr); + + // use once + other.storeUint(5); + require(other.storedUint() == 5, "pre-destruction wrong uint"); + + // destroy and check if still exists + other.destruction(); + bytes memory code = getCode(address(other)); + require(code.length == 0, "post-destruction code length"); + + // redeploy and use again + deploy(_salt, _contractBytecode); + require(other.storedUint() == 0, "post-destruction wrong uint"); + other.storeUint(3); + require(other.storedUint() == 3, "post-destruction stored wrong uint"); + return true; + } + + function getCode(address other) internal view returns (bytes memory code) { + assembly { + code := mload(0x40) + let size := extcodesize(other) + mstore(code, size) + let body := add(code, 0x20) + extcodecopy(other, body, 0, size) + mstore(code, size) + mstore(0x40, add(body, size)) + } + } + + + function () external payable {} + +} + +contract SelfDestruct { + address public storedAddress; + uint public storedUint; + + function () external payable {} + + function storeAddress() public { + storedAddress = msg.sender; + } + + function storeUint(uint _number) public { + storedUint = _number; + } + + function destruction() public { + selfdestruct(msg.sender); + } +} diff --git a/runtime/near-evm-runner/tests/contracts/SolTests.sol b/runtime/near-evm-runner/tests/contracts/SolTests.sol new file mode 100644 index 00000000000..cda1f28a318 --- /dev/null +++ b/runtime/near-evm-runner/tests/contracts/SolTests.sol @@ -0,0 +1,160 @@ +pragma solidity ^0.5.8; + +contract ExposesBalance { + function balance() public view returns (uint256) { + return address(this).balance; + } + + // Unpermissioned. Don't deploy for real :D + function transferTo(address _recipient, uint256 _amount) public returns (uint256) { + address(uint160(_recipient)).transfer(_amount); + return balance(); + } +} + +contract SolTests is ExposesBalance { + constructor() public payable {} + + event SomeEvent(uint256 _number); + + event DeployEvent( + address indexed _contract, + uint256 _amount + ); + + function () external payable {} + + function deployNewGuy(uint256 _aNumber) public payable returns (address, uint256) { + SubContract _newGuy = new SubContract(_aNumber); + address(_newGuy).transfer(msg.value); + emit DeployEvent(address(_newGuy), msg.value); + return (address(_newGuy), msg.value); + } + + function payNewGuy(uint256 _aNumber) public payable returns (address, uint256) { + SubContract _newGuy = (new SubContract).value(msg.value)(_aNumber); + return (address(_newGuy), msg.value); + } + + function returnSomeFunds() public payable returns (address, uint256) { + address(msg.sender).transfer(msg.value / 2); + return (msg.sender, msg.value); + } + + function emitIt(uint256 _aNumber) public returns (bool) { + emit SomeEvent(_aNumber); + return true; + } + + function precompileTest() public pure { + require(sha256("") == hex"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "sha2 digest mismatch"); + require(ripemd160("") == hex"9c1185a5c5e9fc54612808977ee8f548b2258d31", "rmd160 digest mismatch"); + + // signed with hex"2222222222222222222222222222222222222222222222222222222222222222" + address addr = ecrecover( + hex"1111111111111111111111111111111111111111111111111111111111111111", + 27, + hex"b9f0bb08640d3c1c00761cdd0121209268f6fd3816bc98b9e6f3cc77bf82b698", // r + hex"12ac7a61788a0fdc0e19180f14c945a8e1088a27d92a74dce81c0981fb644744" // s + ); + + require( + addr == 0x1563915e194D8CfBA1943570603F7606A3115508, + "ecrecover mismatch" + ); + } +} + +contract SubContract is ExposesBalance { + uint256 public aNumber = 6; + + constructor(uint256 _aNumber) public payable { + aNumber = _aNumber; + } + + function aFunction() public pure returns (bool) { + return true; + } + + function () external payable {} +} + +contract PrecompiledFunction { + constructor() public payable {} + + function noop() public pure { + + } + + function testSha256() public pure returns (bytes32) { + return sha256(""); + } + + function testSha256_100bytes() public pure returns (bytes32) { + return sha256("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw"); + } + + function testEcrecover() public pure returns (address) { + return ecrecover( + hex"1111111111111111111111111111111111111111111111111111111111111111", + 27, + hex"b9f0bb08640d3c1c00761cdd0121209268f6fd3816bc98b9e6f3cc77bf82b698", // r + hex"12ac7a61788a0fdc0e19180f14c945a8e1088a27d92a74dce81c0981fb644744" // s + ); + } + + function testRipemd160() public pure returns (bytes20) { + return ripemd160(""); + } + + function testRipemd160_1kb() public pure returns (bytes20) { + return ripemd160("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij"); + } + + function identity(bytes memory data) public returns (bytes memory) { + bytes memory ret = new bytes(data.length); + assembly { + let len := mload(data) + if iszero(call(gas, 0x04, 0, add(data, 0x20), len, add(ret,0x20), len)) { + invalid() + } + } + + return ret; + } + + function test_identity() public returns (bytes memory) { + return identity(""); + } + + function test_identity_100bytes() public returns (bytes memory) { + return identity("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw"); + } + + function modexp(uint base, uint e, uint m) public view returns (uint o) { + assembly { + // define pointer + let p := mload(0x40) + // store data assembly-favouring ways + mstore(p, 0x20) // Length of Base + mstore(add(p, 0x20), 0x20) // Length of Exponent + mstore(add(p, 0x40), 0x20) // Length of Modulus + mstore(add(p, 0x60), base) // Base + mstore(add(p, 0x80), e) // Exponent + mstore(add(p, 0xa0), m) // Modulus + if iszero(staticcall(sub(gas, 2000), 0x05, p, 0xc0, p, 0x20)) { + revert(0, 0) + } + // data + o := mload(p) + } + } + + function testModExp() public view returns (uint) { + return modexp(12345, 173, 101); + } + + function testBn128Add() public pure returns (uint) { + + } +} \ No newline at end of file diff --git a/runtime/near-evm-runner/tests/contracts/StandardPrecompiles.sol b/runtime/near-evm-runner/tests/contracts/StandardPrecompiles.sol new file mode 100644 index 00000000000..dbfac7b4395 --- /dev/null +++ b/runtime/near-evm-runner/tests/contracts/StandardPrecompiles.sol @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity ^0.7.0; + +//import "hardhat/console.sol"; + +contract StandardPrecompiles { + constructor() payable { + //console.log("Deploying StandardPrecompiles"); + } + + function test_all() public view returns(bool) { + require(test_ecrecover(), "erroneous ecrecover precompile"); + require(test_sha256(), "erroneous sha256 precompile"); + require(test_ripemd160(), "erroneous ripemd160 precompile"); + require(test_identity(), "erroneous identity precompile"); + require(test_modexp(), "erroneous modexp precompile"); + require(test_ecadd(), "erroneous ecadd precompile"); + require(test_ecmul(), "erroneous ecmul precompile"); + require(test_ecpair(), "erroneous ecpair precompile"); + require(test_blake2f(), "erroneous blake2f precompile"); + return true; + } + + // See: https://docs.soliditylang.org/en/develop/units-and-global-variables.html#mathematical-and-cryptographic-functions + // See: https://etherscan.io/address/0x0000000000000000000000000000000000000001 + function test_ecrecover() public pure returns(bool) { + bytes32 hash = hex"1111111111111111111111111111111111111111111111111111111111111111"; + bytes memory sig = hex"b9f0bb08640d3c1c00761cdd0121209268f6fd3816bc98b9e6f3cc77bf82b69812ac7a61788a0fdc0e19180f14c945a8e1088a27d92a74dce81c0981fb6447441b"; + address signer = 0x1563915e194D8CfBA1943570603F7606A3115508; + return ecverify(hash, sig, signer); + } + + // See: https://docs.soliditylang.org/en/develop/units-and-global-variables.html#mathematical-and-cryptographic-functions + // See: https://etherscan.io/address/0x0000000000000000000000000000000000000002 + function test_sha256() public pure returns(bool) { + return sha256("") == hex"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; + } + + // See: https://docs.soliditylang.org/en/develop/units-and-global-variables.html#mathematical-and-cryptographic-functions + // See: https://etherscan.io/address/0x0000000000000000000000000000000000000003 + function test_ripemd160() public pure returns(bool) { + return ripemd160("") == hex"9c1185a5c5e9fc54612808977ee8f548b2258d31"; + } + + // See: https://etherscan.io/address/0x0000000000000000000000000000000000000004 + function test_identity() public view returns(bool) { + bytes memory data = hex"1111111111111111111111111111111111111111111111111111111111111111"; + return keccak256(datacopy(data)) == keccak256(data); + } + + // See: https://eips.ethereum.org/EIPS/eip-198 + // See: https://etherscan.io/address/0x0000000000000000000000000000000000000005 + function test_modexp() public view returns(bool) { + uint256 base = 3; + uint256 exponent = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e; + uint256 modulus = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f; + return modexp(base, exponent, modulus) == 1; + } + + // See: https://eips.ethereum.org/EIPS/eip-196 + // See: https://etherscan.io/address/0x0000000000000000000000000000000000000006 + function test_ecadd() public view returns(bool) { + // alt_bn128_add_chfast1: + bytes32[2] memory result; + result = ecadd( + 0x18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9, + 0x063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f37266, + 0x07c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed, + 0x06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7 + ); + return result[0] == 0x2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703 && result[1] == 0x301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c915; + } + + // See: https://eips.ethereum.org/EIPS/eip-196 + // See: https://etherscan.io/address/0x0000000000000000000000000000000000000007 + function test_ecmul() public view returns(bool) { + // alt_bn128_mul_chfast1: + bytes32[2] memory result; + result = ecmul( + 0x2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb7, + 0x21611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204, + 0x00000000000000000000000000000000000000000000000011138ce750fa15c2 + ); + return result[0] == 0x070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c && result[1] == 0x031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc; + } + + // See: https://eips.ethereum.org/EIPS/eip-197 + // See: https://etherscan.io/address/0x0000000000000000000000000000000000000008 + function test_ecpair() public view returns(bool) { + // alt_bn128_pairing_jeff1: + bytes32 result = ecpair(hex"1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa"); + return result == 0x0000000000000000000000000000000000000000000000000000000000000001; + } + + // See: https://eips.ethereum.org/EIPS/eip-152 + // See: https://etherscan.io/address/0x0000000000000000000000000000000000000009 + function test_blake2f() public view returns(bool) { + uint32 rounds = 12; + bytes32[2] memory h; + h[0] = hex"48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5"; + h[1] = hex"d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b"; + bytes32[4] memory m; + m[0] = hex"6162630000000000000000000000000000000000000000000000000000000000"; + m[1] = hex"0000000000000000000000000000000000000000000000000000000000000000"; + m[2] = hex"0000000000000000000000000000000000000000000000000000000000000000"; + m[3] = hex"0000000000000000000000000000000000000000000000000000000000000000"; + bytes8[2] memory t; + t[0] = hex"03000000"; + t[1] = hex"00000000"; + bool f = true; + bytes32[2] memory result = blake2f(rounds, h, m, t, f); + return result[0] == hex"ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1" && result[1] == hex"7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"; + } + + function ecverify(bytes32 hash, bytes memory sig, address signer) private pure returns (bool) { + bool ok; + address addr; + (ok, addr) = ecrecovery(hash, sig); + return ok && addr == signer; + } + + function ecrecovery(bytes32 hash, bytes memory sig) private pure returns (bool, address) { + if (sig.length != 65) + return (false, address(0)); + + bytes32 r; + bytes32 s; + uint8 v; + assembly { + r := mload(add(sig, 32)) + s := mload(add(sig, 64)) + v := byte(0, mload(add(sig, 96))) + } + + address addr = ecrecover(hash, v, r, s); + return (true, addr); + } + + function datacopy(bytes memory input) private view returns (bytes memory) { + bytes memory output = new bytes(input.length); + assembly { + let len := mload(input) + let ok := staticcall(gas(), 0x04, add(input, 32), len, add(output, 32), len) + switch ok + case 0 { + revert(0, 0) + } + } + return output; + } + + function modexp(uint256 base, uint256 exponent, uint256 modulus) private view returns (uint256 output) { + assembly { + let ptr := mload(0x40) + mstore(ptr, 32) + mstore(add(ptr, 0x20), 32) + mstore(add(ptr, 0x40), 32) + mstore(add(ptr, 0x60), base) + mstore(add(ptr, 0x80), exponent) + mstore(add(ptr, 0xA0), modulus) + let ok := staticcall(gas(), 0x05, ptr, 0xC0, ptr, 0x20) + switch ok + case 0 { + revert(0, 0) + } + default { + output := mload(ptr) + } + } + } + + function ecadd(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) private view returns (bytes32[2] memory output) { + bytes32[4] memory input = [ax, ay, bx, by]; + assembly { + let ok := staticcall(gas(), 0x06, input, 0x80, output, 0x40) + switch ok + case 0 { + revert(0, 0) + } + } + } + + function ecmul(bytes32 x, bytes32 y, bytes32 scalar) private view returns (bytes32[2] memory output) { + bytes32[3] memory input = [x, y, scalar]; + assembly { + let ok := staticcall(gas(), 0x07, input, 0x60, output, 0x40) + switch ok + case 0 { + revert(0, 0) + } + } + } + + function ecpair(bytes memory input) private view returns (bytes32 output) { + uint256 len = input.length; + require(len % 192 == 0); + assembly { + let ptr := mload(0x40) + let ok := staticcall(gas(), 0x08, add(input, 32), len, ptr, 0x20) + switch ok + case 0 { + revert(0, 0) + } + default { + output := mload(ptr) + } + } + } + + function blake2f(uint32 rounds, bytes32[2] memory h, bytes32[4] memory m, bytes8[2] memory t, bool f) private view returns (bytes32[2] memory) { + bytes32[2] memory output; + bytes memory args = abi.encodePacked(rounds, h[0], h[1], m[0], m[1], m[2], m[3], t[0], t[1], f); + assembly { + let ok := staticcall(gas(), 0x09, add(args, 32), 0xD5, output, 0x40) + switch ok + case 0 { + revert(0, 0) + } + } + return output; + } +} diff --git a/runtime/near-evm-runner/tests/failures.rs b/runtime/near-evm-runner/tests/failures.rs new file mode 100644 index 00000000000..eedcaa79357 --- /dev/null +++ b/runtime/near-evm-runner/tests/failures.rs @@ -0,0 +1,33 @@ +mod utils; + +use crate::utils::{accounts, create_context, setup}; + +/// Test various invalid inputs to function calls. +#[test] +fn test_invalid_input() { + let (mut fake_external, vm_config, fees_config) = setup(); + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 10); + assert!(context.get_nonce(vec![]).is_err()); + assert!(context.get_balance(vec![]).is_err()); + assert!(context.get_code(vec![]).is_err()); + assert!(context.get_storage_at(vec![]).is_err()); + assert!(context.view_call_function(vec![]).is_err()); + assert!(context.view_call_function(vec![0u8; 20]).is_err()); + assert!(context.call_function(vec![]).is_err()); + assert!(context.call_function(vec![0u8; 20]).is_err()); + assert!(context.deposit(vec![]).is_err()); + assert!(context.withdraw(vec![]).is_err()); + assert!(context.transfer(vec![]).is_err()); +} + +#[test] +fn test_invalid_view_args() { + let args = vec![vec![1u8; 20], vec![2u8; 20], vec![0u8; 32], vec![1u8, 0u8, 0u8, 0u8], vec![1]] + .concat(); + let (mut fake_external, vm_config, fees_config) = setup(); + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + assert_eq!( + context.view_call_function(args).unwrap_err().to_string(), + "EvmError(ContractNotFound)" + ); +} diff --git a/runtime/near-evm-runner/tests/standard_ops.rs b/runtime/near-evm-runner/tests/standard_ops.rs new file mode 100644 index 00000000000..28620069af1 --- /dev/null +++ b/runtime/near-evm-runner/tests/standard_ops.rs @@ -0,0 +1,309 @@ +#[macro_use] +extern crate lazy_static_include; + +use borsh::BorshSerialize; +use ethabi_contract::use_contract; +use ethereum_types::{Address, H256, U256}; + +use near_crypto::{InMemorySigner, KeyType}; +use near_evm_runner::types::{TransferArgs, WithdrawArgs}; +use near_evm_runner::utils::{ + address_from_arr, address_to_vec, encode_call_function_args, encode_view_call_function_args, + near_account_id_to_evm_address, near_erc721_domain, parse_meta_call, u256_to_arr, +}; +use near_runtime_fees::RuntimeFeesConfig; +use near_vm_errors::{EvmError, VMLogicError}; +use near_vm_logic::mocks::mock_external::MockedExternal; +use near_vm_logic::VMConfig; + +use crate::utils::{ + accounts, create_context, encode_meta_call_function_args, public_key_to_address, setup, + CHAIN_ID, +}; +mod utils; + +use parity_bytes::ToPretty; + +use_contract!(soltest, "tests/build/SolTests.abi"); +use_contract!(subcontract, "tests/build/SubContract.abi"); +use_contract!(create2factory, "tests/build/Create2Factory.abi"); +use_contract!(selfdestruct, "tests/build/SelfDestruct.abi"); + +lazy_static_include_str!(TEST, "tests/build/SolTests.bin"); +lazy_static_include_str!(FACTORY_TEST, "tests/build/Create2Factory.bin"); +lazy_static_include_str!(DESTRUCT_TEST, "tests/build/SelfDestruct.bin"); +lazy_static_include_str!(CONSTRUCTOR_TEST, "tests/build/ConstructorRevert.bin"); + +#[test] +fn test_funds_transfers() { + let (mut fake_external, vm_config, fees_config) = setup(); + let context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + assert_eq!( + context.get_balance(address_to_vec(&near_account_id_to_evm_address(&accounts(1)))).unwrap(), + U256::from(0) + ); + let mut context = + create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 100); + assert_eq!( + context.deposit(address_to_vec(&near_account_id_to_evm_address(&accounts(1)))).unwrap(), + U256::from(100) + ); + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + context + .transfer( + TransferArgs { + address: near_account_id_to_evm_address(&accounts(2)).0, + amount: u256_to_arr(&U256::from(50)), + } + .try_to_vec() + .unwrap(), + ) + .unwrap(); + assert_eq!( + context.get_balance(address_to_vec(&near_account_id_to_evm_address(&accounts(2)))).unwrap(), + U256::from(50) + ); + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(2), 0); + context + .withdraw( + WithdrawArgs { account_id: accounts(2), amount: u256_to_arr(&U256::from(50)) } + .try_to_vec() + .unwrap(), + ) + .unwrap(); + assert_eq!( + context.get_balance(address_to_vec(&near_account_id_to_evm_address(&accounts(2)))).unwrap(), + U256::from(0) + ); +} + +#[test] +fn test_deploy_with_nonce() { + let (mut fake_external, vm_config, fees_config) = setup(); + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + let address = near_account_id_to_evm_address(&accounts(1)); + assert_eq!(context.get_nonce(address.0.to_vec()).unwrap(), U256::from(0)); + let address1 = context.deploy_code(hex::decode(&TEST).unwrap()).unwrap(); + assert_eq!(context.get_nonce(address.0.to_vec()).unwrap(), U256::from(1)); + let address2 = context.deploy_code(hex::decode(&TEST).unwrap()).unwrap(); + assert_eq!(context.get_nonce(address.0.to_vec()).unwrap(), U256::from(2)); + assert_ne!(address1, address2); +} + +#[test] +#[ignore] +fn test_failed_deploy_returns_error() { + let (mut fake_external, vm_config, fees_config) = setup(); + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + if let Err(VMLogicError::EvmError(EvmError::DeployFail(_))) = + context.deploy_code(hex::decode(&CONSTRUCTOR_TEST).unwrap()) + { + } else { + panic!("Should fail"); + } +} + +#[test] +fn test_internal_create() { + let (mut fake_external, vm_config, fees_config) = setup(); + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + let test_addr = context.deploy_code(hex::decode(&TEST).unwrap()).unwrap(); + assert_eq!(context.get_nonce(test_addr.0.to_vec()).unwrap(), U256::from(0)); + + // This should increment the nonce of the deploying contract + let (input, _) = soltest::functions::deploy_new_guy::call(8); + let raw = context.call_function(encode_call_function_args(test_addr, input)).unwrap(); + assert_eq!(context.get_nonce(test_addr.0.to_vec()).unwrap(), U256::from(1)); + + let sub_addr = address_from_arr(&raw[12..32]); + let (new_input, _) = subcontract::functions::a_number::call(); + let new_raw = context.call_function(encode_call_function_args(sub_addr, new_input)).unwrap(); + let output = subcontract::functions::a_number::decode_output(&new_raw).unwrap(); + assert_eq!(output, U256::from(8)); +} + +#[test] +fn test_precompiles() { + let (mut fake_external, vm_config, fees_config) = setup(); + let mut context = + create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 100); + let test_addr = context.deploy_code(hex::decode(&TEST).unwrap()).unwrap(); + + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + let (input, _) = soltest::functions::precompile_test::call(); + let raw = context.call_function(encode_call_function_args(test_addr, input)).unwrap(); + assert_eq!(raw.len(), 0); +} + +fn setup_and_deploy_test() -> (MockedExternal, Address, VMConfig, RuntimeFeesConfig) { + let (mut fake_external, vm_config, fees_config) = setup(); + let mut context = + create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 100); + let test_addr = context.deploy_code(hex::decode(&TEST).unwrap()).unwrap(); + assert_eq!(context.get_balance(test_addr.0.to_vec()).unwrap(), U256::from(100)); + (fake_external, test_addr, vm_config, fees_config) +} + +#[test] +fn test_deploy_and_transfer() { + let (mut fake_external, test_addr, vm_config, fees_config) = setup_and_deploy_test(); + + // This should increment the nonce of the deploying contract. + // There is 100 attached to this that should be passed through. + let (input, _) = soltest::functions::deploy_new_guy::call(8); + let mut context = + create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 100); + let raw = context.call_function(encode_call_function_args(test_addr, input)).unwrap(); + assert!(context.logs.len() > 0); + + // The sub_addr should have been transferred 100 yoctoN. + let sub_addr = raw[12..32].to_vec(); + assert_eq!(context.get_balance(test_addr.0.to_vec()).unwrap(), U256::from(100)); + assert_eq!(context.get_balance(sub_addr).unwrap(), U256::from(100)); +} + +#[test] +fn test_deploy_with_value() { + let (mut fake_external, test_addr, vm_config, fees_config) = setup_and_deploy_test(); + + // This should increment the nonce of the deploying contract + // There is 100 attached to this that should be passed through + let (input, _) = soltest::functions::pay_new_guy::call(8); + let mut context = + create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 100); + let raw = context.call_function(encode_call_function_args(test_addr, input)).unwrap(); + + // The sub_addr should have been transferred 100 tokens. + let sub_addr = raw[12..32].to_vec(); + assert_eq!(context.get_balance(test_addr.0.to_vec()).unwrap(), U256::from(100)); + assert_eq!(context.get_balance(sub_addr).unwrap(), U256::from(100)); +} + +#[test] +fn test_contract_to_eoa_transfer() { + let (mut fake_external, test_addr, vm_config, fees_config) = setup_and_deploy_test(); + + let (input, _) = soltest::functions::return_some_funds::call(); + let mut context = + create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 100); + let raw = context.call_function(encode_call_function_args(test_addr, input)).unwrap(); + + let sender_addr = raw[12..32].to_vec(); + assert_eq!(context.get_balance(test_addr.0.to_vec()).unwrap(), U256::from(150)); + assert_eq!(context.get_balance(sender_addr).unwrap(), U256::from(50)); +} + +#[test] +fn test_get_code() { + let (mut fake_external, test_addr, vm_config, fees_config) = setup_and_deploy_test(); + let context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + + assert!(context.get_code(test_addr.0.to_vec()).unwrap().len() > 1500); // contract code should roughly be over length 1500 + assert_eq!(context.get_code(vec![0u8; 20]).unwrap().len(), 0); +} + +#[test] +fn test_view_call() { + let (mut fake_external, test_addr, vm_config, fees_config) = setup_and_deploy_test(); + + // This should NOT increment the nonce of the deploying contract + // And NO CODE should be deployed + let (input, _) = soltest::functions::deploy_new_guy::call(8); + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + let raw = context + .view_call_function(encode_view_call_function_args( + test_addr, + test_addr, + U256::from(0), + input, + )) + .unwrap(); + assert_eq!(context.get_nonce(test_addr.0.to_vec()).unwrap(), U256::from(0)); + + let sub_addr = raw[12..32].to_vec(); + assert_eq!(context.get_code(sub_addr).unwrap().len(), 0); + + let (input, _) = soltest::functions::return_some_funds::call(); + let raw = context + .view_call_function(encode_view_call_function_args( + test_addr, + test_addr, + U256::from(10u128.pow(27)), + input, + )) + .unwrap(); + assert_eq!(raw[12..32], test_addr.0); +} + +#[test] +fn test_solidity_accurate_storage_on_selfdestruct() { + let (mut fake_external, vm_config, fees_config) = setup(); + let mut context = + create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 100); + assert_eq!( + context.deposit(near_account_id_to_evm_address(&accounts(1)).0.to_vec()).unwrap(), + U256::from(100) + ); + + // Deploy CREATE2 Factory + let mut context = create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 0); + let factory_addr = context.deploy_code(hex::decode(&FACTORY_TEST).unwrap()).unwrap(); + + // Deploy + SelfDestruct in one transaction + let salt = H256([0u8; 32]); + let destruct_code = hex::decode(&DESTRUCT_TEST).unwrap(); + let input = create2factory::functions::test_double_deploy::call(salt, destruct_code.clone()).0; + let raw = context.call_function(encode_call_function_args(factory_addr, input)).unwrap(); + assert!(create2factory::functions::test_double_deploy::decode_output(&raw).unwrap()); +} + +#[test] +fn test_meta_call() { + let (mut fake_external, test_addr, vm_config, fees_config) = setup_and_deploy_test(); + let signer = InMemorySigner::from_random("doesnt".to_string(), KeyType::SECP256K1); + let mut context = + create_context(&mut fake_external, &vm_config, &fees_config, accounts(1), 100); + let meta_tx = encode_meta_call_function_args( + &signer, + CHAIN_ID, + U256::from(0), + U256::from(0), + Address::from_slice(&[0u8; 20]), + test_addr, + "returnSomeFunds()", + vec![], + ); + let _ = context.meta_call_function(meta_tx.clone()).unwrap(); + let signer_addr = public_key_to_address(signer.public_key); + assert_eq!(context.get_balance(test_addr.0.to_vec()).unwrap(), U256::from(150)); + assert_eq!(context.get_balance(signer_addr.0.to_vec()).unwrap(), U256::from(50)); + assert_eq!( + context.meta_call_function(meta_tx).unwrap_err().to_string(), + "EvmError(InvalidNonce)" + ); +} + +#[test] +#[ignore] +fn test_meta_call_sig_recover() { + let meta_tx = [ + // signature: 65 bytes + hex::decode("1cb6f28f29524cf3ae5ce49f364b5ad798af5dd8ec3563744dc62792735ce5e222285df1e91c416e430d0a38ea3b51d6677e337e1b0684d7618f5a00a26a2ee21c").unwrap(), + // nonce: 14 + u256_to_arr(&U256::from(14)).to_vec(), + // fee amount: 6 + u256_to_arr(&U256::from(6)).to_vec(), + // fee token: 0x0 + vec![0; 20], + // contract: address, + hex::decode("Ed2a1b3Fa739DAbBf8c07a059dE1333D20e8b482").unwrap(), + // contract method: length 1 byte + bytes for the name. + vec![14], + b"adopt(uint256)".to_vec(), + // arguments + u256_to_arr(&U256::from(9)).to_vec(), + ].concat(); + let domain_separator = near_erc721_domain(U256::from(CHAIN_ID)); + let result = parse_meta_call(&domain_separator, &"evm".to_string(), meta_tx).unwrap(); + assert_eq!(result.sender.to_hex(), "2941022347348828A24a5ff33c775D67691681e9"); +} diff --git a/runtime/near-evm-runner/tests/truffle-config.js b/runtime/near-evm-runner/tests/truffle-config.js new file mode 100644 index 00000000000..f036f7b7bf4 --- /dev/null +++ b/runtime/near-evm-runner/tests/truffle-config.js @@ -0,0 +1,7 @@ +// empty, but necessary for truffle compile +module.exports = { + networks: {}, + compilers: { + solc: {} + } +} diff --git a/runtime/near-evm-runner/tests/utils/mod.rs b/runtime/near-evm-runner/tests/utils/mod.rs new file mode 100644 index 00000000000..bf063b6a480 --- /dev/null +++ b/runtime/near-evm-runner/tests/utils/mod.rs @@ -0,0 +1,107 @@ +use ethereum_types::{Address, U256}; +use keccak_hash::keccak; +use near_crypto::{PublicKey, Signature, Signer}; +use near_evm_runner::utils::{near_erc721_domain, prepare_meta_call_args, u256_to_arr}; +use near_evm_runner::EvmContext; +use near_runtime_fees::RuntimeFeesConfig; +use near_vm_logic::mocks::mock_external::MockedExternal; +use near_vm_logic::types::Balance; +use near_vm_logic::VMConfig; + +/// See https://github.com/ethereum-lists/chains/blob/master/_data/chains/1313161555.json +pub const CHAIN_ID: u128 = 1313161555; + +pub fn accounts(num: usize) -> String { + ["evm", "alice", "bob", "chad"][num].to_string() +} + +pub fn setup() -> (MockedExternal, VMConfig, RuntimeFeesConfig) { + let vm_config = VMConfig::default(); + let fees_config = RuntimeFeesConfig::default(); + let fake_external = MockedExternal::new(); + (fake_external, vm_config, fees_config) +} + +pub fn create_context<'a>( + external: &'a mut MockedExternal, + vm_config: &'a VMConfig, + fees_config: &'a RuntimeFeesConfig, + account_id: String, + attached_deposit: Balance, +) -> EvmContext<'a> { + EvmContext::new( + external, + CHAIN_ID, + vm_config, + fees_config, + 1000, + "evm".to_string(), + account_id.to_string(), + account_id.to_string(), + attached_deposit, + 0, + 10u64.pow(14), + false, + 1_000_000_000.into(), + ) +} + +#[cfg(test)] +#[allow(dead_code)] +pub fn show_evm_gas_used(context: &EvmContext) { + println!("Accumulated EVM gas used: {}", &context.evm_gas_counter.used_gas); +} + +/// Linter is suboptimal, because doesn't see that this is used in standard_ops.rs. +#[allow(dead_code)] +pub fn public_key_to_address(public_key: PublicKey) -> Address { + match public_key { + PublicKey::ED25519(_) => panic!("Wrong PublicKey"), + PublicKey::SECP256K1(pubkey) => { + let pk: [u8; 64] = pubkey.into(); + let bytes = keccak(&pk.to_vec()); + let mut result = Address::zero(); + result.as_bytes_mut().copy_from_slice(&bytes[12..]); + result + } + } +} + +/// Linter is suboptimal, because doesn't see that this is used in standard_ops.rs. +#[allow(dead_code)] +pub fn encode_meta_call_function_args( + signer: &dyn Signer, + chain_id: u128, + nonce: U256, + fee_amount: U256, + fee_token: Address, + address: Address, + method_name: &str, + args: Vec, +) -> Vec { + let domain_separator = near_erc721_domain(U256::from(chain_id)); + let msg = prepare_meta_call_args( + &domain_separator, + &"evm".to_string(), + nonce, + fee_amount, + fee_token, + address, + method_name, + &args, + ); + match signer.sign(&msg) { + Signature::ED25519(_) => panic!("Wrong Signer"), + Signature::SECP256K1(sig) => [ + Into::<[u8; 65]>::into(sig).to_vec(), + u256_to_arr(&nonce).to_vec(), + u256_to_arr(&fee_amount).to_vec(), + fee_token.0.to_vec(), + address.0.to_vec(), + vec![method_name.len() as u8], + method_name.as_bytes().to_vec(), + args, + ] + .concat(), + } +} diff --git a/runtime/near-runtime-fees/Cargo.toml b/runtime/near-runtime-fees/Cargo.toml index 39f7f43b0cb..e5e235043f6 100644 --- a/runtime/near-runtime-fees/Cargo.toml +++ b/runtime/near-runtime-fees/Cargo.toml @@ -16,3 +16,7 @@ Fees applied to near runtime encapsulated in a separate crate. Might merge it la serde = { version = "1", features = ["derive"] } num-rational = { version = "0.2.4", features = ["serde"]} + +[features] +default = [] +protocol_feature_evm = [] diff --git a/runtime/near-runtime-fees/src/lib.rs b/runtime/near-runtime-fees/src/lib.rs index 6e484a2a4be..94bb39f37cb 100644 --- a/runtime/near-runtime-fees/src/lib.rs +++ b/runtime/near-runtime-fees/src/lib.rs @@ -6,7 +6,14 @@ use num_rational::Rational; use serde::{Deserialize, Serialize}; +pub type Balance = u128; pub type Gas = u64; +#[cfg(feature = "protocol_feature_evm")] +pub type EvmGas = u64; + +/// The amount is 1000 * 10e24 = 1000 NEAR. +#[cfg(feature = "protocol_feature_evm")] +const EVM_DEPOSIT: Balance = 1_000_000_000_000_000_000_000_000_000; /// Costs associated with an object that can only be sent over the network (and executed /// by the receiver). @@ -44,6 +51,7 @@ impl Fee { } #[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] +#[serde(default)] pub struct RuntimeFeesConfig { /// Describes the cost of creating an action receipt, `ActionReceipt`, excluding the actual cost /// of actions. @@ -63,6 +71,16 @@ pub struct RuntimeFeesConfig { /// Pessimistic gas price inflation ratio. pub pessimistic_gas_price_inflation_ratio: Rational, + + /// Describes cost of running method of evm, include deploy code and call contract function + #[cfg(feature = "protocol_feature_evm")] + pub evm_config: EvmCostConfig, + + /// New EVM deposit. + /// Fee to create new EVM account. + #[cfg(feature = "protocol_feature_evm")] + #[serde(with = "u128_dec_format")] + pub evm_deposit: Balance, } /// Describes the cost of creating a data receipt, `DataReceipt`. @@ -135,6 +153,87 @@ pub struct StorageUsageConfig { pub num_extra_bytes_record: u64, } +/// Describe cost of evm +#[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] +pub struct EvmCostConfig { + /// Base cost of instantiate an evm instance for any evm operation + pub bootstrap_cost: Gas, + /// For every unit of gas used by evm in deploy evm contract, equivalent near gas cost + pub deploy_cost_per_evm_gas: Gas, + /// For every byte of evm contract, result near gas cost + pub deploy_cost_per_byte: Gas, + /// For bootstrapped evm, base cost to invoke a contract function + pub funcall_cost_base: Gas, + /// For every unit of gas used by evm in funcall, equivalent near gas cost + pub funcall_cost_per_evm_gas: Gas, + /// Evm precompiled function costs + pub precompile_costs: EvmPrecompileCostConfig, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] +pub struct EvmPrecompileCostConfig { + pub ecrecover_cost: EvmLinearCost, + pub sha256_cost: EvmLinearCost, + pub ripemd160_cost: EvmLinearCost, + pub identity_cost: EvmLinearCost, + pub modexp_cost: EvmModexpCost, + pub bn128_add_cost: EvmBls12ConstOpCost, + pub bn128_mul_cost: EvmBls12ConstOpCost, + pub bn128_pairing_cost: EvmBn128PairingCost, + pub blake2f_cost: EvmBlake2FCost, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] +pub struct EvmLinearCost { + pub base: u64, + pub word: u64, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] +pub struct EvmModexpCost { + pub divisor: u64, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] +pub struct EvmBls12ConstOpCost { + pub price: u64, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] +pub struct EvmBn128PairingCost { + pub base: u64, + pub pair: u64, +} + +pub type EvmBlake2FCost = u64; + +impl Default for EvmCostConfig { + fn default() -> Self { + Self { + // Got inside emu-cost docker, numbers differ slightly in different runs: + // cd /host/nearcore/runtime/near-evm-runner/tests + // ../../runtime-params-estimator/emu-cost/counter_plugin/qemu-x86_64 -cpu Westmere-v1 -plugin file=../../runtime-params-estimator/emu-cost/counter_plugin/libcounter.so ../../../target/release/runtime-params-estimator --home /tmp/data --accounts-num 200000 --iters 1 --warmup-iters 1 --evm-only + bootstrap_cost: 373945633846, + deploy_cost_per_evm_gas: 3004467, + deploy_cost_per_byte: 2732257, + funcall_cost_base: 300126401250, + funcall_cost_per_evm_gas: 116076934, + precompile_costs: EvmPrecompileCostConfig { + // Data from openethereum/ethcore/res/ethereum/ethercore.json + ecrecover_cost: EvmLinearCost { base: 3000, word: 0 }, + sha256_cost: EvmLinearCost { base: 60, word: 12 }, + ripemd160_cost: EvmLinearCost { base: 600, word: 120 }, + identity_cost: EvmLinearCost { base: 15, word: 3 }, + modexp_cost: EvmModexpCost { divisor: 20 }, + bn128_add_cost: EvmBls12ConstOpCost { price: 150 }, + bn128_mul_cost: EvmBls12ConstOpCost { price: 6000 }, + bn128_pairing_cost: EvmBn128PairingCost { base: 45000, pair: 34000 }, + blake2f_cost: 1, + }, + } + } +} + impl Default for RuntimeFeesConfig { fn default() -> Self { #[allow(clippy::unreadable_literal)] @@ -228,6 +327,10 @@ impl Default for RuntimeFeesConfig { }, burnt_gas_reward: Rational::new(3, 10), pessimistic_gas_price_inflation_ratio: Rational::new(103, 100), + #[cfg(feature = "protocol_feature_evm")] + evm_config: EvmCostConfig::default(), + #[cfg(feature = "protocol_feature_evm")] + evm_deposit: EVM_DEPOSIT, } } } @@ -263,6 +366,27 @@ impl RuntimeFeesConfig { }, burnt_gas_reward: Rational::from_integer(0), pessimistic_gas_price_inflation_ratio: Rational::from_integer(0), + #[cfg(feature = "protocol_feature_evm")] + evm_config: EvmCostConfig { + bootstrap_cost: 0, + deploy_cost_per_evm_gas: 0, + deploy_cost_per_byte: 0, + funcall_cost_base: 0, + funcall_cost_per_evm_gas: 0, + precompile_costs: EvmPrecompileCostConfig { + ecrecover_cost: EvmLinearCost { base: 0, word: 0 }, + sha256_cost: EvmLinearCost { base: 0, word: 0 }, + ripemd160_cost: EvmLinearCost { base: 0, word: 0 }, + identity_cost: EvmLinearCost { base: 0, word: 0 }, + modexp_cost: EvmModexpCost { divisor: 1 }, + bn128_add_cost: EvmBls12ConstOpCost { price: 0 }, + bn128_mul_cost: EvmBls12ConstOpCost { price: 0 }, + bn128_pairing_cost: EvmBn128PairingCost { base: 0, pair: 0 }, + blake2f_cost: 0, + }, + }, + #[cfg(feature = "protocol_feature_evm")] + evm_deposit: 0, } } @@ -276,6 +400,30 @@ impl RuntimeFeesConfig { } } +/// Serde serializer for u128 to integer. +/// This is copy from core/primitives/src/serialize.rs +/// It is required as this module doesn't depend on primitives. +/// TODO(3384): move basic primitives into a separate module and use in runtime. +pub mod u128_dec_format { + use serde::de; + use serde::{Deserialize, Deserializer, Serializer}; + + pub fn serialize(num: &u128, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&format!("{}", num)) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + u128::from_str_radix(&s, 10).map_err(de::Error::custom) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/runtime/near-runtime-utils/Cargo.toml b/runtime/near-runtime-utils/Cargo.toml index f2b806a04c3..b800610ccf9 100644 --- a/runtime/near-runtime-utils/Cargo.toml +++ b/runtime/near-runtime-utils/Cargo.toml @@ -17,3 +17,5 @@ This crate contains utility functions for NEAR runtime. # Historically, `near-primitives` contained a bunch of dependencies that prevented this crate from being compiled to Wasm. [dependencies] +lazy_static = "1.4" +regex = "1" diff --git a/runtime/near-runtime-utils/src/lib.rs b/runtime/near-runtime-utils/src/lib.rs index 2efd03702bf..9298cb35e25 100644 --- a/runtime/near-runtime-utils/src/lib.rs +++ b/runtime/near-runtime-utils/src/lib.rs @@ -1,4 +1,61 @@ //! Contains utility functions for runtime. +#[macro_use] +extern crate lazy_static; + +use regex::Regex; + +type AccountId = String; + +pub const MIN_ACCOUNT_ID_LEN: usize = 2; +pub const MAX_ACCOUNT_ID_LEN: usize = 64; + +lazy_static! { + /// See NEP#0006 + static ref VALID_ACCOUNT_ID: Regex = + Regex::new(r"^(([a-z\d]+[\-_])*[a-z\d]+\.)*([a-z\d]+[\-_])*[a-z\d]+$").unwrap(); + /// Represents a part of an account ID with a suffix of as a separator `.`. + static ref VALID_ACCOUNT_PART_ID_WITH_TAIL_SEPARATOR: Regex = + Regex::new(r"^([a-z\d]+[\-_])*[a-z\d]+\.$").unwrap(); + /// Represents a top level account ID. + static ref VALID_TOP_LEVEL_ACCOUNT_ID: Regex = + Regex::new(r"^([a-z\d]+[\-_])*[a-z\d]+$").unwrap(); +} + +/// const does not allow function call, so have to resort to this +pub fn system_account() -> AccountId { + "system".to_string() +} + +pub fn is_valid_account_id(account_id: &AccountId) -> bool { + account_id.len() >= MIN_ACCOUNT_ID_LEN + && account_id.len() <= MAX_ACCOUNT_ID_LEN + && VALID_ACCOUNT_ID.is_match(account_id) +} + +pub fn is_valid_top_level_account_id(account_id: &AccountId) -> bool { + account_id.len() >= MIN_ACCOUNT_ID_LEN + && account_id.len() <= MAX_ACCOUNT_ID_LEN + && account_id != &system_account() + && VALID_TOP_LEVEL_ACCOUNT_ID.is_match(account_id) +} + +/// Returns true if the signer_id can create a direct sub-account with the given account Id. +/// It assumes the signer_id is a valid account_id +pub fn is_valid_sub_account_id(signer_id: &AccountId, sub_account_id: &AccountId) -> bool { + if !is_valid_account_id(sub_account_id) { + return false; + } + if signer_id.len() >= sub_account_id.len() { + return false; + } + // Will not panic, since valid account id is utf-8 only and the length is checked above. + // e.g. when `near` creates `aa.near`, it splits into `aa.` and `near` + let (prefix, suffix) = sub_account_id.split_at(sub_account_id.len() - signer_id.len()); + if suffix != signer_id { + return false; + } + VALID_ACCOUNT_PART_ID_WITH_TAIL_SEPARATOR.is_match(prefix) +} /// Returns true if the account ID length is 64 characters and it's a hex representation. pub fn is_account_id_64_len_hex(account_id: &str) -> bool { @@ -9,10 +66,233 @@ pub fn is_account_id_64_len_hex(account_id: &str) -> bool { }) } +/// Returns true if the account ID is suppose to be EVM machine. +pub fn is_account_evm(account_id: &str) -> bool { + account_id == "evm" +} + #[cfg(test)] mod tests { use super::*; + const OK_ACCOUNT_IDS: &[&str] = &[ + "aa", + "a-a", + "a-aa", + "100", + "0o", + "com", + "near", + "bowen", + "b-o_w_e-n", + "b.owen", + "bro.wen", + "a.ha", + "a.b-a.ra", + "system", + "over.9000", + "google.com", + "illia.cheapaccounts.near", + "0o0ooo00oo00o", + "alex-skidanov", + "10-4.8-2", + "b-o_w_e-n", + "no_lols", + "0123456789012345678901234567890123456789012345678901234567890123", + // Valid, but can't be created + "near.a", + ]; + + #[test] + fn test_is_valid_account_id() { + for account_id in OK_ACCOUNT_IDS { + assert!( + is_valid_account_id(&account_id.to_string()), + "Valid account id {:?} marked invalid", + account_id + ); + } + + let bad_account_ids = vec![ + "a", + "A", + "Abc", + "-near", + "near-", + "-near-", + "near.", + ".near", + "near@", + "@near", + "неар", + "@@@@@", + "0__0", + "0_-_0", + "0_-_0", + "..", + "a..near", + "nEar", + "_bowen", + "hello world", + "abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz", + "01234567890123456789012345678901234567890123456789012345678901234", + // `@` separators are banned now + "some-complex-address@gmail.com", + "sub.buy_d1gitz@atata@b0-rg.c_0_m", + ]; + for account_id in bad_account_ids { + assert!( + !is_valid_account_id(&account_id.to_string()), + "Invalid account id {:?} marked valid", + account_id + ); + } + } + + #[test] + fn test_is_valid_top_level_account_id() { + let ok_top_level_account_ids = vec![ + "aa", + "a-a", + "a-aa", + "100", + "0o", + "com", + "near", + "bowen", + "b-o_w_e-n", + "0o0ooo00oo00o", + "alex-skidanov", + "b-o_w_e-n", + "no_lols", + "0123456789012345678901234567890123456789012345678901234567890123", + ]; + for account_id in ok_top_level_account_ids { + assert!( + is_valid_top_level_account_id(&account_id.to_string()), + "Valid top level account id {:?} marked invalid", + account_id + ); + } + + let bad_top_level_account_ids = vec![ + "near.a", + "b.owen", + "bro.wen", + "a.ha", + "a.b-a.ra", + "some-complex-address@gmail.com", + "sub.buy_d1gitz@atata@b0-rg.c_0_m", + "over.9000", + "google.com", + "illia.cheapaccounts.near", + "10-4.8-2", + "a", + "A", + "Abc", + "-near", + "near-", + "-near-", + "near.", + ".near", + "near@", + "@near", + "неар", + "@@@@@", + "0__0", + "0_-_0", + "0_-_0", + "..", + "a..near", + "nEar", + "_bowen", + "hello world", + "abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz.abcdefghijklmnopqrstuvwxyz", + "01234567890123456789012345678901234567890123456789012345678901234", + // Valid regex and length, but reserved + "system", + ]; + for account_id in bad_top_level_account_ids { + assert!( + !is_valid_top_level_account_id(&account_id.to_string()), + "Invalid top level account id {:?} marked valid", + account_id + ); + } + } + + #[test] + fn test_is_valid_sub_account_id() { + let ok_pairs = vec![ + ("test", "a.test"), + ("test-me", "abc.test-me"), + ("gmail.com", "abc.gmail.com"), + ("gmail.com", "abc-lol.gmail.com"), + ("gmail.com", "abc_lol.gmail.com"), + ("gmail.com", "bro-abc_lol.gmail.com"), + ("g0", "0g.g0"), + ("1g", "1g.1g"), + ("5-3", "4_2.5-3"), + ]; + for (signer_id, sub_account_id) in ok_pairs { + assert!( + is_valid_sub_account_id(&signer_id.to_string(), &sub_account_id.to_string()), + "Failed to create sub-account {:?} by account {:?}", + sub_account_id, + signer_id + ); + } + + let bad_pairs = vec![ + ("test", ".test"), + ("test", "test"), + ("test", "est"), + ("test", ""), + ("test", "st"), + ("test5", "ббб"), + ("test", "a-test"), + ("test", "etest"), + ("test", "a.etest"), + ("test", "retest"), + ("test-me", "abc-.test-me"), + ("test-me", "Abc.test-me"), + ("test-me", "-abc.test-me"), + ("test-me", "a--c.test-me"), + ("test-me", "a_-c.test-me"), + ("test-me", "a-_c.test-me"), + ("test-me", "_abc.test-me"), + ("test-me", "abc_.test-me"), + ("test-me", "..test-me"), + ("test-me", "a..test-me"), + ("gmail.com", "a.abc@gmail.com"), + ("gmail.com", ".abc@gmail.com"), + ("gmail.com", ".abc@gmail@com"), + ("gmail.com", "abc@gmail@com"), + ("test", "a@test"), + ("test_me", "abc@test_me"), + ("gmail.com", "abc@gmail.com"), + ("gmail@com", "abc.gmail@com"), + ("gmail.com", "abc-lol@gmail.com"), + ("gmail@com", "abc_lol.gmail@com"), + ("gmail@com", "bro-abc_lol.gmail@com"), + ("gmail.com", "123456789012345678901234567890123456789012345678901234567890@gmail.com"), + ( + "123456789012345678901234567890123456789012345678901234567890", + "1234567890.123456789012345678901234567890123456789012345678901234567890", + ), + ("aa", "ъ@aa"), + ("aa", "ъ.aa"), + ]; + for (signer_id, sub_account_id) in bad_pairs { + assert!( + !is_valid_sub_account_id(&signer_id.to_string(), &sub_account_id.to_string()), + "Invalid sub-account {:?} created by account {:?}", + sub_account_id, + signer_id + ); + } + } + #[test] fn test_is_account_id_64_len_hex() { let valid_64_len_hex_account_ids = vec![ diff --git a/runtime/near-vm-errors/Cargo.toml b/runtime/near-vm-errors/Cargo.toml index 2373b78b2d0..c443b25dfbd 100644 --- a/runtime/near-vm-errors/Cargo.toml +++ b/runtime/near-vm-errors/Cargo.toml @@ -13,11 +13,14 @@ Error that can occur inside Near Runtime encapsulated in a separate crate. Might """ [dependencies] +hex = "0.4" serde = { version = "1", features = ["derive"] } borsh = "0.7.1" near-rpc-error-macro = { path = "../../tools/rpctypegen/macro", version = "0.1.0" } +ethereum-types = "0.8.0" + [features] dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] diff --git a/runtime/near-vm-errors/src/lib.rs b/runtime/near-vm-errors/src/lib.rs index 50b5d4c2b13..bed8ead86f6 100644 --- a/runtime/near-vm-errors/src/lib.rs +++ b/runtime/near-vm-errors/src/lib.rs @@ -1,7 +1,11 @@ +use std::fmt; + use borsh::{BorshDeserialize, BorshSerialize}; -use near_rpc_error_macro::RpcError; +use serde::export::fmt::Error; +use serde::export::Formatter; use serde::{Deserialize, Serialize}; -use std::fmt; + +use near_rpc_error_macro::RpcError; #[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize, Deserialize, Serialize)] pub enum VMError { @@ -31,6 +35,7 @@ pub enum FunctionCallError { WasmTrap(WasmTrap), WasmUnknownError, HostError(HostError), + EvmError(EvmError), } #[derive( Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize, Deserialize, Serialize, RpcError, @@ -179,19 +184,99 @@ pub enum HostError { Deprecated { method_name: String }, } +/// Errors specifically from native EVM. +#[derive(Debug, Clone, Eq, PartialEq, BorshDeserialize, BorshSerialize, Deserialize, Serialize)] +pub enum EvmError { + /// Contract not found. + ContractNotFound, + /// Fatal failure due conflicting addresses on contract deployment. + DuplicateContract(#[serde(with = "hex_format")] Vec), + /// Contract deployment failure. + DeployFail(#[serde(with = "hex_format")] Vec), + /// Contract execution failed, revert the state. + Revert(#[serde(with = "hex_format")] Vec), + /// Failed to parse arguments. + ArgumentParseError, + /// No deposit when expected. + MissingDeposit, + /// Insufficient funds to finish the operation. + InsufficientFunds, + /// U256 overflow. + IntegerOverflow, + /// Method not found. + MethodNotFound, + /// Invalid signature when recovering. + InvalidEcRecoverSignature, + /// Invalid nonce. + InvalidNonce, + /// Invalid sub EVM account. + InvalidSubAccount, + /// Won't withdraw to itself. + FailSelfWithdraw, + /// Too small NEAR deposit. + InsufficientDeposit, + /// `OutOfGas` is returned when transaction execution runs out of gas. + /// The state should be reverted to the state from before the + /// transaction execution. But it does not mean that transaction + /// was invalid. Balance still should be transfered and nonce + /// should be increased. + OutOfGas, + /// `BadJumpDestination` is returned when execution tried to move + /// to position that wasn't marked with JUMPDEST instruction + BadJumpDestination { + /// Position the code tried to jump to. + destination: u64, + }, + /// `BadInstructions` is returned when given instruction is not supported + BadInstruction { + /// Unrecognized opcode + instruction: u8, + }, + /// `StackUnderflow` when there is not enough stack elements to execute instruction + StackUnderflow { + /// Invoked instruction + instruction: String, + /// How many stack elements was requested by instruction + wanted: u64, + /// How many elements were on stack + on_stack: u64, + }, + /// When execution would exceed defined Stack Limit + OutOfStack { + /// Invoked instruction + instruction: String, + /// How many stack elements instruction wanted to push + wanted: u64, + /// What was the stack limit + limit: u64, + }, + /// Built-in contract failed on given input + BuiltIn(String), + /// When execution tries to modify the state in static context + MutableCallInStaticContext, + /// Out of bounds access in RETURNDATACOPY. + OutOfBounds, + /// Execution has been reverted with REVERT. + Reverted, +} + #[derive(Debug, Clone, PartialEq, BorshDeserialize, BorshSerialize, Deserialize, Serialize)] pub enum VMLogicError { + /// Errors coming from native Wasm VM. HostError(HostError), /// Serialized external error from External trait implementation. ExternalError(Vec), /// An error that is caused by an operation on an inconsistent state. InconsistentStateError(InconsistentStateError), + /// An error coming from native EVM. + EvmError(EvmError), } /// An error that is caused by an operation on an inconsistent state. /// E.g. a deserialization error or an integer overflow. #[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize, Deserialize, Serialize)] pub enum InconsistentStateError { + StorageError(String), /// Math operation with a value from the state resulted in a integer overflow. IntegerOverflow, } @@ -216,6 +301,12 @@ impl From for VMError { } } +impl fmt::Display for VMLogicError { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { + write!(f, "{:?}", self) + } +} + impl fmt::Display for PrepareError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { use PrepareError::*; @@ -244,6 +335,7 @@ impl fmt::Display for FunctionCallError { FunctionCallError::WasmUnknownError => { write!(f, "Unknown error during Wasm contract execution") } + FunctionCallError::EvmError(e) => write!(f, "EVM: {:?}", e), } } } @@ -302,6 +394,7 @@ impl fmt::Display for VMError { impl std::fmt::Display for InconsistentStateError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { match self { + InconsistentStateError::StorageError(err) => write!(f, "Storage error: {:?}", err), InconsistentStateError::IntegerOverflow => write!( f, "Math operation with a value from the state resulted in a integer overflow.", @@ -348,6 +441,30 @@ impl std::fmt::Display for HostError { } } +pub mod hex_format { + use hex::{decode, encode}; + + use serde::de; + use serde::{Deserialize, Deserializer, Serializer}; + + pub fn serialize(data: T, serializer: S) -> Result + where + S: Serializer, + T: AsRef<[u8]>, + { + serializer.serialize_str(&encode(data)) + } + + pub fn deserialize<'de, D, T>(deserializer: D) -> Result + where + D: Deserializer<'de>, + T: From>, + { + let s = String::deserialize(deserializer)?; + decode(&s).map_err(|err| de::Error::custom(err.to_string())).map(Into::into) + } +} + #[cfg(test)] mod tests { use crate::{CompilationError, FunctionCallError, MethodResolveError, PrepareError, VMError}; diff --git a/runtime/near-vm-logic/Cargo.toml b/runtime/near-vm-logic/Cargo.toml index 8aba801f3d7..8e3a897a678 100644 --- a/runtime/near-vm-logic/Cargo.toml +++ b/runtime/near-vm-logic/Cargo.toml @@ -30,8 +30,10 @@ serde_json = {version= "1", features= ["preserve_order"]} [features] default = ["costs_counting"] +protocol_feature_evm = ["near-runtime-fees/protocol_feature_evm"] wasmtime_default = [] + # Use this feature to enable counting of fees and costs applied. costs_counting = [] diff --git a/runtime/near-vm-logic/src/dependencies.rs b/runtime/near-vm-logic/src/dependencies.rs index 60f9074627c..db66e10c0be 100644 --- a/runtime/near-vm-logic/src/dependencies.rs +++ b/runtime/near-vm-logic/src/dependencies.rs @@ -111,13 +111,37 @@ pub trait External { /// /// # let mut external = MockedExternal::new(); /// external.storage_set(b"key42", b"value1337").unwrap(); - /// // Returns value if exists + /// // Returns Ok if exists /// assert_eq!(external.storage_remove(b"key42"), Ok(())); - /// // Returns None if there was no value + /// // Returns Ok if there was no value /// assert_eq!(external.storage_remove(b"no_value_key"), Ok(())); /// ``` fn storage_remove(&mut self, key: &[u8]) -> Result<()>; + /// Removes all keys under given suffix in the storage. + /// + /// # Arguments + /// + /// * `prefix` - a prefix for all keys to remove + /// + /// # Errors + /// + /// This function could return HostErrorOrStorageError::StorageError on underlying DB failure + /// + /// # Example + /// ``` + /// # use near_vm_logic::mocks::mock_external::MockedExternal; + /// # use near_vm_logic::External; + /// + /// # let mut external = MockedExternal::new(); + /// external.storage_set(b"key1", b"value1337").unwrap(); + /// external.storage_set(b"key2", b"value1337").unwrap(); + /// assert_eq!(external.storage_remove_subtree(b"key"), Ok(())); + /// assert!(!external.storage_has_key(b"key1").unwrap()); + /// assert!(!external.storage_has_key(b"key2").unwrap()); + /// ``` + fn storage_remove_subtree(&mut self, prefix: &[u8]) -> Result<()>; + /// Check whether key exists. Returns Ok(true) if key exists or Ok(false) otherwise /// /// # Arguments diff --git a/runtime/near-vm-logic/src/gas_counter.rs b/runtime/near-vm-logic/src/gas_counter.rs index 7a99702f271..d114b5ea2ba 100644 --- a/runtime/near-vm-logic/src/gas_counter.rs +++ b/runtime/near-vm-logic/src/gas_counter.rs @@ -1,12 +1,27 @@ use crate::config::{ActionCosts, ExtCosts, ExtCostsConfig}; use crate::types::{Gas, ProfileData}; use crate::{HostError, VMLogicError}; +#[cfg(feature = "protocol_feature_evm")] +use near_runtime_fees::EvmGas; use near_runtime_fees::Fee; #[cfg(feature = "costs_counting")] thread_local! { pub static EXT_COSTS_COUNTER: std::cell::RefCell> = Default::default(); + + #[cfg(feature = "protocol_feature_evm")] + pub static EVM_GAS_COUNTER: std::cell::RefCell = Default::default(); +} + +#[cfg(all(feature = "costs_counting", feature = "protocol_feature_evm"))] +pub fn reset_evm_gas_counter() -> u64 { + let mut ret = 0; + EVM_GAS_COUNTER.with(|f| { + ret = *f.borrow(); + *f.borrow_mut() = 0; + }); + ret } type Result = ::std::result::Result; @@ -26,6 +41,13 @@ pub struct GasCounter { profile: Option, } +use std::fmt; +impl fmt::Debug for GasCounter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("").finish() + } +} + impl GasCounter { pub fn new( ext_costs_config: ExtCostsConfig, @@ -73,6 +95,18 @@ impl GasCounter { } } + #[cfg(all(feature = "costs_counting", feature = "protocol_feature_evm"))] + #[inline] + pub fn inc_evm_gas_counter(&mut self, value: EvmGas) { + EVM_GAS_COUNTER.with(|f| { + *f.borrow_mut() += value; + }) + } + + #[cfg(all(not(feature = "costs_counting"), feature = "protocol_feature_evm"))] + #[inline] + pub fn inc_evm_gas_counter(&mut self, _value: EvmGas) {} + #[cfg(feature = "costs_counting")] #[inline] fn inc_ext_costs_counter(&mut self, cost: ExtCosts, value: u64) { @@ -117,6 +151,10 @@ impl GasCounter { self.deduct_gas(value, value) } + pub fn pay_evm_gas(&mut self, value: u64) -> Result<()> { + self.deduct_gas(value, value) + } + /// A helper function to pay per byte gas pub fn pay_per_byte(&mut self, cost: ExtCosts, num_bytes: u64) -> Result<()> { let use_gas = num_bytes diff --git a/runtime/near-vm-logic/src/lib.rs b/runtime/near-vm-logic/src/lib.rs index 113afd33075..e76c348a03d 100644 --- a/runtime/near-vm-logic/src/lib.rs +++ b/runtime/near-vm-logic/src/lib.rs @@ -1,7 +1,7 @@ mod config; mod context; mod dependencies; -mod gas_counter; +pub mod gas_counter; mod logic; pub mod mocks; pub mod serde_with; diff --git a/runtime/near-vm-logic/src/mocks/mock_external.rs b/runtime/near-vm-logic/src/mocks/mock_external.rs index 123a4534203..2f5906acf55 100644 --- a/runtime/near-vm-logic/src/mocks/mock_external.rs +++ b/runtime/near-vm-logic/src/mocks/mock_external.rs @@ -66,6 +66,18 @@ impl External for MockedExternal { Ok(()) } + fn storage_remove_subtree(&mut self, prefix: &[u8]) -> Result<()> { + let keys: Vec<_> = self + .fake_trie + .iter() + .filter_map(|(key, _)| if key.starts_with(prefix) { Some(key.clone()) } else { None }) + .collect(); + for key in keys { + self.fake_trie.remove(&key); + } + Ok(()) + } + fn storage_has_key(&mut self, key: &[u8]) -> Result { Ok(self.fake_trie.contains_key(key)) } diff --git a/runtime/near-vm-logic/src/types.rs b/runtime/near-vm-logic/src/types.rs index 3416fd713cb..21745e20be6 100644 --- a/runtime/near-vm-logic/src/types.rs +++ b/runtime/near-vm-logic/src/types.rs @@ -29,6 +29,16 @@ pub enum ReturnData { None, } +impl ReturnData { + /// Function to extract value from ReturnData. + pub fn as_value(self) -> Option> { + match self { + ReturnData::Value(value) => Some(value), + _ => None, + } + } +} + /// When there is a callback attached to one or more contract calls the execution results of these /// calls are available to the contract invoked through the callback. #[derive(Debug, PartialEq, Serialize, Deserialize)] diff --git a/runtime/near-vm-runner-standalone/example-contract/Cargo.toml b/runtime/near-vm-runner-standalone/example-contract/Cargo.toml index 91707826836..a839cfefff5 100644 --- a/runtime/near-vm-runner-standalone/example-contract/Cargo.toml +++ b/runtime/near-vm-runner-standalone/example-contract/Cargo.toml @@ -13,7 +13,7 @@ serde_json = "1" wee_alloc = "0.4.5" near-sdk = "0.6.0" -borsh = "0.6.0" +borsh = "0.7.1" [profile.release] codegen-units = 1 diff --git a/runtime/near-vm-runner/Cargo.toml b/runtime/near-vm-runner/Cargo.toml index 22f8b160c88..1ad276e732e 100644 --- a/runtime/near-vm-runner/Cargo.toml +++ b/runtime/near-vm-runner/Cargo.toml @@ -25,6 +25,7 @@ near-vm-logic = { path="../near-vm-logic", version = "2.2.0", default-features = near-vm-errors = { path = "../near-vm-errors", version = "2.2.0" } near-primitives = { path = "../../core/primitives" } log = "0.4" +near-evm-runner = { path = "../near-evm-runner", version = "2.2.0", optional = true} [dev-dependencies] assert_matches = "1.3" @@ -38,6 +39,7 @@ wasmer_default = [] wasmtime_default = ["wasmtime_vm"] no_cpu_compatibility_checks = [] lightbeam = ["wasmtime_vm"] +protocol_feature_evm = ["near-runtime-fees/protocol_feature_evm", "near-evm-runner/protocol_feature_evm"] # Use this feature to enable counting of fees and costs applied. costs_counting = ["near-vm-logic/costs_counting"] diff --git a/runtime/near-vm-runner/src/wasmer_runner.rs b/runtime/near-vm-runner/src/wasmer_runner.rs index 249dd6da6ab..9047ab2b480 100644 --- a/runtime/near-vm-runner/src/wasmer_runner.rs +++ b/runtime/near-vm-runner/src/wasmer_runner.rs @@ -161,6 +161,7 @@ impl IntoVMError for wasmer_runtime::error::RuntimeError { VMLogicError::InconsistentStateError(e) => { VMError::InconsistentStateError(e.clone()) } + VMLogicError::EvmError(_) => unreachable!("Wasm can't return EVM error"), } } else { panic!( diff --git a/runtime/near-vm-runner/src/wasmtime_runner.rs b/runtime/near-vm-runner/src/wasmtime_runner.rs index b6dff8b8e52..a28286ebedb 100644 --- a/runtime/near-vm-runner/src/wasmtime_runner.rs +++ b/runtime/near-vm-runner/src/wasmtime_runner.rs @@ -79,6 +79,7 @@ pub mod wasmtime_runner { Some(VMLogicError::InconsistentStateError(e)) => { VMError::InconsistentStateError(e.clone()) } + Some(VMLogicError::EvmError(_)) => unreachable!("Wasm can't return EVM error"), None => panic!("Error is not properly set"), } } else { diff --git a/runtime/runtime-params-estimator/Cargo.toml b/runtime/runtime-params-estimator/Cargo.toml index 0754f292624..f27a021cae0 100644 --- a/runtime/runtime-params-estimator/Cargo.toml +++ b/runtime/runtime-params-estimator/Cargo.toml @@ -17,6 +17,7 @@ clap = "2.33" borsh = "0.7.1" num-rational = "0.3.0" +near-chain-configs = { path = "../../core/chain-configs" } near-runtime-fees = { path = "../../runtime/near-runtime-fees" } near-crypto = { path = "../../core/crypto" } near-vm-logic = {path = "../../runtime/near-vm-logic" , features = ["costs_counting"]} @@ -24,12 +25,23 @@ near-vm-runner = {path = "../../runtime/near-vm-runner" , features = ["costs_cou node-runtime = { path = "../../runtime/runtime" , features = ["costs_counting", "no_cache"]} near-store = { path = "../../core/store" } near-primitives = { path = "../../core/primitives" } +testlib = { path = "../../test-utils/testlib" } +state-viewer = { path = "../../test-utils/state-viewer" } neard = { path = "../../neard" } rocksdb = { git = "https://github.com/nearprotocol/rust-rocksdb", branch="disable-thread" } glob = "0.3.0" walrus = "0.18.0" +near-evm-runner = { path = "../../runtime/near-evm-runner", features = ["costs_counting"], optional = true } +hex = "0.4" +ethabi = "9.0.1" +ethabi-contract = "9.0.0" +ethabi-derive = "9.0.1" +ethereum-types = "0.8.0" +lazy-static-include = "2.2.2" +num-traits = "0.2.12" [features] default = [] wasmtime = ["near-vm-logic/wasmtime_default"] lightbeam = ["wasmtime", "near-vm-runner/lightbeam"] +protocol_feature_evm = ["near-evm-runner/protocol_feature_evm", "near-vm-runner/protocol_feature_evm", "near-chain-configs/protocol_feature_evm", "near-runtime-fees/protocol_feature_evm", "node-runtime/protocol_feature_evm", "near-primitives/protocol_feature_evm", "testlib/protocol_feature_evm"] diff --git a/runtime/runtime-params-estimator/emu-cost/README.md b/runtime/runtime-params-estimator/emu-cost/README.md index d86b9e0e448..6de19f1b9ec 100644 --- a/runtime/runtime-params-estimator/emu-cost/README.md +++ b/runtime/runtime-params-estimator/emu-cost/README.md @@ -28,9 +28,10 @@ It will be mounted under `/host` in the Docker container. Start container and build estimator with: host> ./run.sh - docker> cd /host/nearcore/runtime/runtime-params-estimator - docker> cargo run --release --package neard --bin neard -- --home /tmp/data init --chain-id= --test-seed=alice.near --account-id=test.near --fast + docker> cd /host/nearcore + docker> cargo run --release --package neard --features protocol_feature_evm,nightly_protocol_features --bin neard -- --home /tmp/data init --chain-id= --test-seed=alice.near --account-id=test.near --fast docker> cargo run --release --package genesis-populate --bin genesis-populate -- --additional-accounts-num=200000 --home /tmp/data + docker> cd /host/nearcore/runtime/runtime-params-estimator docker> cargo build --release --package runtime-params-estimator Now start the estimator under QEMU with the counter plugin enabled (note, that Rust compiler produces SSE4, so specify recent CPU): diff --git a/runtime/runtime-params-estimator/src/cases.rs b/runtime/runtime-params-estimator/src/cases.rs index 810b0ba65ba..a199e7a477c 100644 --- a/runtime/runtime-params-estimator/src/cases.rs +++ b/runtime/runtime-params-estimator/src/cases.rs @@ -1,4 +1,6 @@ use num_rational::Ratio; +#[cfg(feature = "protocol_feature_evm")] +use num_traits::cast::FromPrimitive; use rand::seq::SliceRandom; use rand::{Rng, SeedableRng}; use std::cell::RefCell; @@ -14,6 +16,8 @@ use near_primitives::transaction::{ DeployContractAction, FunctionCallAction, SignedTransaction, StakeAction, TransferAction, }; +#[cfg(feature = "protocol_feature_evm")] +use crate::evm_estimator::cost_of_evm; use crate::ext_costs_generator::ExtCostsGenerator; use crate::runtime_fees_generator::RuntimeFeesGenerator; use crate::stats::Measurements; @@ -21,6 +25,7 @@ use crate::testbed::RuntimeTestbed; use crate::testbed_runners::GasMetric; use crate::testbed_runners::{get_account_id, measure_actions, measure_transactions, Config}; use crate::vm_estimator::{cost_per_op, cost_to_compile, load_and_compile}; + use near_runtime_fees::{ AccessKeyCreationConfig, ActionCreationConfig, DataReceiptCreationConfig, Fee, RuntimeFeesConfig, @@ -148,7 +153,8 @@ pub enum Metric { cpu_ram_soak_test, } -pub fn run(mut config: Config, only_compile: bool) -> RuntimeConfig { +#[allow(unused_variables)] +pub fn run(mut config: Config, only_compile: bool, only_evm: bool) -> RuntimeConfig { let mut m = Measurements::new(config.metric); if only_compile { let (contract_compile_cost, contract_compile_base_cost) = @@ -160,6 +166,25 @@ pub fn run(mut config: Config, only_compile: bool) -> RuntimeConfig { ratio_to_gas(config.metric, contract_compile_base_cost) ); process::exit(0); + } else { + #[cfg(feature = "protocol_feature_evm")] + if only_evm { + config.block_sizes = vec![100]; + let cost = cost_of_evm(&config, true); + println!( + "EVM base deploy (and init evm instance) cost: {}, deploy cost per EVM gas: {}, deploy cost per byte: {}", + ratio_to_gas(config.metric, Ratio::::from_f64(cost.deploy_cost.2).unwrap()), + ratio_to_gas(config.metric, Ratio::::from_f64(cost.deploy_cost.0).unwrap()), + ratio_to_gas(config.metric, Ratio::::from_f64(cost.deploy_cost.1).unwrap()), + ); + println!( + "EVM base function call cost: {}, function call cost per EVM gas: {}", + ratio_to_gas(config.metric, cost.funcall_cost.1), + ratio_to_gas(config.metric, cost.funcall_cost.0), + ); + + process::exit(0); + } } config.block_sizes = vec![100]; // Warmup for receipts diff --git a/runtime/runtime-params-estimator/src/evm_estimator.rs b/runtime/runtime-params-estimator/src/evm_estimator.rs new file mode 100644 index 00000000000..4860f07cb9e --- /dev/null +++ b/runtime/runtime-params-estimator/src/evm_estimator.rs @@ -0,0 +1,491 @@ +use crate::testbed::RuntimeTestbed; +use crate::testbed_runners::{end_count, get_account_id, start_count, total_transactions, Config}; +use ethabi_contract::use_contract; +use glob::glob; +use indicatif::{ProgressBar, ProgressStyle}; +use lazy_static_include::lazy_static_include_str; +use near_crypto::{InMemorySigner, KeyType}; +use near_evm_runner::EvmContext; +use near_primitives::hash::CryptoHash; +use near_primitives::transaction::{Action, FunctionCallAction, SignedTransaction}; +use near_runtime_fees::RuntimeFeesConfig; +use near_vm_logic::gas_counter::reset_evm_gas_counter; +use near_vm_logic::mocks::mock_external::MockedExternal; +use near_vm_logic::VMConfig; +use node_runtime::Runtime; +use num_rational::Ratio; +use num_traits::cast::ToPrimitive; +use rand::Rng; +use rocksdb::Env; +use std::collections::{HashMap, HashSet}; +use std::convert::TryFrom; +use std::fs; +use std::path::PathBuf; +use std::sync::{Arc, Mutex, RwLock}; +use testlib::node::{Node, RuntimeNode}; +use testlib::user::runtime_user::MockClient; + +#[derive(Debug)] +pub struct EvmCost { + pub evm_gas: u64, + pub size: u64, + pub cost: Ratio, +} + +fn testbed_for_evm( + state_dump_path: &str, + accounts: usize, +) -> (Arc>, Arc>>) { + let path = PathBuf::from(state_dump_path); + let testbed = Arc::new(Mutex::new(RuntimeTestbed::from_state_dump(&path))); + let mut nonces: HashMap = HashMap::new(); + let bar = ProgressBar::new(accounts as _); + println!("Prepare a testbed of {} accounts all having a deployed evm contract", accounts); + bar.set_style(ProgressStyle::default_bar().template( + "[elapsed {elapsed_precise} remaining {eta_precise}] Evm contracts {bar} {pos:>7}/{len:7} {msg}", + )); + let mut env = Env::default().unwrap(); + env.set_background_threads(4); + for account_idx in 0..accounts { + let account_id = get_account_id(account_idx); + let signer = InMemorySigner::from_seed(&account_id, KeyType::ED25519, &account_id); + let code = hex::decode(&TEST).unwrap(); + let nonce = *nonces.entry(account_idx).and_modify(|x| *x += 1).or_insert(1); + + let block: Vec<_> = vec![SignedTransaction::from_actions( + nonce as u64, + account_id.clone(), + "evm".to_owned(), + &signer, + vec![Action::FunctionCall(FunctionCallAction { + method_name: "deploy_code".to_string(), + args: code, + gas: 10u64.pow(18), + deposit: 0, + })], + CryptoHash::default(), + )]; + let mut testbed = testbed.lock().unwrap(); + testbed.process_block(&block, false); + testbed.process_blocks_until_no_receipts(false); + bar.inc(1); + } + bar.finish(); + reset_evm_gas_counter(); + env.set_background_threads(0); + (testbed, Arc::new(Mutex::new(nonces))) +} + +fn deploy_evm_contract( + code: &[u8], + config: &Config, + testbed: Arc>, + nonces: Arc>>, +) -> Option { + println!("{:?}. Preparing testbed. Loading state.", config.metric); + let allow_failures = false; + let mut nonces = nonces.lock().unwrap(); + let mut accounts_deployed = HashSet::new(); + + let mut f = || { + let account_idx = loop { + let x = rand::thread_rng().gen::() % config.active_accounts; + if accounts_deployed.contains(&x) { + continue; + } + break x; + }; + accounts_deployed.insert(account_idx); + let account_id = get_account_id(account_idx); + let signer = InMemorySigner::from_seed(&account_id, KeyType::ED25519, &account_id); + + let nonce = *nonces.entry(account_idx).and_modify(|x| *x += 1).or_insert(1); + SignedTransaction::from_actions( + nonce as u64, + account_id.clone(), + "evm".to_owned(), + &signer, + vec![Action::FunctionCall(FunctionCallAction { + method_name: "deploy_code".to_string(), + args: hex::decode(code).unwrap(), + gas: 10u64.pow(18), + deposit: 0, + })], + CryptoHash::default(), + ) + }; + + for _ in 0..config.warmup_iters_per_block { + for block_size in config.block_sizes.clone() { + let block: Vec<_> = (0..block_size).map(|_| f()).collect(); + let mut testbed = testbed.lock().unwrap(); + testbed.process_block(&block, allow_failures); + testbed.process_blocks_until_no_receipts(allow_failures); + } + } + reset_evm_gas_counter(); + let mut evm_gas = 0; + let mut total_cost = 0; + for _ in 0..config.iter_per_block { + for block_size in config.block_sizes.clone() { + let block: Vec<_> = (0..block_size).map(|_| f()).collect(); + let mut testbed = testbed.lock().unwrap(); + testbed.process_block(&block, allow_failures); + // process_block create action receipt for FunctionCall Action, not count as gas used in evm. + // In real node, action receipt cost is deducted in validate_tx -> tx_cost so should only count + // and deduct evm execution cost + let start = start_count(config.metric); + testbed.process_blocks_until_no_receipts(allow_failures); + let cost = end_count(config.metric, &start); + total_cost += cost; + evm_gas += reset_evm_gas_counter(); + } + } + + let counts = total_transactions(config) as u64; + evm_gas /= counts; + + Some(EvmCost { evm_gas, size: code.len() as u64, cost: Ratio::new(total_cost, counts) }) +} + +fn load_and_deploy_evm_contract( + path: &PathBuf, + config: &Config, + testbed: Arc>, + nonces: Arc>>, +) -> Option { + match fs::read(path) { + Ok(code) => deploy_evm_contract(&code, config, testbed, nonces), + _ => None, + } +} + +pub struct EvmCostCoef { + pub deploy_cost: Coef2D, + pub funcall_cost: Coef, +} + +pub fn measure_evm_deploy( + config: &Config, + verbose: bool, + testbed: Arc>, + nonces: Arc>>, +) -> Coef2D { + let globbed_files = glob("./**/*.bin").expect("Failed to read glob pattern for bin files"); + let paths = globbed_files + .filter_map(|x| match x { + Ok(p) => Some(p), + _ => None, + }) + .collect::>(); + + let measurements = paths + .iter() + .filter(|path| fs::metadata(path).is_ok()) + .map(|path| { + if verbose { + print!("Testing {}: ", path.display()); + }; + // Evm counted gas already count on size of the contract, therefore we look for cost = m*evm_gas + b. + if let Some(EvmCost { evm_gas, size, cost }) = + load_and_deploy_evm_contract(path, config, testbed.clone(), nonces.clone()) + { + if verbose { + println!("({}, {}, {}),", evm_gas, size, cost); + }; + Some(EvmCost { evm_gas, size, cost }) + } else { + if verbose { + println!("FAILED") + }; + None + } + }) + .filter(|x| x.is_some()) + .map(|x| x.unwrap()) + .collect::>(); + measurements_to_coef_2d(measurements, true) +} + +use_contract!(soltest, "../near-evm-runner/tests/build/SolTests.abi"); +use_contract!(precompiled_function, "../near-evm-runner/tests/build/PrecompiledFunction.abi"); + +lazy_static_include_str!(TEST, "../near-evm-runner/tests/build/SolTests.bin"); +lazy_static_include_str!( + PRECOMPILED_TEST, + "../near-evm-runner/tests/build/PrecompiledFunction.bin" +); + +const CHAIN_ID: u128 = 0x99; + +pub fn create_evm_context<'a>( + external: &'a mut MockedExternal, + vm_config: &'a VMConfig, + fees_config: &'a RuntimeFeesConfig, + account_id: String, + attached_deposit: u128, +) -> EvmContext<'a> { + EvmContext::new( + external, + CHAIN_ID, + vm_config, + fees_config, + 1000, + account_id.to_string(), + account_id.to_string(), + account_id.to_string(), + attached_deposit, + 0, + 10u64.pow(14), + false, + 100_000_000.into(), + ) +} + +pub fn measure_evm_funcall( + config: &Config, + verbose: bool, + testbed: Arc>, + nonces: Arc>>, +) -> Coef { + let measurements = vec![ + measure_evm_function( + config, + verbose, + |sol_test_addr| { + vec![sol_test_addr, soltest::functions::deploy_new_guy::call(8).0].concat() + }, + "deploy_new_guy(8)", + testbed.clone(), + nonces.clone(), + ), + measure_evm_function( + config, + verbose, + |sol_test_addr| { + vec![sol_test_addr, soltest::functions::pay_new_guy::call(8).0].concat() + }, + "pay_new_guy(8)", + testbed.clone(), + nonces.clone(), + ), + measure_evm_function( + config, + verbose, + |sol_test_addr| { + vec![sol_test_addr, soltest::functions::return_some_funds::call().0].concat() + }, + "return_some_funds()", + testbed.clone(), + nonces.clone(), + ), + measure_evm_function( + config, + verbose, + |sol_test_addr| vec![sol_test_addr, soltest::functions::emit_it::call(8).0].concat(), + "emit_it(8)", + testbed.clone(), + nonces.clone(), + ), + ]; + println!("{:?}", measurements); + measurements_to_coef(measurements, true) +} + +pub fn measure_evm_function) -> Vec + Copy>( + config: &Config, + verbose: bool, + args_encoder: F, + test_name: &str, + testbed: Arc>, + nonces: Arc>>, +) -> EvmCost { + println!("{:?}. Preparing testbed. Loading state.", config.metric); + let allow_failures = false; + let mut nonces = nonces.lock().unwrap(); + let mut accounts_deployed = HashSet::new(); + let code = hex::decode(&TEST).unwrap(); + + let mut f = || { + let account_idx = loop { + let x = rand::thread_rng().gen::() % config.active_accounts; + if accounts_deployed.contains(&x) { + continue; + } + break x; + }; + accounts_deployed.insert(account_idx); + let account_id = get_account_id(account_idx); + let signer = InMemorySigner::from_seed(&account_id, KeyType::ED25519, &account_id); + + let mut testbed = testbed.lock().unwrap(); + let runtime_node = RuntimeNode { + signer: Arc::new(signer.clone()), + client: Arc::new(RwLock::new(MockClient { + runtime: Runtime::new(), + runtime_config: testbed.genesis.config.runtime_config.clone(), + tries: testbed.tries.clone(), + state_root: testbed.root, + epoch_length: testbed.genesis.config.epoch_length, + })), + genesis: testbed.genesis.clone(), + }; + let node_user = runtime_node.user(); + let _nonce = *nonces.entry(account_idx).and_modify(|x| *x += 1).or_insert(1); + let addr = node_user + .function_call( + account_id.clone(), + "evm".to_string(), + "deploy_code", + code.clone(), + 10u64.pow(14), + 10, + ) + .unwrap() + .status + .as_success_decoded() + .unwrap(); + + testbed.tries = runtime_node.client.read().unwrap().tries.clone(); + testbed.root = runtime_node.client.read().unwrap().state_root; + testbed.runtime = Runtime::new(); + + let nonce = *nonces.entry(account_idx).and_modify(|x| *x += 1).or_insert(1); + SignedTransaction::from_actions( + nonce as u64, + account_id.clone(), + "evm".to_owned(), + &signer, + vec![Action::FunctionCall(FunctionCallAction { + method_name: "call_function".to_string(), + args: args_encoder(addr), + gas: 10u64.pow(18), + deposit: 0, + })], + CryptoHash::default(), + ) + }; + + for _ in 0..config.warmup_iters_per_block { + for block_size in config.block_sizes.clone() { + let block: Vec<_> = (0..block_size).map(|_| f()).collect(); + let mut testbed = testbed.lock().unwrap(); + testbed.process_block(&block, allow_failures); + testbed.process_blocks_until_no_receipts(allow_failures); + } + } + reset_evm_gas_counter(); + let mut evm_gas = 0; + let mut total_cost = 0; + for _ in 0..config.iter_per_block { + for block_size in config.block_sizes.clone() { + let block: Vec<_> = (0..block_size).map(|_| f()).collect(); + let mut testbed = testbed.lock().unwrap(); + testbed.process_block(&block, allow_failures); + let start = start_count(config.metric); + testbed.process_blocks_until_no_receipts(allow_failures); + let cost = end_count(config.metric, &start); + total_cost += cost; + evm_gas += reset_evm_gas_counter(); + } + } + + let counts = total_transactions(config) as u64; + evm_gas /= counts; + + let cost = Ratio::new(total_cost, counts); + if verbose { + println!("Testing call {}: ({}, {})", test_name, evm_gas, cost); + } + EvmCost { evm_gas, size: 0, cost } +} + +pub fn near_cost_to_evm_gas(funcall_cost: Coef, cost: Ratio) -> u64 { + return u64::try_from((cost / funcall_cost.0).to_integer()).unwrap(); +} + +/// Cost of all evm related +pub fn cost_of_evm(config: &Config, verbose: bool) -> EvmCostCoef { + let (testbed, nonces) = testbed_for_evm(&config.state_dump_path, config.active_accounts); + let evm_cost_config = EvmCostCoef { + deploy_cost: measure_evm_deploy(config, verbose, testbed.clone(), nonces.clone()), + funcall_cost: measure_evm_funcall(config, verbose, testbed.clone(), nonces.clone()), + }; + evm_cost_config +} + +fn measurements_to_coef_2d(measurements: Vec, verbose: bool) -> Coef2D { + let v1: Vec<_> = measurements.iter().map(|m| m.evm_gas as f64).collect(); + let (v1, _) = normalize(&v1); + let v2: Vec<_> = measurements.iter().map(|m| m.size as f64).collect(); + let (v2, _) = normalize(&v2); + let a = dot(&v1, &v1); + let b = dot(&v1, &v2); + let c = dot(&v2, &v1); + let d = dot(&v2, &v2); + + let xt_x_inverse = inverse2x2(Matrix2x2 { a, b, c, d }); + + let y: Vec<_> = measurements.iter().map(|m| m.cost.to_f64().unwrap()).collect(); + let xt_y1 = dot(&v1, &y); + let xt_y2 = dot(&v2, &y); + + let beta1 = xt_x_inverse.a * xt_y1 + xt_x_inverse.b * xt_y2; + let beta2 = xt_x_inverse.c * xt_y1 + xt_x_inverse.d * xt_y2; + + let delta: Vec<_> = measurements + .iter() + .map(|m| m.cost.to_f64().unwrap() - (m.evm_gas as f64) * beta1 - (m.size as f64) * beta2) + .collect(); + let r = (beta1, beta2, delta.iter().sum::() / delta.len() as f64); + if verbose { + println!("evm calc data {:?}", r); + println!("delta: {:?}", delta); + } + r +} + +fn measurements_to_coef(measurements: Vec, verbose: bool) -> Coef { + let ratio = Ratio::new(0 as u64, 1); + let base = Ratio::new(u64::MAX, 1); + let b = measurements.iter().fold(base, |b, EvmCost { evm_gas: _, size: _, cost }| b.min(*cost)); + let m = measurements + .iter() + .fold(ratio, |r, EvmCost { evm_gas, size: _, cost }| r.max((*cost - b) / evm_gas)); + if verbose { + println!("raw data: ({},{})", m, b); + } + (m, b) +} + +type Coef = (Ratio, Ratio); + +type Coef2D = (f64, f64, f64); + +struct Matrix2x2 { + a: f64, + b: f64, + c: f64, + d: f64, +} + +fn dot(v1: &Vec, v2: &Vec) -> f64 { + let mut ret = 0.0; + for (i, u) in v1.iter().enumerate() { + ret += u * v2[i]; + } + ret +} +fn inverse2x2(m: Matrix2x2) -> Matrix2x2 { + let Matrix2x2 { a, b, c, d } = m; + let delta = a * d - b * c; + Matrix2x2 { a: d / delta, b: -b / delta, c: -c / delta, d: a / delta } +} + +fn normalize(v: &Vec) -> (Vec, f64) { + let mean = v.iter().sum::() / (v.len() as f64); + // default sklearn LinearRegression only normalize mean to 0, but not normalize stddev to 1, and that gives a very good result. + + let v: Vec<_> = v.iter().map(|x| (*x - mean)).collect(); + (v, mean) +} diff --git a/runtime/runtime-params-estimator/src/lib.rs b/runtime/runtime-params-estimator/src/lib.rs index 40ad7766c48..b1ea8a22e7f 100644 --- a/runtime/runtime-params-estimator/src/lib.rs +++ b/runtime/runtime-params-estimator/src/lib.rs @@ -7,6 +7,8 @@ pub mod runtime_fees_generator; // Generates external costs from the measurements. pub mod ext_costs_generator; // Runs a VM (Default: Wasmer) on the given contract and measures the time it takes to do a single operation. +#[cfg(feature = "protocol_feature_evm")] +pub mod evm_estimator; pub mod vm_estimator; // Collects and processes stats. Prints them on display, plots them, writes them into a file. pub mod stats; diff --git a/runtime/runtime-params-estimator/src/main.rs b/runtime/runtime-params-estimator/src/main.rs index 4ff7df436d2..0d5d3aa60e6 100644 --- a/runtime/runtime-params-estimator/src/main.rs +++ b/runtime/runtime-params-estimator/src/main.rs @@ -71,6 +71,7 @@ fn main() { .long("transaction") .help("Disables transaction measurements"), ) + .arg(Arg::with_name("evm-only").long("evm-only").help("only test evm related cost")) .get_matches(); let state_dump_path = matches.value_of("home").unwrap().to_string(); @@ -102,6 +103,7 @@ fn main() { disable_measure_transaction, }, matches.is_present("compile-only"), + matches.is_present("evm-only"), ); println!("Generated RuntimeConfig:"); diff --git a/runtime/runtime-params-estimator/src/testbed.rs b/runtime/runtime-params-estimator/src/testbed.rs index d90b682a99e..4766b2c4a37 100644 --- a/runtime/runtime-params-estimator/src/testbed.rs +++ b/runtime/runtime-params-estimator/src/testbed.rs @@ -4,6 +4,7 @@ use std::path::Path; use borsh::BorshDeserialize; +use near_chain_configs::Genesis; use near_primitives::receipt::Receipt; use near_primitives::test_utils::MockEpochInfoProvider; use near_primitives::transaction::{ExecutionStatus, SignedTransaction}; @@ -23,9 +24,10 @@ pub struct RuntimeTestbed { /// Directory where we temporarily keep the storage. #[allow(dead_code)] workdir: tempfile::TempDir, - tries: ShardTries, - root: MerkleHash, - runtime: Runtime, + pub tries: ShardTries, + pub root: MerkleHash, + pub runtime: Runtime, + pub genesis: Genesis, prev_receipts: Vec, apply_state: ApplyState, epoch_info_provider: MockEpochInfoProvider, @@ -39,6 +41,7 @@ impl RuntimeTestbed { let store = create_store(&get_store_path(workdir.path())); let tries = ShardTries::new(store.clone(), 1); + let genesis = Genesis::from_file(dump_dir.join("genesis.json")); let mut state_file = dump_dir.to_path_buf(); state_file.push(STATE_DUMP_FILE); store.load_from_file(ColState, state_file.as_path()).expect("Failed to read state dump"); @@ -89,6 +92,8 @@ impl RuntimeTestbed { current_protocol_version: PROTOCOL_VERSION, config: Arc::new(runtime_config), cache: Some(Arc::new(StoreCompiledContractCache { store: tries.get_store() })), + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: near_chain_configs::TEST_EVM_CHAIN_ID, }; Self { workdir, @@ -98,6 +103,7 @@ impl RuntimeTestbed { prev_receipts, apply_state, epoch_info_provider: MockEpochInfoProvider::default(), + genesis, } } diff --git a/runtime/runtime-params-estimator/src/testbed_runners.rs b/runtime/runtime-params-estimator/src/testbed_runners.rs index 67fa26e2afc..c4c40958cf7 100644 --- a/runtime/runtime-params-estimator/src/testbed_runners.rs +++ b/runtime/runtime-params-estimator/src/testbed_runners.rs @@ -18,7 +18,7 @@ pub fn get_account_id(account_index: usize) -> String { } /// Total number of transactions that we need to prepare. -fn total_transactions(config: &Config) -> usize { +pub fn total_transactions(config: &Config) -> usize { config.block_sizes.iter().sum::() * config.iter_per_block } diff --git a/runtime/runtime-params-estimator/src/vm_estimator.rs b/runtime/runtime-params-estimator/src/vm_estimator.rs index 29102dd66f2..9e8f1dd2877 100644 --- a/runtime/runtime-params-estimator/src/vm_estimator.rs +++ b/runtime/runtime-params-estimator/src/vm_estimator.rs @@ -1,6 +1,4 @@ -use crate::testbed_runners::end_count; -use crate::testbed_runners::start_count; -use crate::testbed_runners::GasMetric; +use crate::testbed_runners::{end_count, start_count, GasMetric}; use glob::glob; use near_primitives::version::PROTOCOL_VERSION; use near_runtime_fees::RuntimeFeesConfig; @@ -161,12 +159,13 @@ pub fn cost_to_compile( "About to compile {}", match vm_kind { VMKind::Wasmer => "wasmer", - VMKind::Wasmtime => + VMKind::Wasmtime => { if USING_LIGHTBEAM { "wasmtime-lightbeam" } else { "wasmtime" - }, + } + } } ); }; @@ -175,7 +174,7 @@ pub fn cost_to_compile( .filter(|path| fs::metadata(path).is_ok()) .map(|path| { if verbose { - print!("Testing {}: ", path.display()); + print!("Testing deploy {}: ", path.display()); }; if let Some((size, cost)) = load_and_compile(path, gas_metric, vm_kind) { if verbose { diff --git a/runtime/runtime-standalone/Cargo.toml b/runtime/runtime-standalone/Cargo.toml index dbc3001a825..f265f1abed5 100644 --- a/runtime/runtime-standalone/Cargo.toml +++ b/runtime/runtime-standalone/Cargo.toml @@ -15,4 +15,5 @@ node-runtime = { path = "../runtime" } [features] default = [] +protocol_feature_evm = ["near-primitives/protocol_feature_evm", "node-runtime/protocol_feature_evm"] no_cache = ["near-store/no_cache", "node-runtime/no_cache"] diff --git a/runtime/runtime-standalone/src/lib.rs b/runtime/runtime-standalone/src/lib.rs index e043c6debed..c6e30a697a5 100644 --- a/runtime/runtime-standalone/src/lib.rs +++ b/runtime/runtime-standalone/src/lib.rs @@ -26,6 +26,10 @@ use node_runtime::{state_viewer::TrieViewer, ApplyState, Runtime}; const DEFAULT_EPOCH_LENGTH: u64 = 3; +#[cfg(feature = "protocol_feature_evm")] +/// See https://github.com/ethereum-lists/chains/blob/master/_data/chains/1313161555.json +const CHAIN_ID: u128 = 1313161555; + pub fn init_runtime_and_signer(root_account_id: &AccountId) -> (RuntimeStandalone, InMemorySigner) { let mut genesis = GenesisConfig::default(); let signer = genesis.init_root_signer(root_account_id); @@ -229,6 +233,8 @@ impl RuntimeStandalone { config: self.runtime_config.clone(), // TODO: shall we use compiled contracts cache in standalone runtime? cache: None, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: CHAIN_ID, }; let apply_result = self.runtime.apply( @@ -262,7 +268,6 @@ impl RuntimeStandalone { /// assert_eq!(runtime.current_block().block_height, 5); /// assert_eq!(runtime.current_block().epoch_height, 1); ///``` - pub fn produce_blocks(&mut self, num_of_blocks: u64) -> Result<(), RuntimeError> { for _ in 0..num_of_blocks { self.produce_block()?; @@ -312,11 +317,13 @@ impl RuntimeStandalone { block_timestamp: self.cur_block.block_timestamp, current_protocol_version: PROTOCOL_VERSION, cache: Some(Arc::new(StoreCompiledContractCache { store: self.tries.get_store() })), + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: CHAIN_ID, }; let mut logs = vec![]; let result = viewer.call_function( trie_update, - &view_state, + view_state, account_id, method_name, args, diff --git a/runtime/runtime/Cargo.toml b/runtime/runtime/Cargo.toml index 37ccc948be6..40501450e8b 100644 --- a/runtime/runtime/Cargo.toml +++ b/runtime/runtime/Cargo.toml @@ -16,6 +16,7 @@ num-rational = "0.2.4" num-bigint = "0.2.6" num-traits = "0.2.11" hex = "0.4.2" +ethereum-types = "0.8.0" borsh = "0.7.1" @@ -29,10 +30,12 @@ near-runtime-utils = { path = "../../runtime/near-runtime-utils" } near-vm-logic = { path = "../../runtime/near-vm-logic" } near-vm-runner = { path = "../../runtime/near-vm-runner" } near-vm-errors = { path = "../../runtime/near-vm-errors" } +near-evm-runner = { path = "../../runtime/near-evm-runner", optional = true } [features] default = [] dump_errors_schema = ["near-vm-errors/dump_errors_schema"] +protocol_feature_evm = ["near-evm-runner/protocol_feature_evm", "near-primitives/protocol_feature_evm", "near-runtime-fees/protocol_feature_evm", "near-vm-runner/protocol_feature_evm"] # Use this feature to enable counting of fees and costs applied. costs_counting = ["near-vm-logic/costs_counting", "near-vm-runner/costs_counting"] @@ -49,3 +52,4 @@ rayon = "^1.1" assert_matches = "1.3" testlib = { path = "../../test-utils/testlib" } +near-chain-configs = { path = "../../core/chain-configs" } diff --git a/runtime/runtime/src/actions.rs b/runtime/runtime/src/actions.rs index 0d6a0c6b148..89f20916c36 100644 --- a/runtime/runtime/src/actions.rs +++ b/runtime/runtime/src/actions.rs @@ -1,10 +1,10 @@ -use std::sync::Arc; - use borsh::{BorshDeserialize, BorshSerialize}; -use log::debug; +use near_crypto::PublicKey; use near_primitives::account::{AccessKey, AccessKeyPermission, Account}; +use near_primitives::checked_feature; use near_primitives::contract::ContractCode; +use near_primitives::errors::{ActionError, ActionErrorKind, ExternalError, RuntimeError}; use near_primitives::hash::CryptoHash; use near_primitives::receipt::{ActionReceipt, Receipt}; use near_primitives::transaction::{ @@ -12,40 +12,138 @@ use near_primitives::transaction::{ FunctionCallAction, StakeAction, TransferAction, }; use near_primitives::types::{AccountId, EpochInfoProvider, ValidatorStake}; -use near_primitives::utils::{ - create_random_seed, is_valid_account_id, is_valid_sub_account_id, is_valid_top_level_account_id, +use near_primitives::utils::create_random_seed; +use near_primitives::version::{ + ProtocolVersion, DELETE_KEY_STORAGE_USAGE_PROTOCOL_VERSION, + IMPLICIT_ACCOUNT_CREATION_PROTOCOL_VERSION, }; +use near_runtime_configs::AccountCreationConfig; use near_runtime_fees::RuntimeFeesConfig; -use near_runtime_utils::is_account_id_64_len_hex; +use near_runtime_utils::{ + is_account_evm, is_account_id_64_len_hex, is_valid_account_id, is_valid_sub_account_id, + is_valid_top_level_account_id, +}; use near_store::{ get_access_key, get_code, remove_access_key, remove_account, set_access_key, set_code, StorageError, TrieUpdate, }; +use near_vm_errors::{CacheError, CompilationError, FunctionCallError, InconsistentStateError}; use near_vm_logic::types::PromiseResult; -use near_vm_logic::VMContext; +use near_vm_logic::{VMContext, VMOutcome}; +use near_vm_runner::VMError; use crate::config::{safe_add_gas, RuntimeConfig}; use crate::ext::RuntimeExt; use crate::{ActionResult, ApplyState}; -use near_crypto::PublicKey; -use near_primitives::errors::{ActionError, ActionErrorKind, ExternalError, RuntimeError}; -use near_primitives::version::{ - ProtocolVersion, DELETE_KEY_STORAGE_USAGE_PROTOCOL_VERSION, - IMPLICIT_ACCOUNT_CREATION_PROTOCOL_VERSION, -}; -use near_runtime_configs::AccountCreationConfig; -use near_vm_errors::{CacheError, CompilationError, FunctionCallError}; -use near_vm_runner::VMError; -pub(crate) fn get_code_with_cache( - state_update: &TrieUpdate, - account_id: &AccountId, - account: &Account, -) -> Result>, StorageError> { - debug!(target:"runtime", "Calling the contract at account {}", account_id); - let code_hash = account.code_hash; - let code = || get_code(state_update, account_id, Some(code_hash)); - crate::cache::get_code(code_hash, code) +/// Runs given function call with given context / apply state. +/// Precompiles: +/// - 0x1: EVM interpreter; +pub(crate) fn execute_function_call( + apply_state: &ApplyState, + runtime_ext: &mut RuntimeExt, + account: &mut Account, + predecessor_id: &AccountId, + action_receipt: &ActionReceipt, + promise_results: &[PromiseResult], + function_call: &FunctionCallAction, + action_hash: &CryptoHash, + config: &RuntimeConfig, + is_last_action: bool, + is_view: bool, +) -> (Option, Option) { + let account_id = runtime_ext.account_id(); + if checked_feature!("protocol_feature_evm", EVM, runtime_ext.protocol_version()) + && is_account_evm(&account_id) + { + #[cfg(not(feature = "protocol_feature_evm"))] + unreachable!(); + #[cfg(feature = "protocol_feature_evm")] + near_evm_runner::run_evm( + runtime_ext, + apply_state.evm_chain_id, + &config.wasm_config, + &config.transaction_costs, + &account_id, + &action_receipt.signer_id, + predecessor_id, + account.amount, + function_call.deposit, + account.storage_usage, + function_call.method_name.clone(), + function_call.args.clone(), + function_call.gas, + is_view, + ) + } else { + let cache = match &apply_state.cache { + Some(cache) => Some((*cache).as_ref()), + None => None, + }; + let code = match runtime_ext.get_code(account.code_hash) { + Ok(Some(code)) => code, + Ok(None) => { + let error = + FunctionCallError::CompilationError(CompilationError::CodeDoesNotExist { + account_id: account_id.clone(), + }); + return (None, Some(VMError::FunctionCallError(error))); + } + Err(e) => { + return ( + None, + Some(VMError::InconsistentStateError(InconsistentStateError::StorageError( + e.to_string(), + ))), + ); + } + }; + // Output data receipts are ignored if the function call is not the last action in the batch. + let output_data_receivers: Vec<_> = if is_last_action { + action_receipt.output_data_receivers.iter().map(|r| r.receiver_id.clone()).collect() + } else { + vec![] + }; + let random_seed = create_random_seed( + apply_state.current_protocol_version, + *action_hash, + apply_state.random_seed, + ); + let context = VMContext { + current_account_id: runtime_ext.account_id().clone(), + signer_account_id: action_receipt.signer_id.clone(), + signer_account_pk: action_receipt + .signer_public_key + .try_to_vec() + .expect("Failed to serialize"), + predecessor_account_id: predecessor_id.clone(), + input: function_call.args.clone(), + block_index: apply_state.block_index, + block_timestamp: apply_state.block_timestamp, + epoch_height: apply_state.epoch_height, + account_balance: account.amount, + account_locked_balance: account.locked, + storage_usage: account.storage_usage, + attached_deposit: function_call.deposit, + prepaid_gas: function_call.gas, + random_seed, + is_view, + output_data_receivers, + }; + + near_vm_runner::run( + code.hash.as_ref().to_vec(), + &code.code, + function_call.method_name.as_bytes(), + runtime_ext, + context, + &config.wasm_config, + &config.transaction_costs, + promise_results, + apply_state.current_protocol_version, + cache, + ) + } } pub(crate) fn action_function_call( @@ -63,32 +161,12 @@ pub(crate) fn action_function_call( is_last_action: bool, epoch_info_provider: &dyn EpochInfoProvider, ) -> Result<(), RuntimeError> { - // TODO: maybe we don't need it in such a way. - let cache = match &apply_state.cache { - Some(cache) => Some((*cache).as_ref()), - None => None, - }; - let code = match get_code_with_cache(state_update, account_id, &account) { - Ok(Some(code)) => code, - Ok(None) => { - let error = FunctionCallError::CompilationError(CompilationError::CodeDoesNotExist { - account_id: account_id.clone(), - }); - result.result = Err(ActionErrorKind::FunctionCallError(error).into()); - return Ok(()); - } - Err(e) => { - return Err(e.into()); - } - }; - if account.amount.checked_add(function_call.deposit).is_none() { return Err(StorageError::StorageInconsistentState( "Account balance integer overflow during function call deposit".to_string(), ) .into()); } - let mut runtime_ext = RuntimeExt::new( state_update, account_id, @@ -101,51 +179,18 @@ pub(crate) fn action_function_call( epoch_info_provider, apply_state.current_protocol_version, ); - // Output data receipts are ignored if the function call is not the last action in the batch. - let output_data_receivers: Vec<_> = if is_last_action { - action_receipt.output_data_receivers.iter().map(|r| r.receiver_id.clone()).collect() - } else { - vec![] - }; - let random_seed = create_random_seed( - apply_state.current_protocol_version, - *action_hash, - apply_state.random_seed, - ); - - let context = VMContext { - current_account_id: account_id.clone(), - signer_account_id: action_receipt.signer_id.clone(), - signer_account_pk: action_receipt - .signer_public_key - .try_to_vec() - .expect("Failed to serialize"), - predecessor_account_id: receipt.predecessor_id.clone(), - input: function_call.args.clone(), - block_index: apply_state.block_index, - block_timestamp: apply_state.block_timestamp, - epoch_height: apply_state.epoch_height, - account_balance: account.amount, - account_locked_balance: account.locked, - storage_usage: account.storage_usage, - attached_deposit: function_call.deposit, - prepaid_gas: function_call.gas, - random_seed, - is_view: false, - output_data_receivers, - }; - - let (outcome, err) = near_vm_runner::run( - code.hash.as_ref().to_vec(), - &code.code, - function_call.method_name.as_bytes(), + let (outcome, err) = execute_function_call( + apply_state, &mut runtime_ext, - context, - &config.wasm_config, - &config.transaction_costs, + account, + &receipt.predecessor_id, + action_receipt, promise_results, - apply_state.current_protocol_version, - cache, + function_call, + action_hash, + config, + is_last_action, + false, ); let execution_succeeded = match err { Some(VMError::FunctionCallError(err)) => { diff --git a/runtime/runtime/src/adapter.rs b/runtime/runtime/src/adapter.rs index bdce1a91dbd..eb3f4af4808 100644 --- a/runtime/runtime/src/adapter.rs +++ b/runtime/runtime/src/adapter.rs @@ -31,6 +31,7 @@ pub trait ViewRuntimeAdapter { logs: &mut Vec, epoch_info_provider: &dyn EpochInfoProvider, current_protocol_version: ProtocolVersion, + #[cfg(feature = "protocol_feature_evm")] evm_chain_id: u128, ) -> Result, Box>; fn view_access_key( diff --git a/runtime/runtime/src/ext.rs b/runtime/runtime/src/ext.rs index 5cffc35f3b8..ac28e0b207d 100644 --- a/runtime/runtime/src/ext.rs +++ b/runtime/runtime/src/ext.rs @@ -1,6 +1,11 @@ +use std::sync::Arc; + use borsh::BorshDeserialize; +use log::debug; + use near_crypto::PublicKey; use near_primitives::account::{AccessKey, AccessKeyPermission, FunctionCallPermission}; +use near_primitives::contract::ContractCode; use near_primitives::errors::{ExternalError, StorageError}; use near_primitives::hash::CryptoHash; use near_primitives::receipt::{ActionReceipt, DataReceiver, Receipt, ReceiptEnum}; @@ -8,11 +13,12 @@ use near_primitives::transaction::{ Action, AddKeyAction, CreateAccountAction, DeleteAccountAction, DeleteKeyAction, DeployContractAction, FunctionCallAction, StakeAction, TransferAction, }; -use near_primitives::trie_key::TrieKey; +use near_primitives::trie_key::{trie_key_parsers, TrieKey}; use near_primitives::types::{AccountId, Balance, EpochId, EpochInfoProvider}; use near_primitives::utils::create_data_id; use near_primitives::version::ProtocolVersion; -use near_store::{TrieUpdate, TrieUpdateValuePtr}; +use near_store::{get_code, TrieUpdate, TrieUpdateValuePtr}; +use near_vm_errors::InconsistentStateError; use near_vm_logic::{External, HostError, VMLogicError, ValuePtr}; pub struct RuntimeExt<'a> { @@ -71,6 +77,20 @@ impl<'a> RuntimeExt<'a> { } } + #[inline] + pub fn account_id(&self) -> &'a AccountId { + self.account_id + } + + pub fn get_code( + &self, + code_hash: CryptoHash, + ) -> Result>, StorageError> { + debug!(target:"runtime", "Calling the contract at account {}", self.account_id); + let code = || get_code(self.trie_update, self.account_id, Some(code_hash)); + crate::cache::get_code(code_hash, code) + } + pub fn create_storage_key(&self, key: &[u8]) -> TrieKey { TrieKey::ContractData { account_id: self.account_id.clone(), key: key.to_vec() } } @@ -106,6 +126,11 @@ impl<'a> RuntimeExt<'a> { .actions .push(action); } + + #[inline] + pub fn protocol_version(&self) -> ProtocolVersion { + self.current_protocol_version + } } fn wrap_storage_error(error: StorageError) -> VMLogicError { @@ -143,6 +168,37 @@ impl<'a> External for RuntimeExt<'a> { self.trie_update.get_ref(&storage_key).map(|x| x.is_some()).map_err(wrap_storage_error) } + fn storage_remove_subtree(&mut self, prefix: &[u8]) -> ExtResult<()> { + let data_keys = self + .trie_update + .iter(&trie_key_parsers::get_raw_prefix_for_contract_data(&self.account_id, prefix)) + .map_err(|err| { + VMLogicError::InconsistentStateError(InconsistentStateError::StorageError( + err.to_string(), + )) + })? + .map(|raw_key| { + trie_key_parsers::parse_data_key_from_contract_data_key(&raw_key?, self.account_id) + .map_err(|_e| { + StorageError::StorageInconsistentState( + "Can't parse data key from raw key for ContractData".to_string(), + ) + }) + .map(Vec::from) + }) + .collect::, _>>() + .map_err(|err| { + VMLogicError::InconsistentStateError(InconsistentStateError::StorageError( + err.to_string(), + )) + })?; + for key in data_keys { + self.trie_update + .remove(TrieKey::ContractData { account_id: self.account_id.clone(), key }); + } + Ok(()) + } + fn create_receipt(&mut self, receipt_indices: Vec, receiver_id: String) -> ExtResult { let mut input_data_ids = vec![]; for receipt_index in receipt_indices { diff --git a/runtime/runtime/src/lib.rs b/runtime/runtime/src/lib.rs index 105c2eebd0b..8bd9e119aac 100644 --- a/runtime/runtime/src/lib.rs +++ b/runtime/runtime/src/lib.rs @@ -89,6 +89,9 @@ pub struct ApplyState { pub config: Arc, /// Cache for compiled contracts. pub cache: Option>, + /// Ethereum chain id. + #[cfg(feature = "protocol_feature_evm")] + pub evm_chain_id: u128, } /// Contains information to update validators accounts at the first block of a new epoch. @@ -304,6 +307,7 @@ impl Runtime { actions: &[Action], epoch_info_provider: &dyn EpochInfoProvider, ) -> Result { + // println!("enter apply_action"); let mut result = ActionResult::default(); let exec_fees = exec_fee( &apply_state.config.transaction_costs, @@ -1536,6 +1540,8 @@ mod tests { current_protocol_version: PROTOCOL_VERSION, config: Arc::new(RuntimeConfig::default()), cache: Some(Arc::new(StoreCompiledContractCache { store: tries.get_store() })), + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: near_chain_configs::TEST_EVM_CHAIN_ID, }; (runtime, tries, root, apply_state, signer, MockEpochInfoProvider::default()) diff --git a/runtime/runtime/src/state_viewer.rs b/runtime/runtime/src/state_viewer.rs index 0883f0f210e..69c1f95dd74 100644 --- a/runtime/runtime/src/state_viewer.rs +++ b/runtime/runtime/src/state_viewer.rs @@ -1,23 +1,26 @@ use std::str; use std::time::Instant; -use borsh::BorshSerialize; use log::debug; use near_crypto::{KeyType, PublicKey}; use near_primitives::account::{AccessKey, Account}; use near_primitives::hash::CryptoHash; +use near_primitives::receipt::ActionReceipt; use near_primitives::serialize::to_base64; +use near_primitives::transaction::FunctionCallAction; use near_primitives::trie_key::trie_key_parsers; use near_primitives::types::{AccountId, EpochInfoProvider}; -use near_primitives::utils::is_valid_account_id; use near_primitives::views::{StateItem, ViewApplyState, ViewStateResult}; -use near_runtime_fees::RuntimeFeesConfig; +use near_runtime_configs::RuntimeConfig; +use near_runtime_utils::is_valid_account_id; use near_store::{get_access_key, get_account, TrieUpdate}; -use near_vm_logic::{ReturnData, VMConfig, VMContext}; +use near_vm_logic::ReturnData; -use crate::actions::get_code_with_cache; +use crate::actions::execute_function_call; use crate::ext::RuntimeExt; +use crate::ApplyState; +use std::sync::Arc; pub struct TrieViewer {} @@ -85,7 +88,7 @@ impl TrieViewer { pub fn call_function( &self, mut state_update: TrieUpdate, - view_state: &ViewApplyState, + view_state: ViewApplyState, contract_id: &AccountId, method_name: &str, args: &[u8], @@ -97,62 +100,67 @@ impl TrieViewer { return Err(format!("Contract ID {:?} is not valid", contract_id).into()); } let root = state_update.get_root(); - let account = get_account(&state_update, contract_id)? + let mut account = get_account(&state_update, contract_id)? .ok_or_else(|| format!("Account {:?} doesn't exist", contract_id))?; - let code = get_code_with_cache(&state_update, contract_id, &account)?.ok_or_else(|| { - format!("cannot find contract code for account {}", contract_id.clone()) - })?; // TODO(#1015): Add ability to pass public key and originator_id let originator_id = contract_id; let public_key = PublicKey::empty(KeyType::ED25519); - let cache = view_state.cache.as_deref(); - let (outcome, err) = { - let empty_hash = CryptoHash::default(); - let mut runtime_ext = RuntimeExt::new( - &mut state_update, - contract_id, - originator_id, - &public_key, - 0, - &empty_hash, - &view_state.epoch_id, - &view_state.last_block_hash, - epoch_info_provider, - view_state.current_protocol_version, - ); - - let context = VMContext { - current_account_id: contract_id.clone(), - signer_account_id: originator_id.clone(), - signer_account_pk: public_key.try_to_vec().expect("Failed to serialize"), - predecessor_account_id: originator_id.clone(), - input: args.to_owned(), - block_index: view_state.block_height, - block_timestamp: view_state.block_timestamp, - epoch_height: view_state.epoch_height, - account_balance: account.amount, - account_locked_balance: account.locked, - storage_usage: account.storage_usage, - attached_deposit: 0, - prepaid_gas: 0, - random_seed: root.as_ref().into(), - is_view: true, - output_data_receivers: vec![], - }; - - near_vm_runner::run( - code.hash.as_ref().to_vec(), - &code.code, - method_name.as_bytes(), - &mut runtime_ext, - context, - &VMConfig::default(), - &RuntimeFeesConfig::default(), - &[], - view_state.current_protocol_version, - cache, - ) + let empty_hash = CryptoHash::default(); + let mut runtime_ext = RuntimeExt::new( + &mut state_update, + contract_id, + originator_id, + &public_key, + 0, + &empty_hash, + &view_state.epoch_id, + &view_state.last_block_hash, + epoch_info_provider, + view_state.current_protocol_version, + ); + let config = Arc::new(RuntimeConfig::default()); + let apply_state = ApplyState { + block_index: view_state.block_height, + last_block_hash: view_state.last_block_hash, + epoch_id: view_state.epoch_id.clone(), + epoch_height: view_state.epoch_height, + gas_price: 0, + block_timestamp: view_state.block_timestamp, + gas_limit: None, + random_seed: root, + current_protocol_version: view_state.current_protocol_version, + config: config.clone(), + cache: view_state.cache, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: view_state.evm_chain_id, }; + let action_receipt = ActionReceipt { + signer_id: originator_id.clone(), + signer_public_key: public_key.clone(), + gas_price: 0, + output_data_receivers: vec![], + input_data_ids: vec![], + actions: vec![], + }; + let function_call = FunctionCallAction { + method_name: method_name.to_string(), + args: args.to_vec(), + gas: config.wasm_config.limit_config.max_gas_burnt_view, + deposit: 0, + }; + let (outcome, err) = execute_function_call( + &apply_state, + &mut runtime_ext, + &mut account, + &originator_id, + &action_receipt, + &[], + &function_call, + &empty_hash, + &config, + true, + true, + ); let elapsed = now.elapsed(); let time_ms = (elapsed.as_secs() as f64 / 1_000.0) + f64::from(elapsed.subsec_nanos()) / 1_000_000.0; @@ -180,14 +188,14 @@ impl TrieViewer { #[cfg(test)] mod tests { - use crate::state_viewer::TrieViewer; - use crate::AccountId; - use near_primitives::hash::CryptoHash; + use super::*; + + #[cfg(feature = "protocol_feature_evm")] + use near_chain_configs::TEST_EVM_CHAIN_ID; use near_primitives::test_utils::MockEpochInfoProvider; use near_primitives::trie_key::TrieKey; use near_primitives::types::{EpochId, StateChangeCause}; use near_primitives::version::PROTOCOL_VERSION; - use near_primitives::views::{StateItem, ViewApplyState}; use testlib::runtime_utils::{ alice_account, encode_int, get_runtime_and_trie, get_test_trie_viewer, }; @@ -205,10 +213,12 @@ mod tests { block_timestamp: 1, current_protocol_version: PROTOCOL_VERSION, cache: None, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: TEST_EVM_CHAIN_ID, }; let result = viewer.call_function( root, - &view_state, + view_state, &AccountId::from("test.contract"), "run_test", &[], @@ -232,10 +242,12 @@ mod tests { block_timestamp: 1, current_protocol_version: PROTOCOL_VERSION, cache: None, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: TEST_EVM_CHAIN_ID, }; let result = viewer.call_function( root, - &view_state, + view_state, &"bad!contract".to_string(), "run_test", &[], @@ -263,10 +275,12 @@ mod tests { block_timestamp: 1, current_protocol_version: PROTOCOL_VERSION, cache: None, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: 0x99, }; let result = viewer.call_function( root, - &view_state, + view_state, &AccountId::from("test.contract"), "run_test_with_storage_change", &[], @@ -293,10 +307,12 @@ mod tests { block_timestamp: 1, current_protocol_version: PROTOCOL_VERSION, cache: None, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: 0x99, }; let view_call_result = viewer.call_function( root, - &view_state, + view_state, &AccountId::from("test.contract"), "sum_with_input", &args, @@ -374,12 +390,14 @@ mod tests { block_timestamp: 1, current_protocol_version: PROTOCOL_VERSION, cache: None, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: 0x99, }; let mut logs = vec![]; viewer .call_function( root, - &view_state, + view_state, &AccountId::from("test.contract"), "panic_after_logging", &[], diff --git a/runtime/runtime/src/verifier.rs b/runtime/runtime/src/verifier.rs index 694b53a4450..1f68e093d54 100644 --- a/runtime/runtime/src/verifier.rs +++ b/runtime/runtime/src/verifier.rs @@ -9,9 +9,9 @@ use near_primitives::transaction::{ Action, AddKeyAction, DeleteAccountAction, DeployContractAction, FunctionCallAction, SignedTransaction, StakeAction, }; -use near_primitives::utils::is_valid_account_id; use near_primitives::version::ProtocolVersion; use near_runtime_configs::get_insufficient_storage_stake; +use near_runtime_utils::is_valid_account_id; use near_store::{ get_access_key, get_account, set_access_key, set_account, StorageError, TrieUpdate, }; diff --git a/runtime/runtime/tests/runtime_group_tools/mod.rs b/runtime/runtime/tests/runtime_group_tools/mod.rs index 1473725aead..07943794eac 100644 --- a/runtime/runtime/tests/runtime_group_tools/mod.rs +++ b/runtime/runtime/tests/runtime_group_tools/mod.rs @@ -68,6 +68,8 @@ impl StandaloneRuntime { current_protocol_version: PROTOCOL_VERSION, config: Arc::new(runtime_config), cache: None, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: near_chain_configs::TEST_EVM_CHAIN_ID, }; Self { diff --git a/runtime/runtime/tests/runtime_group_tools/random_config.rs b/runtime/runtime/tests/runtime_group_tools/random_config.rs index ab78dd27438..4e4353bd088 100644 --- a/runtime/runtime/tests/runtime_group_tools/random_config.rs +++ b/runtime/runtime/tests/runtime_group_tools/random_config.rs @@ -2,6 +2,11 @@ use near_runtime_fees::{ AccessKeyCreationConfig, ActionCreationConfig, DataReceiptCreationConfig, Fee, RuntimeFeesConfig, StorageUsageConfig, }; +#[cfg(feature = "protocol_feature_evm")] +use near_runtime_fees::{ + EvmBls12ConstOpCost, EvmBn128PairingCost, EvmCostConfig, EvmLinearCost, EvmModexpCost, + EvmPrecompileCostConfig, +}; use node_runtime::config::RuntimeConfig; use num_rational::Rational; use rand::{thread_rng, RngCore}; @@ -46,6 +51,42 @@ pub fn random_config() -> RuntimeConfig { (101 + rng.next_u32() % 10).try_into().unwrap(), 100, ), + #[cfg(feature = "protocol_feature_evm")] + evm_config: EvmCostConfig { + bootstrap_cost: rng.next_u64() % 1000, + deploy_cost_per_evm_gas: rng.next_u64() % 1000, + deploy_cost_per_byte: rng.next_u64() % 1000, + funcall_cost_base: rng.next_u64() % 1000, + funcall_cost_per_evm_gas: rng.next_u64() % 1000, + precompile_costs: EvmPrecompileCostConfig { + ecrecover_cost: EvmLinearCost { + base: rng.next_u64() % 1000, + word: rng.next_u64() % 1000, + }, + sha256_cost: EvmLinearCost { + base: rng.next_u64() % 1000, + word: rng.next_u64() % 1000, + }, + ripemd160_cost: EvmLinearCost { + base: rng.next_u64() % 1000, + word: rng.next_u64() % 1000, + }, + identity_cost: EvmLinearCost { + base: rng.next_u64() % 1000, + word: rng.next_u64() % 1000, + }, + modexp_cost: EvmModexpCost { divisor: rng.next_u64() % 1000 + 1 }, + bn128_add_cost: EvmBls12ConstOpCost { price: rng.next_u64() % 1000 }, + bn128_mul_cost: EvmBls12ConstOpCost { price: rng.next_u64() % 1000 }, + bn128_pairing_cost: EvmBn128PairingCost { + base: rng.next_u64() % 1000, + pair: rng.next_u64() % 1000, + }, + blake2f_cost: rng.next_u64() % 1000, + }, + }, + #[cfg(feature = "protocol_feature_evm")] + evm_deposit: (rng.next_u64() % 10000) as u128 * 10u128.pow(23), }, ..Default::default() } diff --git a/test-utils/state-viewer/src/lib.rs b/test-utils/state-viewer/src/lib.rs new file mode 100644 index 00000000000..c54d8b02d76 --- /dev/null +++ b/test-utils/state-viewer/src/lib.rs @@ -0,0 +1,2 @@ +mod state_dump; +pub use crate::state_dump::state_dump; diff --git a/test-utils/testlib/Cargo.toml b/test-utils/testlib/Cargo.toml index ec3755f6407..9bbedf73d0f 100644 --- a/test-utils/testlib/Cargo.toml +++ b/test-utils/testlib/Cargo.toml @@ -19,7 +19,11 @@ byteorder = "1.2" tempfile = "3" assert_matches = "1.3" num-rational = "0.2.4" -hex = "0.4.2" +hex = "0.4" +ethabi = "9.0.1" +ethabi-contract = "9.0.0" +ethabi-derive = "9.0.1" +ethereum-types = "0.8.0" borsh = "0.7.1" @@ -37,3 +41,8 @@ near-network = { path = "../../chain/network" } near-jsonrpc-client = { path = "../../chain/jsonrpc/client" } near-runtime-fees = { path = "../../runtime/near-runtime-fees" } neard = { path = "../../neard" } +near-evm-runner = { path = "../../runtime/near-evm-runner", optional = true } + +[features] +default = [] +protocol_feature_evm = ["near-evm-runner/protocol_feature_evm", "near-primitives/protocol_feature_evm", "near-runtime-fees/protocol_feature_evm", "neard/protocol_feature_evm", "node-runtime/protocol_feature_evm", "near-chain-configs/protocol_feature_evm", "near-chain/protocol_feature_evm"] diff --git a/test-utils/testlib/src/lib.rs b/test-utils/testlib/src/lib.rs index 1a45479c004..e05d4fc5bd2 100644 --- a/test-utils/testlib/src/lib.rs +++ b/test-utils/testlib/src/lib.rs @@ -18,6 +18,8 @@ pub mod actix_utils; pub mod fees_utils; pub mod node; pub mod runtime_utils; +#[cfg(feature = "protocol_feature_evm")] +pub mod standard_evm_cases; pub mod standard_test_cases; pub mod test_helpers; pub mod user; diff --git a/test-utils/testlib/src/node/runtime_node.rs b/test-utils/testlib/src/node/runtime_node.rs index cc4fd310ddf..90920072a7d 100644 --- a/test-utils/testlib/src/node/runtime_node.rs +++ b/test-utils/testlib/src/node/runtime_node.rs @@ -2,12 +2,15 @@ use std::sync::{Arc, RwLock}; use near_chain_configs::Genesis; use near_crypto::{InMemorySigner, KeyType, Signer}; +use near_primitives::account::Account; +use near_primitives::hash::CryptoHash; +use near_primitives::state_record::StateRecord; use near_primitives::types::AccountId; -use neard::config::GenesisExt; +use neard::config::{GenesisExt, TESTING_INIT_BALANCE}; use crate::node::Node; use crate::runtime_utils::{ - add_test_contract, alice_account, bob_account, get_runtime_and_trie_from_genesis, + add_test_contract, alice_account, bob_account, evm_account, get_runtime_and_trie_from_genesis, }; use crate::user::runtime_user::MockClient; use crate::user::{RuntimeUser, User}; @@ -23,6 +26,15 @@ impl RuntimeNode { let mut genesis = Genesis::test(vec![&alice_account(), &bob_account(), "carol.near"], 3); add_test_contract(&mut genesis, &alice_account()); add_test_contract(&mut genesis, &bob_account()); + genesis.records.as_mut().push(StateRecord::Account { + account_id: evm_account(), + account: Account { + amount: TESTING_INIT_BALANCE, + locked: 0, + code_hash: CryptoHash::default(), + storage_usage: 0, + }, + }); Self::new_from_genesis(account_id, genesis) } diff --git a/test-utils/testlib/src/runtime_utils.rs b/test-utils/testlib/src/runtime_utils.rs index e4e8537d637..38a6226b8da 100644 --- a/test-utils/testlib/src/runtime_utils.rs +++ b/test-utils/testlib/src/runtime_utils.rs @@ -22,6 +22,9 @@ pub fn bob_account() -> AccountId { pub fn eve_dot_alice_account() -> AccountId { "eve.alice.near".to_string() } +pub fn evm_account() -> AccountId { + "evm".to_string() +} pub fn default_code_hash() -> CryptoHash { let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); diff --git a/test-utils/testlib/src/standard_evm_cases.rs b/test-utils/testlib/src/standard_evm_cases.rs new file mode 100644 index 00000000000..2371fc89056 --- /dev/null +++ b/test-utils/testlib/src/standard_evm_cases.rs @@ -0,0 +1,130 @@ +use crate::node::Node; +use crate::runtime_utils::{alice_account, evm_account}; +use borsh::BorshSerialize; +use ethabi_contract::use_contract; +use ethereum_types::U256; +use near_evm_runner::types::WithdrawArgs; +use near_evm_runner::utils::{ + address_from_arr, encode_call_function_args, encode_view_call_function_args, u256_to_arr, +}; + +use_contract!(cryptozombies, "../../runtime/near-evm-runner/tests/build/zombieAttack.abi"); +use_contract!(precompiles, "../../runtime/near-evm-runner/tests/build/StandardPrecompiles.abi"); + +pub fn test_evm_deploy_call(node: impl Node) { + let node_user = node.user(); + let bytes = hex::decode( + include_bytes!("../../../runtime/near-evm-runner/tests/build/zombieAttack.bin").to_vec(), + ) + .unwrap(); + let contract_id = node_user + .function_call(alice_account(), evm_account(), "deploy_code", bytes, 10u64.pow(14), 10) + .unwrap() + .status + .as_success_decoded() + .unwrap(); + + let result = node_user.view_call(&evm_account(), "get_balance", &contract_id).unwrap(); + assert_eq!(result.result, u256_to_arr(&U256::from(10)).to_vec()); + + let contract_id = address_from_arr(&contract_id); + + let (input, _decoder) = cryptozombies::functions::create_random_zombie::call("test"); + let args = encode_call_function_args(contract_id, input); + assert_eq!( + node_user + .function_call(alice_account(), evm_account(), "call", args, 10u64.pow(14), 0) + .unwrap() + .status + .as_success_decoded() + .unwrap(), + Vec::::new() + ); + + let alice_address = near_evm_runner::utils::near_account_id_to_evm_address(&alice_account()); + let (input, _decoder) = cryptozombies::functions::get_zombies_by_owner::call( + near_evm_runner::utils::near_account_id_to_evm_address(&alice_account()), + ); + // sender, to, attached amount, args + let args = encode_view_call_function_args(alice_address, contract_id, U256::zero(), input); + let bytes = node_user + .function_call(alice_account(), evm_account(), "view", args.clone(), 10u64.pow(14), 0) + .unwrap() + .status + .as_success_decoded() + .unwrap(); + let res = cryptozombies::functions::get_zombies_by_owner::decode_output(&bytes).unwrap(); + assert_eq!(res, vec![U256::from(0)]); + + let result = node_user.view_call(&evm_account(), "view", &args).unwrap(); + let res = + cryptozombies::functions::get_zombies_by_owner::decode_output(&result.result).unwrap(); + assert_eq!(res, vec![U256::from(0)]); + + let result = node_user.view_call(&evm_account(), "get_balance", &contract_id.0).unwrap(); + assert_eq!(U256::from_big_endian(&result.result), U256::from(10)); + + assert!(node_user + .function_call( + alice_account(), + evm_account(), + "deposit", + alice_address.0.to_vec(), + 10u64.pow(14), + 1000, + ) + .unwrap() + .status + .as_success() + .is_some()); + + let result = node_user.view_call(&evm_account(), "get_balance", &alice_address.0).unwrap(); + assert_eq!(U256::from_big_endian(&result.result), U256::from(1000)); + + let result = node_user + .function_call( + alice_account(), + evm_account(), + "withdraw", + WithdrawArgs { account_id: alice_account(), amount: U256::from(10).into() } + .try_to_vec() + .unwrap(), + 10u64.pow(14), + 0, + ) + .unwrap() + .status + .as_success_decoded() + .unwrap(); + assert_eq!(result.len(), 0); +} + +pub fn test_evm_call_standard_precompiles(node: impl Node) { + let node_user = node.user(); + let bytes = hex::decode( + include_bytes!("../../../runtime/near-evm-runner/tests/build/StandardPrecompiles.bin") + .to_vec(), + ) + .unwrap(); + + let contract_id = node_user + .function_call(alice_account(), evm_account(), "deploy_code", bytes, 10u64.pow(14), 0) + .unwrap() + .status + .as_success_decoded() + .unwrap(); + let contract_id = address_from_arr(&contract_id); + + let alice_address = near_evm_runner::utils::near_account_id_to_evm_address(&alice_account()); + + let (input, _decoder) = precompiles::functions::test_all::call(); + let args = encode_view_call_function_args(alice_address, contract_id, U256::zero(), input); + let bytes = node_user + .function_call(alice_account(), evm_account(), "view", args.clone(), 10u64.pow(14), 0) + .unwrap() + .status + .as_success_decoded() + .unwrap(); + let res = precompiles::functions::test_all::decode_output(&bytes).unwrap(); + assert_eq!(res, true); +} diff --git a/test-utils/testlib/src/user/mod.rs b/test-utils/testlib/src/user/mod.rs index 16467957190..5e74aacba9e 100644 --- a/test-utils/testlib/src/user/mod.rs +++ b/test-utils/testlib/src/user/mod.rs @@ -13,8 +13,10 @@ use near_primitives::transaction::{ TransferAction, }; use near_primitives::types::{AccountId, Balance, BlockHeight, Gas, MerkleHash, ShardId}; -use near_primitives::views::{AccessKeyView, AccountView, BlockView, ChunkView, ViewStateResult}; -use near_primitives::views::{ExecutionOutcomeView, FinalExecutionOutcomeView}; +use near_primitives::views::{ + AccessKeyView, AccountView, BlockView, CallResult, ChunkView, ExecutionOutcomeView, + FinalExecutionOutcomeView, ViewStateResult, +}; pub use crate::user::runtime_user::RuntimeUser; @@ -32,6 +34,13 @@ pub trait User { fn view_state(&self, account_id: &AccountId, prefix: &[u8]) -> Result; + fn view_call( + &self, + account_id: &AccountId, + method_name: &str, + args: &[u8], + ) -> Result; + fn add_transaction(&self, signed_transaction: SignedTransaction) -> Result<(), ServerError>; fn commit_transaction( diff --git a/test-utils/testlib/src/user/rpc_user.rs b/test-utils/testlib/src/user/rpc_user.rs index 580999555c5..50d19bc3484 100644 --- a/test-utils/testlib/src/user/rpc_user.rs +++ b/test-utils/testlib/src/user/rpc_user.rs @@ -11,6 +11,7 @@ use near_client::StatusResponse; use near_crypto::{PublicKey, Signer}; use near_jsonrpc::client::{new_client, JsonRpcClient}; use near_jsonrpc::ServerError; +use near_jsonrpc_client::ChunkId; use near_primitives::hash::CryptoHash; use near_primitives::receipt::Receipt; use near_primitives::serialize::{to_base, to_base64}; @@ -19,12 +20,11 @@ use near_primitives::types::{ AccountId, BlockHeight, BlockId, BlockReference, MaybeBlockId, ShardId, }; use near_primitives::views::{ - AccessKeyView, AccountView, BlockView, ChunkView, EpochValidatorInfo, ExecutionOutcomeView, - FinalExecutionOutcomeView, QueryResponse, ViewStateResult, + AccessKeyView, AccountView, BlockView, CallResult, ChunkView, EpochValidatorInfo, + ExecutionOutcomeView, FinalExecutionOutcomeView, QueryResponse, ViewStateResult, }; use crate::user::User; -use near_jsonrpc_client::ChunkId; pub struct RpcUser { account_id: AccountId, @@ -70,6 +70,16 @@ impl User for RpcUser { self.query(format!("contract/{}", account_id), prefix)?.try_into() } + fn view_call( + &self, + account_id: &AccountId, + method_name: &str, + args: &[u8], + ) -> Result { + self.query(format!("call/{}/{}", account_id, method_name), args) + .and_then(|value| value.try_into()) + } + fn add_transaction(&self, transaction: SignedTransaction) -> Result<(), ServerError> { let bytes = transaction.try_to_vec().unwrap(); let _ = self.actix(move |client| client.broadcast_tx_async(to_base64(&bytes))).map_err( diff --git a/test-utils/testlib/src/user/runtime_user.rs b/test-utils/testlib/src/user/runtime_user.rs index 4be76e17471..4dab5de80a9 100644 --- a/test-utils/testlib/src/user/runtime_user.rs +++ b/test-utils/testlib/src/user/runtime_user.rs @@ -7,22 +7,24 @@ use near_jsonrpc::ServerError; use near_primitives::errors::{RuntimeError, TxExecutionError}; use near_primitives::hash::CryptoHash; use near_primitives::receipt::Receipt; +use near_primitives::test_utils::MockEpochInfoProvider; use near_primitives::transaction::SignedTransaction; use near_primitives::types::{AccountId, BlockHeightDelta, MerkleHash}; use near_primitives::version::PROTOCOL_VERSION; use near_primitives::views::{ - AccessKeyView, AccountView, BlockView, ChunkView, ExecutionOutcomeView, - ExecutionOutcomeWithIdView, ExecutionStatusView, ViewStateResult, + AccessKeyView, AccountView, BlockView, CallResult, ChunkView, ExecutionOutcomeView, + ExecutionOutcomeWithIdView, ExecutionStatusView, FinalExecutionOutcomeView, + FinalExecutionStatus, ViewApplyState, ViewStateResult, }; -use near_primitives::views::{FinalExecutionOutcomeView, FinalExecutionStatus}; use near_store::{ShardTries, TrieUpdate}; +use neard::config::MIN_GAS_PRICE; +#[cfg(feature = "protocol_feature_evm")] +use neard::config::TEST_EVM_CHAIN_ID; +use node_runtime::config::RuntimeConfig; use node_runtime::state_viewer::TrieViewer; use node_runtime::{ApplyState, Runtime}; use crate::user::{User, POISONED_LOCK_ERR}; -use near_primitives::test_utils::MockEpochInfoProvider; -use neard::config::MIN_GAS_PRICE; -use node_runtime::config::RuntimeConfig; /// Mock client without chain, used in RuntimeUser and RuntimeNode pub struct MockClient { @@ -136,6 +138,8 @@ impl RuntimeUser { current_protocol_version: PROTOCOL_VERSION, config: self.runtime_config.clone(), cache: None, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: TEST_EVM_CHAIN_ID, } } @@ -214,6 +218,42 @@ impl User for RuntimeUser { .map_err(|err| err.to_string()) } + fn view_call( + &self, + account_id: &AccountId, + method_name: &str, + args: &[u8], + ) -> Result { + let apply_state = self.apply_state(); + let client = self.client.read().expect(POISONED_LOCK_ERR); + let state_update = client.get_state_update(); + let mut result = CallResult::default(); + let view_state = ViewApplyState { + block_height: apply_state.block_index, + last_block_hash: apply_state.last_block_hash, + epoch_id: apply_state.epoch_id, + epoch_height: apply_state.epoch_height, + block_timestamp: apply_state.block_timestamp, + current_protocol_version: PROTOCOL_VERSION, + cache: apply_state.cache, + #[cfg(feature = "protocol_feature_evm")] + evm_chain_id: TEST_EVM_CHAIN_ID, + }; + result.result = self + .trie_viewer + .call_function( + state_update, + view_state, + account_id, + method_name, + args, + &mut result.logs, + &self.epoch_info_provider, + ) + .map_err(|err| err.to_string())?; + Ok(result) + } + fn add_transaction(&self, transaction: SignedTransaction) -> Result<(), ServerError> { self.apply_all(self.apply_state(), vec![], vec![transaction])?; Ok(()) diff --git a/tests/test_cases_runtime.rs b/tests/test_cases_runtime.rs index c5f55c35d2c..c1305c4d3f0 100644 --- a/tests/test_cases_runtime.rs +++ b/tests/test_cases_runtime.rs @@ -5,6 +5,8 @@ mod test { use neard::config::{GenesisExt, TESTING_INIT_BALANCE}; use testlib::node::RuntimeNode; use testlib::runtime_utils::{add_test_contract, alice_account, bob_account}; + #[cfg(feature = "protocol_feature_evm")] + use testlib::standard_evm_cases::*; use testlib::standard_test_cases::*; fn create_runtime_node() -> RuntimeNode { @@ -303,4 +305,20 @@ mod test { let node = create_free_runtime_node(); test_smart_contract_free(node); } + + // cargo test --package nearcore --test test_cases_runtime test::test_evm_deploy_call_runtime --features protocol_feature_evm,nightly_protocol_features -- --exact --nocapture + #[cfg(feature = "protocol_feature_evm")] + #[test] + fn test_evm_deploy_call_runtime() { + let node = create_runtime_node(); + test_evm_deploy_call(node); + } + + // cargo test --package nearcore --test test_cases_runtime test::test_evm_call_standard_precompiles_runtime --features protocol_feature_evm,nightly_protocol_features -- --exact --nocapture + #[cfg(feature = "protocol_feature_evm")] + #[test] + fn test_evm_call_standard_precompiles_runtime() { + let node = create_runtime_node(); + test_evm_call_standard_precompiles(node); + } } diff --git a/tests/test_cases_testnet_rpc.rs b/tests/test_cases_testnet_rpc.rs index 724c06dbb8b..f81aca2cc93 100644 --- a/tests/test_cases_testnet_rpc.rs +++ b/tests/test_cases_testnet_rpc.rs @@ -9,6 +9,8 @@ mod test { use near_logger_utils::init_test_module_logger; use testlib::node::{create_nodes_from_seeds, Node, NodeConfig, ThreadNode}; use testlib::runtime_utils::alice_account; + #[cfg(feature = "protocol_feature_evm")] + use testlib::standard_evm_cases::*; use testlib::standard_test_cases::*; use testlib::test_helpers::heavy_test; @@ -196,4 +198,10 @@ mod test { fn test_access_key_smart_contract_testnet() { run_testnet_test!(test_access_key_smart_contract); } + + #[cfg(feature = "protocol_feature_evm")] + #[test] + fn test_evm_deploy_call_testnet() { + run_testnet_test!(test_evm_deploy_call); + } }