diff --git a/Cargo.lock b/Cargo.lock index 88c413ce..901cc99e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.7.8" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ "getrandom", "once_cell", @@ -15,15 +15,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base16ct" @@ -33,9 +33,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.21.7" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -75,15 +75,15 @@ checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" [[package]] name = "byteorder" -version = "1.5.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.7.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cfg-if" @@ -93,18 +93,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "num-traits", ] [[package]] name = "const-oid" -version = "0.9.6" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "const_panic" @@ -123,11 +123,12 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.7" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" +checksum = "e6b4c3f9c4616d6413d4b5fc4c270a4cc32a374b9be08671e80e1a019f805d8f" dependencies = [ "digest 0.10.7", + "ecdsa", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -136,18 +137,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.5.7" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" +checksum = "c586ced10c3b00e809ee664a895025a024f60d65d34fe4c09daed4a4db68a3f3" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.5.7" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" +checksum = "8467874827d384c131955ff6f4d47d02e72a956a08eb3c0ff24f8c903a5517b4" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -158,9 +159,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.5.7" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" +checksum = "f6db85d98ac80922aef465e564d5b21fa9cfac5058cb62df7f116c3682337393" dependencies = [ "proc-macro2", "quote", @@ -169,9 +170,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.5.7" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" +checksum = "712fe58f39d55c812f7b2c84e097cdede3a39d520f89b6dc3153837e31741927" dependencies = [ "base64", "bech32", @@ -191,18 +192,18 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -246,7 +247,7 @@ dependencies = [ "cw-utils", "derivative", "itertools 0.12.1", - "prost 0.12.6", + "prost 0.12.4", "schemars", "serde", "sha2 0.10.8", @@ -296,9 +297,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.9" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -338,15 +339,15 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.17" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", "digest 0.10.7", @@ -373,15 +374,15 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", @@ -431,9 +432,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -462,9 +463,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] name = "hex" @@ -483,12 +484,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.14.0", ] [[package]] @@ -511,15 +512,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "k256" -version = "0.13.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", @@ -531,9 +532,9 @@ dependencies = [ [[package]] name = "konst" -version = "0.3.9" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50a0ba6de5f7af397afff922f22c149ff605c766cd3269cf6c1cd5e466dbe3b9" +checksum = "030400e39b2dff8beaa55986a17e0014ad657f569ca92426aafcb5e8e71faee7" dependencies = [ "const_panic", "konst_kernel", @@ -543,9 +544,9 @@ dependencies = [ [[package]] name = "konst_kernel" -version = "0.3.9" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0a455a1719220fd6adf756088e1c69a85bf14b6a9e24537a5cc04f503edb2b" +checksum = "3376133edc39f027d551eb77b077c2865a0ef252b2e7d0dd6b6dc303db95d8b5" dependencies = [ "typewit", ] @@ -558,15 +559,15 @@ checksum = "4e28ab1dc35e09d60c2b8c90d12a9a8d9666c876c10a3739a3196db0103b6043" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "memchr" -version = "2.7.4" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "76fc44e2588d5b436dbc3c6cf62aef290f90dab6235744a93dfe1cc18f451e2c" [[package]] name = "mesh-apis" @@ -810,39 +811,26 @@ dependencies = [ "thiserror", ] -[[package]] -name = "mesh-virtual-staking-mock" -version = "0.10.0-alpha.1" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "mesh-bindings", - "schemars", - "serde", -] - [[package]] name = "num-traits" -version = "0.2.19" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "osmosis-std" @@ -919,9 +907,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -938,12 +926,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.6" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" dependencies = [ "bytes", - "prost-derive 0.12.6", + "prost-derive 0.12.4", ] [[package]] @@ -961,15 +949,15 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.6" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.60", ] [[package]] @@ -1017,15 +1005,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.21" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +checksum = "7f55c82c700538496bdc329bb4918a81f87cc8888811bd123cf325a0f2f8d309" dependencies = [ "dyn-clone", "schemars_derive", @@ -1035,14 +1023,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.21" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +checksum = "83263746fe5e32097f06356968a077f96089739c927a61450efa069905eec108" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.74", + "syn 2.0.60", ] [[package]] @@ -1061,15 +1049,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.207" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" +checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" dependencies = [ "serde_derive", ] @@ -1103,34 +1091,33 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.207" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" +checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.60", ] [[package]] name = "serde_derive_internals" -version = "0.29.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.60", ] [[package]] name = "serde_json" -version = "1.0.124" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", - "memchr", "ryu", "serde", ] @@ -1161,9 +1148,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -1171,9 +1158,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1187,9 +1174,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "subtle" -version = "2.6.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "sylvia" @@ -1222,7 +1209,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.60", ] [[package]] @@ -1238,9 +1225,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -1265,7 +1252,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.60", ] [[package]] @@ -1276,41 +1263,41 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.60", "test-case-core", ] [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.60", ] [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap", "toml_datetime", @@ -1319,42 +1306,33 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "typewit" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fb9ae6a3cafaf0a5d14c2302ca525f9ae8e07a0f0e6949de88d882c37a6e24" -dependencies = [ - "typewit_proc_macros", -] - -[[package]] -name = "typewit_proc_macros" -version = "1.8.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" +checksum = "3e5cee357cc77d1e02f10a3e6c4e13b8462fafab05998b62d331b7d9485589ff" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "version_check" -version = "0.9.5" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" @@ -1364,15 +1342,15 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "winnow" -version = "0.5.40" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] [[package]] name = "zeroize" -version = "1.8.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/Cargo.toml b/Cargo.toml index 3937a620..aa9857ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,6 @@ mesh-apis = { path = "./packages/apis" } mesh-bindings = { path = "./packages/bindings" } mesh-burn = { path = "./packages/burn" } mesh-sync = { path = "./packages/sync" } -mesh-virtual-staking-mock = { path = "./packages/virtual-staking-mock" } mesh-vault = { path = "./contracts/provider/vault" } mesh-external-staking = { path = "./contracts/provider/external-staking" } diff --git a/contracts/consumer/converter/Cargo.toml b/contracts/consumer/converter/Cargo.toml index aefd9b14..0d7b3858 100644 --- a/contracts/consumer/converter/Cargo.toml +++ b/contracts/consumer/converter/Cargo.toml @@ -41,6 +41,7 @@ thiserror = { workspace = true } mesh-burn = { workspace = true } mesh-simple-price-feed = { workspace = true, features = ["mt"] } mesh-virtual-staking = { workspace = true, features = ["mt"] } + cw-multi-test = { workspace = true } test-case = { workspace = true } derivative = { workspace = true } diff --git a/contracts/consumer/converter/src/contract.rs b/contracts/consumer/converter/src/contract.rs index 7032f061..bb301ed3 100644 --- a/contracts/consumer/converter/src/contract.rs +++ b/contracts/consumer/converter/src/contract.rs @@ -73,6 +73,7 @@ impl ConverterContract<'_> { discount: Decimal, remote_denom: String, virtual_staking_code_id: u64, + tombstoned_unbond_enable: bool, admin: Option, max_retrieve: u32, ) -> Result { @@ -98,8 +99,10 @@ impl ConverterContract<'_> { ctx.deps.api.addr_validate(admin)?; } - let msg = - to_json_binary(&mesh_virtual_staking::contract::sv::InstantiateMsg { max_retrieve })?; + let msg = to_json_binary(&mesh_virtual_staking::contract::sv::InstantiateMsg { + max_retrieve, + tombstoned_unbond_enable, + })?; // Instantiate virtual staking contract let init_msg = WasmMsg::Instantiate { admin, diff --git a/contracts/consumer/converter/src/multitest.rs b/contracts/consumer/converter/src/multitest.rs index ecd165bc..ace07adf 100644 --- a/contracts/consumer/converter/src/multitest.rs +++ b/contracts/consumer/converter/src/multitest.rs @@ -61,6 +61,7 @@ fn setup<'a>(app: &'a App, args: SetupArgs<'a>) -> SetupResponse<'a> { discount, JUNO.to_owned(), virtual_staking_code.code_id(), + true, Some(admin.to_owned()), 50, ) diff --git a/contracts/consumer/virtual-staking/src/contract.rs b/contracts/consumer/virtual-staking/src/contract.rs index 2458a524..c7a87f64 100644 --- a/contracts/consumer/virtual-staking/src/contract.rs +++ b/contracts/consumer/virtual-staking/src/contract.rs @@ -44,7 +44,7 @@ pub struct VirtualStakingContract<'a> { /// This is what validators are inactive because of tombstoning, jailing or removal (unbonded). // `inactive` could be a Map like `bond_requests`, but the only time we use it is to read / write the entire list in bulk (in handle_epoch), // never accessing one element. Reading 100 elements in an Item is much cheaper than ranging over a Map with 100 entries. - pub inactive: Item<'a, Vec>, + pub inactive: Item<'a, Vec<(String, bool)>>, /// Amount of tokens that have been burned from a validator. /// This is just for accounting / tracking reasons, as token "burning" is being implemented as unbonding, /// and there's no real need to discount the burned amount in this contract. @@ -76,6 +76,7 @@ impl VirtualStakingContract<'_> { &self, ctx: InstantiateCtx, max_retrieve: u32, + tombstoned_unbond_enable: bool, ) -> Result, ContractError> { nonpayable(&ctx.info)?; let denom = ctx.deps.querier.query_bonded_denom()?; @@ -83,6 +84,7 @@ impl VirtualStakingContract<'_> { denom, converter: ctx.info.sender, max_retrieve, + tombstoned_unbond_enable, }; self.config.save(ctx.deps.storage, &config)?; // initialize these to no one, so no issue when reading for the first time @@ -295,6 +297,7 @@ fn pop_target(deps: DepsMut) -> StdResult<(String, bool fn calculate_rebalance( current: Vec<(String, Uint128)>, desired: Vec<(String, Uint128)>, + tombstoned_list: HashMap, denom: &str, ) -> Vec> { let mut desired: BTreeMap<_, _> = desired.into_iter().collect(); @@ -303,6 +306,13 @@ fn calculate_rebalance( let mut msgs = vec![]; for (validator, prev) in current { let next = desired.remove(&validator).unwrap_or_else(Uint128::zero); + if tombstoned_list.contains_key(&validator) && !next.is_zero() { + let amount = tombstoned_list.get(&validator).unwrap().clone(); + if !amount.amount.is_zero() { + msgs.push(VirtualStakeMsg::Unbond { validator, amount }.into()); + } + continue; + } match next.cmp(&prev) { Ordering::Less => { let unbond = prev - next; @@ -683,8 +693,15 @@ impl VirtualStakingApi for VirtualStakingContract<'_> { // withdraw rewards let bonded = self.bonded.load(deps.storage)?; - let inactive = self.inactive.load(deps.storage)?; - let withdraw = withdraw_reward_msgs(deps.branch(), &bonded, &inactive); + let inactive_list = self.inactive.load(deps.storage)?; + let withdraw = withdraw_reward_msgs( + deps.branch(), + &bonded, + &inactive_list + .iter() + .map(|(i, _)| i.to_string()) + .collect::>(), + ); let mut resp = Response::new().add_submessages(withdraw); let bond = @@ -694,7 +711,6 @@ impl VirtualStakingApi for VirtualStakingContract<'_> { let config = self.config.load(deps.storage)?; // If 0 max cap, then we assume all tokens were force unbonded already, and just return the withdraw rewards // call and set bonded to empty - // TODO: verify this behavior with SDK module (otherwise we send unbond message) if max_cap.is_zero() { let all_delegations = TokenQuerier::new(&deps.querier) .all_delegations(env.contract.address.to_string(), config.max_retrieve)?; @@ -731,7 +747,12 @@ impl VirtualStakingApi for VirtualStakingContract<'_> { self.adjust_slashings(deps.branch(), &mut current, &slash)?; // Update inactive list. Defensive, as it should already been updated in handle_valset_update, due to removals self.inactive.update(deps.branch().storage, |mut old| { - old.extend_from_slice(&slash.iter().map(|v| v.address.clone()).collect::>()); + old.extend_from_slice( + &slash + .iter() + .map(|v| (v.address.clone(), v.is_tombstoned)) + .collect::>(), + ); old.dedup(); Ok::<_, ContractError>(old) })?; @@ -756,11 +777,31 @@ impl VirtualStakingApi for VirtualStakingContract<'_> { } } + // Force the tombstoned validator to auto unbond + let mut tombstoned_list: HashMap = HashMap::new(); + for (val, is_tombstoned) in inactive_list.iter() { + if *is_tombstoned { + let resp = TokenQuerier::new(&deps.querier) + .total_delegations(env.contract.address.to_string(), val.to_string())?; + tombstoned_list.insert(val.to_string(), resp.delegation); + } + } + + let mut request_with_tombstoned = requests.clone(); + for (val, amount) in request_with_tombstoned.iter_mut() { + if tombstoned_list.contains_key(val) { + *amount = Uint128::zero(); + // Update new value for the bond requests + self.bond_requests.save(deps.storage, val, amount)?; + } + } + // Save the future values - self.bonded.save(deps.branch().storage, &requests)?; + self.bonded + .save(deps.branch().storage, &request_with_tombstoned)?; // Compare these two to make bond/unbond calls as needed - let rebalance = calculate_rebalance(current, requests, &config.denom); + let rebalance = calculate_rebalance(current, requests, tombstoned_list, &config.denom); resp = resp.add_messages(rebalance); Ok(resp) @@ -803,12 +844,23 @@ impl VirtualStakingApi for VirtualStakingContract<'_> { // Update inactive list. // We ignore `unjailed` as it's not clear they make the validator active again or not. - if !removals.is_empty() || !additions.is_empty() { + if !removals.is_empty() || !additions.is_empty() || !tombstoned.is_empty() { self.inactive.update(deps.storage, |mut old| { // Add removals - old.extend_from_slice(removals); + old.extend_from_slice( + &tombstoned + .iter() + .map(|t| (t.to_string(), true)) + .collect::>(), + ); + old.extend_from_slice( + &removals + .iter() + .map(|r| (r.to_string(), false)) + .collect::>(), + ); // Filter additions - old.retain(|v| !additions.iter().any(|a| a.address == *v)); + old.retain(|v| !additions.iter().any(|a| a.address == *v.0)); old.dedup(); Ok::<_, ContractError>(old) })?; @@ -857,7 +909,7 @@ mod tests { testing::{mock_env, mock_info, MockApi, MockQuerier, MockStorage}, AllDelegationsResponse, Decimal, }; - use mesh_bindings::{BondStatusResponse, SlashRatioResponse}; + use mesh_bindings::{BondStatusResponse, SlashRatioResponse, TotalDelegationResponse}; use super::*; @@ -1238,11 +1290,14 @@ mod tests { // Val1 is being tombstoned contract.tombstone(deps.as_mut(), "val1", Decimal::percent(25), Uint128::new(5)); + knobs + .total_delegation + .update_total_delegation(15u128, &denom); contract .hit_epoch(deps.as_mut()) .assert_bond(&[]) // No bond msgs after tombstoning - .assert_unbond(&[]) // No unbond msgs after tombstoning - .assert_rewards(&["val1", "val2"]); // Last rewards msgs after tombstoning + .assert_unbond(&[("val1", (15u128, &denom))]) // No unbond msgs after tombstoning + .assert_rewards(&["val2"]); // Last rewards msgs after tombstoning // Check that the bonded amounts of val1 have been slashed for double sign (25%) // Val2 is unaffected. @@ -1251,7 +1306,7 @@ mod tests { assert_eq!( bonded, [ - ("val1".to_string(), Uint128::new(15)), + ("val1".to_string(), Uint128::new(0)), ("val2".to_string(), Uint128::new(20)) ] ); @@ -1280,24 +1335,31 @@ mod tests { // And it's being tombstoned at the same time contract.tombstone(deps.as_mut(), "val1", Decimal::percent(25), Uint128::new(2)); + knobs + .total_delegation + .update_total_delegation(28u128, &denom); contract .hit_epoch(deps.as_mut()) - .assert_bond(&[("val1", (20, &denom))]) // FIXME?: Tombstoned validators can still bond - .assert_unbond(&[]) - .assert_rewards(&["val1"]); // Rewards are still being gathered + .assert_bond(&[]) // Tombstoned validators will be auto unbond + .assert_unbond(&[("val1", (28u128, &denom))]) + .assert_rewards(&[]); // Rewards are still being gathered // Check that the previously bonded amounts of val1 have been slashed for double sign (25%) let bonded = contract.bonded.load(deps.as_ref().storage).unwrap(); assert_eq!( bonded, [ - ("val1".to_string(), Uint128::new(8 + 20)), // Due to rounding up + ("val1".to_string(), Uint128::new(0)), // Due to rounding up ] ); // Subsequent rewards msgs are removed after validator is tombstoned - contract.hit_epoch(deps.as_mut()).assert_rewards(&[]); + contract + .hit_epoch(deps.as_mut()) + .assert_bond(&[]) // Tombstoned validators can still bond + .assert_unbond(&[]) + .assert_rewards(&[]); } #[test] @@ -1325,7 +1387,7 @@ mod tests { .hit_epoch(deps.as_mut()) .assert_bond(&[]) // No bond msgs after jailing .assert_unbond(&[("val1", (8u128, &denom))]) // Unbond adjusted for double sign slashing - .assert_rewards(&["val1"]); // Rewards are still being gathered + .assert_rewards(&[]); // Rewards are still being gathered // Check that bonded accounting has been adjusted let bonded = contract.bonded.load(deps.as_ref().storage).unwrap(); @@ -1421,12 +1483,16 @@ mod tests { slash_fraction_downtime: "0.1".to_string(), slash_fraction_double_sign: "0.25".to_string(), }); + let total_delegation = MockTotalDelegation::new(TotalDelegationResponse { + delegation: coin(0, "DOES NOT MATTER"), + }); let all_delegations = MockAllDelegations::new(AllDelegationsResponse { delegations: vec![], }); let handler = { let bs_copy = bond_status.clone(); + let td_copy = total_delegation.clone(); move |msg: &_| { let VirtualStakeCustomQuery::VirtualStake(msg) = msg; match msg { @@ -1440,6 +1506,11 @@ mod tests { to_json_binary(&*slash_ratio.borrow()).unwrap(), )) } + mesh_bindings::VirtualStakeQuery::TotalDelegation { .. } => { + cosmwasm_std::SystemResult::Ok(cosmwasm_std::ContractResult::Ok( + to_json_binary(&*td_copy.borrow()).unwrap(), + )) + } mesh_bindings::VirtualStakeQuery::AllDelegations { .. } => { cosmwasm_std::SystemResult::Ok(cosmwasm_std::ContractResult::Ok( to_json_binary(&*all_delegations.borrow()).unwrap(), @@ -1456,12 +1527,16 @@ mod tests { querier: MockQuerier::new(&[]).with_custom_handler(handler), custom_query_type: PhantomData, }, - StakingKnobs { bond_status }, + StakingKnobs { + bond_status, + total_delegation, + }, ) } struct StakingKnobs { bond_status: MockBondStatus, + total_delegation: MockTotalDelegation, } #[derive(Clone)] @@ -1495,6 +1570,26 @@ mod tests { } } + #[derive(Clone)] + struct MockTotalDelegation(Rc>); + + impl MockTotalDelegation { + fn new(res: TotalDelegationResponse) -> Self { + Self(Rc::new(RefCell::new(res))) + } + + fn borrow(&self) -> Ref<'_, TotalDelegationResponse> { + self.0.borrow() + } + + fn update_total_delegation(&self, amount: impl Into, denom: impl Into) { + let mut mut_obj = self.0.borrow_mut(); + mut_obj.delegation = Coin { + amount: amount.into(), + denom: denom.into(), + }; + } + } #[derive(Clone)] struct MockAllDelegations(Rc>); @@ -1557,6 +1652,7 @@ mod tests { info: mock_info("me", &[]), }, 50, + true, ) .unwrap(); } @@ -1678,6 +1774,7 @@ mod tests { power: 0, slash_amount, slash_ratio: nominal_slash_ratio.to_string(), + is_tombstoned: false, }]), ) .unwrap(); @@ -1730,6 +1827,7 @@ mod tests { power: 0, slash_amount, slash_ratio: nominal_slash_ratio.to_string(), + is_tombstoned: true, }]), ) .unwrap(); diff --git a/contracts/consumer/virtual-staking/src/multitest.rs b/contracts/consumer/virtual-staking/src/multitest.rs index 76f6ff1e..fa927e09 100644 --- a/contracts/consumer/virtual-staking/src/multitest.rs +++ b/contracts/consumer/virtual-staking/src/multitest.rs @@ -59,6 +59,7 @@ fn setup<'a>(app: &'a App, args: SetupArgs<'a>) -> SetupResponse<'a> { discount, JUNO.to_owned(), virtual_staking_code.code_id(), + true, Some(admin.to_owned()), 50, ) diff --git a/contracts/consumer/virtual-staking/src/state.rs b/contracts/consumer/virtual-staking/src/state.rs index 2563851d..411a2092 100644 --- a/contracts/consumer/virtual-staking/src/state.rs +++ b/contracts/consumer/virtual-staking/src/state.rs @@ -8,8 +8,13 @@ pub struct Config { /// The address of the converter contract (that is authorized to bond/unbond and will receive rewards) pub converter: Addr, - - /// Maximum + /// pub max_retrieve: u32, + + /// If it enable, tombstoned validators will be unbond automatically + pub tombstoned_unbond_enable: bool, + + /// Maximum delegations per query + pub max_retrieve: u16, } diff --git a/contracts/provider/external-staking/src/contract.rs b/contracts/provider/external-staking/src/contract.rs index 292993f6..2d565016 100644 --- a/contracts/provider/external-staking/src/contract.rs +++ b/contracts/provider/external-staking/src/contract.rs @@ -2664,4 +2664,13 @@ mod tests { ] ); } + + #[test] + fn convert_str_decimal() { + let slash_ratio = match String::from("0.100000000000000000").parse::() { + Ok(ratio) => ratio, + Err(err) => panic!("err: {}", err), + }; + println!("slash_ratio: {:#?}", slash_ratio); + } } diff --git a/packages/apis/src/virtual_staking_api.rs b/packages/apis/src/virtual_staking_api.rs index c541e875..3d1eeff8 100644 --- a/packages/apis/src/virtual_staking_api.rs +++ b/packages/apis/src/virtual_staking_api.rs @@ -124,4 +124,6 @@ pub struct ValidatorSlash { /// The (nominal) slash ratio for the validator. /// Useful in case we don't know if it's a double sign or downtime slash. pub slash_ratio: String, + /// Validator is tombstoned or not. + pub is_tombstoned: bool, } diff --git a/packages/bindings/src/lib.rs b/packages/bindings/src/lib.rs index 45c3ba81..4600323e 100644 --- a/packages/bindings/src/lib.rs +++ b/packages/bindings/src/lib.rs @@ -3,8 +3,8 @@ mod query; pub use msg::{ProviderCustomMsg, ProviderMsg, VirtualStakeCustomMsg, VirtualStakeMsg}; pub use query::{ - BondStatusResponse, SlashRatioResponse, TokenQuerier, VirtualStakeCustomQuery, - VirtualStakeQuery, + BondStatusResponse, SlashRatioResponse, TokenQuerier, TotalDelegationResponse, + VirtualStakeCustomQuery, VirtualStakeQuery, }; // This is a signal, such that any contract that imports these helpers diff --git a/packages/bindings/src/query.rs b/packages/bindings/src/query.rs index f3d70dad..6c26937a 100644 --- a/packages/bindings/src/query.rs +++ b/packages/bindings/src/query.rs @@ -22,6 +22,10 @@ pub enum VirtualStakeQuery { #[returns(SlashRatioResponse)] SlashRatio {}, + /// Returns total delegations of the give validator + #[returns(TotalDelegationResponse)] + TotalDelegation { contract: String, validator: String }, + /// Returns a max retrieve amount of delegations for the given contract #[returns(AllDelegationsResponse)] AllDelegations { contract: String, max_retrieve: u32 }, @@ -46,6 +50,10 @@ pub struct SlashRatioResponse { pub slash_fraction_double_sign: String, } +#[cw_serde] +pub struct TotalDelegationResponse { + pub delegation: Coin, +} #[cw_serde] pub struct AllDelegationsResponse { pub delegations: Vec, @@ -86,6 +94,17 @@ impl<'a> TokenQuerier<'a> { self.querier.query(&slash_ratio_query.into()) } + pub fn total_delegations( + &self, + contract: String, + validator: String, + ) -> StdResult { + let total_delegations_query = VirtualStakeQuery::TotalDelegation { + contract, + validator, + }; + self.querier.query(&total_delegations_query.into()) + } pub fn all_delegations( &self, contract: String, diff --git a/packages/virtual-staking-mock/Cargo.toml b/packages/virtual-staking-mock/Cargo.toml deleted file mode 100644 index 5909adbd..00000000 --- a/packages/virtual-staking-mock/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "mesh-virtual-staking-mock" -edition.workspace = true -version.workspace = true -license.workspace = true -repository.workspace = true -publish = false - -[dependencies] -anyhow = { workspace = true } -cosmwasm-std = { workspace = true } -cw-multi-test = { workspace = true } -cw-storage-plus = { workspace = true } -mesh-bindings = { workspace = true } -schemars = { workspace = true } -serde = { workspace = true } diff --git a/packages/virtual-staking-mock/src/lib.rs b/packages/virtual-staking-mock/src/lib.rs deleted file mode 100644 index 0796f5e5..00000000 --- a/packages/virtual-staking-mock/src/lib.rs +++ /dev/null @@ -1,197 +0,0 @@ -use anyhow::Result as AnyResult; -use cosmwasm_std::{ - coin, - testing::{MockApi, MockStorage}, - to_json_binary, Addr, AllDelegationsResponse, Api, Binary, BlockInfo, CustomQuery, Empty, - Querier, QuerierWrapper, Storage, Uint128, -}; -use cw_multi_test::{AppResponse, BankKeeper, Module, WasmKeeper}; -use cw_storage_plus::{Item, Map}; -use mesh_bindings::{ - BondStatusResponse, SlashRatioResponse, VirtualStakeCustomMsg, VirtualStakeCustomQuery, -}; -use schemars::JsonSchema; -use serde::de::DeserializeOwned; - -pub type App = cw_multi_test::App< - BankKeeper, - MockApi, - MockStorage, - VirtualStakingModule, - WasmKeeper, ->; - -pub struct VirtualStakingModule { - /// virtual-staking contract -> max cap - caps: Map<'static, Addr, Uint128>, - /// (virtual-staking contract, validator) -> bonded amount - bonds: Map<'static, (Addr, Addr), Uint128>, - slash_ratio: Item<'static, SlashRatioResponse>, -} - -impl VirtualStakingModule { - pub fn new() -> Self { - Self { - caps: Map::new("virtual_staking_caps"), - bonds: Map::new("virtual_staking_bonds"), - slash_ratio: Item::new("virtual_staking_slash_ratios"), - } - } - - pub fn init_slash_ratios( - &self, - storage: &mut dyn Storage, - slash_for_downtime: impl Into, - slash_for_double_sign: impl Into, - ) -> AnyResult<()> { - self.slash_ratio.save( - storage, - &SlashRatioResponse { - slash_fraction_downtime: slash_for_downtime.into(), - slash_fraction_double_sign: slash_for_double_sign.into(), - }, - )?; - - Ok(()) - } - - fn bonded_for_contract(&self, storage: &dyn Storage, contract: Addr) -> AnyResult { - Ok(self - .bonds - .range(storage, None, None, cosmwasm_std::Order::Ascending) - .collect::, _>>()? - .into_iter() - .filter_map(|((c, _), amt)| if c == contract { Some(amt) } else { None }) - .sum()) - } -} - -impl Default for VirtualStakingModule { - fn default() -> Self { - Self::new() - } -} - -impl Module for VirtualStakingModule { - type ExecT = VirtualStakeCustomMsg; - - type QueryT = VirtualStakeCustomQuery; - - type SudoT = Empty; - - fn execute( - &self, - _api: &dyn Api, - storage: &mut dyn Storage, - _router: &dyn cw_multi_test::CosmosRouter, - _block: &BlockInfo, - sender: Addr, - msg: Self::ExecT, - ) -> AnyResult - where - ExecC: std::fmt::Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static, - { - let VirtualStakeCustomMsg::VirtualStake(msg) = msg; - - let cap = self.caps.load(storage, sender.clone())?; - - match msg { - mesh_bindings::VirtualStakeMsg::Bond { amount, validator } => { - let all_bonded = self.bonded_for_contract(storage, sender.clone())?; - - if all_bonded + amount.amount <= cap { - let current_bonded = self - .bonds - .may_load(storage, (sender.clone(), Addr::unchecked(&validator)))? - .unwrap_or(Uint128::zero()); - - self.bonds.save( - storage, - (sender, Addr::unchecked(validator)), - &(current_bonded + amount.amount), - )?; - - Ok(AppResponse::default()) - } else { - Err(anyhow::anyhow!("cap exceeded")) - } - } - mesh_bindings::VirtualStakeMsg::Unbond { amount, validator } => { - let current_bonded = self - .bonds - .may_load(storage, (sender.clone(), Addr::unchecked(&validator)))? - .unwrap_or(Uint128::zero()); - - if current_bonded - amount.amount >= Uint128::zero() { - self.bonds.save( - storage, - (sender, Addr::unchecked(validator)), - &(current_bonded - amount.amount), - )?; - - Ok(AppResponse::default()) - } else { - Err(anyhow::anyhow!("bonded amount exceeded")) - } - } - mesh_bindings::VirtualStakeMsg::UpdateDelegation { .. } => Ok(AppResponse::default()), - mesh_bindings::VirtualStakeMsg::DeleteAllScheduledTasks { .. } => { - Ok(AppResponse::default()) - } - } - } - - fn sudo( - &self, - _api: &dyn Api, - _storage: &mut dyn Storage, - _router: &dyn cw_multi_test::CosmosRouter, - _block: &BlockInfo, - _msg: Self::SudoT, - ) -> AnyResult - where - ExecC: std::fmt::Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, - QueryC: CustomQuery + DeserializeOwned + 'static, - { - Err(anyhow::anyhow!( - "sudo not implemented for the virtual staking module" - )) - } - - fn query( - &self, - _api: &dyn Api, - storage: &dyn Storage, - querier: &dyn Querier, - _block: &BlockInfo, - request: Self::QueryT, - ) -> AnyResult { - let VirtualStakeCustomQuery::VirtualStake(query) = request; - - let result = match query { - mesh_bindings::VirtualStakeQuery::BondStatus { contract } => { - let denom = - QuerierWrapper::::new(querier).query_bonded_denom()?; - - let cap = self.caps.load(storage, Addr::unchecked(&contract))?; - let bonded = self.bonded_for_contract(storage, Addr::unchecked(contract))?; - - to_json_binary(&BondStatusResponse { - cap: coin(cap.u128(), &denom), - delegated: coin(bonded.u128(), denom), - })? - } - mesh_bindings::VirtualStakeQuery::SlashRatio {} => { - to_json_binary(&self.slash_ratio.load(storage)?)? - } - mesh_bindings::VirtualStakeQuery::AllDelegations { .. } => { - to_json_binary(&AllDelegationsResponse { - delegations: vec![], - })? - } - }; - - Ok(to_json_binary(&result)?) - } -}