diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index 0ab2bf1529..01f9aeb123 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -204,7 +204,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -415,7 +415,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure 0.13.1", ] @@ -438,7 +438,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -614,7 +614,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -661,7 +661,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -772,7 +772,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1284,7 +1284,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2036,7 +2036,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2330,7 +2330,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2370,7 +2370,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2387,7 +2387,7 @@ checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2518,7 +2518,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2531,7 +2531,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2620,7 +2620,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2644,7 +2644,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.89", + "syn 2.0.90", "termcolor", "toml 0.8.16", "walkdir", @@ -2803,7 +2803,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2823,7 +2823,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2834,7 +2834,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3053,7 +3053,7 @@ dependencies = [ "prettyplease 0.2.20", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3104,7 +3104,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3606,7 +3606,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3727,7 +3727,7 @@ dependencies = [ "proc-macro2", "quote", "sp-crypto-hashing", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3739,7 +3739,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3749,7 +3749,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2407#f2081 dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3943,7 +3943,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4863,7 +4863,7 @@ dependencies = [ "jsonrpsee-core", "pin-project", "rustls 0.23.20", - "rustls-pki-types 1.10.0", + "rustls-pki-types 1.10.1", "rustls-platform-verifier", "soketto 0.8.1", "thiserror", @@ -4912,7 +4912,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5059,9 +5059,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.168" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" @@ -5070,7 +5070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -5154,7 +5154,7 @@ dependencies = [ "libp2p-identity", "log", "multiaddr 0.18.2", - "multihash 0.19.2", + "multihash 0.19.3", "multistream-select", "once_cell", "parking_lot 0.12.3", @@ -5216,7 +5216,7 @@ dependencies = [ "bs58 0.5.1", "ed25519-dalek", "hkdf", - "multihash 0.19.2", + "multihash 0.19.3", "quick-protobuf", "rand", "sha2 0.10.8", @@ -5305,7 +5305,7 @@ dependencies = [ "libp2p-identity", "log", "multiaddr 0.18.2", - "multihash 0.19.2", + "multihash 0.19.3", "once_cell", "quick-protobuf", "rand", @@ -5410,7 +5410,7 @@ dependencies = [ "proc-macro-warning 0.4.2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5888,7 +5888,7 @@ dependencies = [ "cargo_toml", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6024,7 +6024,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6038,7 +6038,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6049,7 +6049,7 @@ checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6060,7 +6060,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6194,10 +6194,11 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", "windows-sys 0.52.0", @@ -6313,7 +6314,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6572,7 +6573,7 @@ dependencies = [ "data-encoding", "libp2p-identity", "multibase", - "multihash 0.19.2", + "multihash 0.19.3", "percent-encoding", "serde", "static_assertions", @@ -6627,9 +6628,9 @@ dependencies = [ [[package]] name = "multihash" -version = "0.19.2" +version = "0.19.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc41f430805af9d1cf4adae4ed2149c759b877b01d909a1f40256188d09345d2" +checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d" dependencies = [ "core2", "unsigned-varint 0.8.0", @@ -6669,26 +6670,6 @@ dependencies = [ "unsigned-varint 0.7.2", ] -[[package]] -name = "munge" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64142d38c84badf60abf06ff9bd80ad2174306a5b11bd4706535090a30a419df" -dependencies = [ - "munge_macro", -] - -[[package]] -name = "munge_macro" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb5c1d8184f13f7d0ccbeeca0def2f9a181bce2624302793005f5ca8aa62e5e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.89", -] - [[package]] name = "nalgebra" version = "0.32.6" @@ -6713,7 +6694,7 @@ checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7023,7 +7004,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7115,7 +7096,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -8200,6 +8181,24 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-halving-mint" +version = "0.1.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-assets", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-identity" version = "37.0.0" @@ -8766,7 +8765,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9416,7 +9415,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9457,7 +9456,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10625,7 +10624,7 @@ dependencies = [ "polkavm-common", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10635,7 +10634,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" dependencies = [ "polkavm-derive-impl", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10831,7 +10830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10915,7 +10914,7 @@ checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10926,7 +10925,7 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10972,7 +10971,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11034,7 +11033,7 @@ dependencies = [ "prost 0.12.6", "prost-types 0.12.6", "regex", - "syn 2.0.89", + "syn 2.0.90", "tempfile", ] @@ -11061,7 +11060,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11097,16 +11096,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" dependencies = [ - "ptr_meta_derive 0.1.4", -] - -[[package]] -name = "ptr_meta" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90" -dependencies = [ - "ptr_meta_derive 0.3.0", + "ptr_meta_derive", ] [[package]] @@ -11120,22 +11110,11 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "ptr_meta_derive" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.89", -] - [[package]] name = "quanta" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +checksum = "773ce68d0bb9bc7ef20be3536ffe94e223e1f365bd374108b2659fac0c65cfe6" dependencies = [ "crossbeam-utils", "libc", @@ -11286,15 +11265,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "rancor" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf5f7161924b9d1cea0e4cabc97c372cea92b5f927fc13c6bca67157a0ad947" -dependencies = [ - "ptr_meta 0.3.0", -] - [[package]] name = "rand" version = "0.8.5" @@ -11458,7 +11428,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11488,9 +11458,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -11530,12 +11500,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" -[[package]] -name = "rend" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35e8a6bf28cd121053a66aa2e6a2e3eaffad4a60012179f0e864aa5ffeff215" - [[package]] name = "resolv-conf" version = "0.7.0" @@ -11565,13 +11529,13 @@ dependencies = [ "libc", "log", "once_cell", - "rkyv 0.4.3", + "rkyv", "spin 0.5.2", "untrusted 0.7.1", "winapi", "xous", "xous-api-names", - "xous-ipc 0.9.63", + "xous-ipc", ] [[package]] @@ -11605,26 +11569,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70de01b38fe7baba4ecdd33b777096d2b326993d8ea99bc5b6ede691883d3010" dependencies = [ "memoffset 0.6.5", - "ptr_meta 0.1.4", - "rkyv_derive 0.4.0", -] - -[[package]] -name = "rkyv" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b11a153aec4a6ab60795f8ebe2923c597b16b05bb1504377451e705ef1a45323" -dependencies = [ - "bytes", - "hashbrown 0.15.2", - "indexmap 2.2.6", - "munge", - "ptr_meta 0.3.0", - "rancor", - "rend", - "rkyv_derive 0.8.9", - "tinyvec", - "uuid", + "ptr_meta", + "rkyv_derive", ] [[package]] @@ -11638,17 +11584,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "rkyv_derive" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb382a4d9f53bd5c0be86b10d8179c3f8a14c30bf774ff77096ed6581e35981" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.89", -] - [[package]] name = "rlp" version = "0.5.2" @@ -11993,7 +11928,7 @@ dependencies = [ "log", "once_cell", "ring 0.17.8", - "rustls-pki-types 1.10.0", + "rustls-pki-types 1.10.1", "rustls-webpki 0.102.8", "subtle 2.6.1", "zeroize", @@ -12019,7 +11954,7 @@ checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ "openssl-probe", "rustls-pemfile 2.2.0", - "rustls-pki-types 1.10.0", + "rustls-pki-types 1.10.1", "schannel", "security-framework", ] @@ -12039,7 +11974,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "rustls-pki-types 1.10.0", + "rustls-pki-types 1.10.1", ] [[package]] @@ -12050,9 +11985,9 @@ checksum = "a47003264dea418db67060fa420ad16d0d2f8f0a0360d825c00e177ac52cb5d8" [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" [[package]] name = "rustls-platform-verifier" @@ -12108,7 +12043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring 0.17.8", - "rustls-pki-types 1.10.0", + "rustls-pki-types 1.10.1", "untrusted 0.9.0", ] @@ -12187,7 +12122,7 @@ dependencies = [ "libp2p", "linked_hash_set", "log", - "multihash 0.19.2", + "multihash 0.19.3", "parity-scale-codec", "prost 0.12.6", "prost-build 0.12.6", @@ -12277,7 +12212,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -12942,7 +12877,7 @@ dependencies = [ "litep2p", "log", "multiaddr 0.18.2", - "multihash 0.19.2", + "multihash 0.19.3", "rand", "thiserror", "zeroize", @@ -13283,7 +13218,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -13593,7 +13528,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -14049,7 +13984,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -14282,7 +14217,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2407#f2081 dependencies = [ "quote", "sp-crypto-hashing", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -14301,7 +14236,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2407#f2081 dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -14531,7 +14466,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -14716,7 +14651,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -14977,7 +14912,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -15132,9 +15067,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -15161,7 +15096,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -15260,7 +15195,7 @@ checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -15271,7 +15206,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -15335,9 +15270,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.37" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -15356,9 +15291,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -15414,7 +15349,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -15606,7 +15541,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -15649,7 +15584,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -15949,12 +15884,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" - [[package]] name = "valuable" version = "0.1.0" @@ -16064,7 +15993,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -16098,7 +16027,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -16450,7 +16379,7 @@ version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ - "rustls-pki-types 1.10.0", + "rustls-pki-types 1.10.1", ] [[package]] @@ -16976,7 +16905,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -17032,39 +16961,39 @@ dependencies = [ [[package]] name = "xous" -version = "0.9.64" +version = "0.9.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a70ee183d699fd609d92b17af7a39b60908130af8dc7089095f713bcae85a12b" +checksum = "b4ca3a121c4c2f9751469bbf19e777a9aaf15ad46a35d153a5e26d4b382e5171" dependencies = [ "lazy_static", ] [[package]] name = "xous-api-log" -version = "0.1.61" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca4b418619005a69b15fbb3832eb974440a3b4d14639d08211af0e307f90440c" +checksum = "8fc03209afc102ee02405cdf80a8bc133a656a2cd5ed92e0194e1008786d5281" dependencies = [ "log", "num-derive", "num-traits", "xous", - "xous-ipc 0.10.2", + "xous-ipc", ] [[package]] name = "xous-api-names" -version = "0.9.63" +version = "0.9.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efe645ec314e1d233a9a97ecd84d3f7b9500b5726eb429af13d7a11f36ec5df7" +checksum = "0029321b0a8b0dde9adee3ee510d288703f3045ab7e23c46cc48f45c16020e88" dependencies = [ "log", "num-derive", "num-traits", - "rkyv 0.8.9", + "rkyv", "xous", "xous-api-log", - "xous-ipc 0.10.2", + "xous-ipc", ] [[package]] @@ -17074,18 +17003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47c88158f43d35c03454af8eba9d6f85ad140a71c150512cdbe68bf54bd8dc34" dependencies = [ "bitflags 1.3.2", - "rkyv 0.4.3", - "xous", -] - -[[package]] -name = "xous-ipc" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "696ba6ec9c5cc8218f55d8a04ae7ef9311ed0ec92699f4d509317883ad04769a" -dependencies = [ - "bitflags 1.3.2", - "rkyv 0.8.9", + "rkyv", "xous", ] @@ -17130,7 +17048,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -17150,7 +17068,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] diff --git a/parachain/Cargo.toml b/parachain/Cargo.toml index 9f79774779..9a6b259916 100644 --- a/parachain/Cargo.toml +++ b/parachain/Cargo.toml @@ -11,6 +11,7 @@ members = [ 'pallets/collab-ai/common', 'pallets/collab-ai/curator', 'pallets/collab-ai/guardian', + 'pallets/collab-ai/halving-mint', 'pallets/collab-ai/pool-proposal', 'pallets/collab-ai/investing-pool', 'pallets/extrinsic-filter', @@ -293,6 +294,7 @@ pallet-evm-precompile-pool-proposal = { path = "precompiles/collab-ai/pool-propo pallet-evm-precompile-investing-pool = { path = "precompiles/collab-ai/investing-pool", default-features = false } pallet-evm-assertions = { path = "pallets/evm-assertions", default-features = false } +pallet-halving-mint = { path = "pallets/halving-mint", default-features = false } # CollabAI local pallet-aiusd-convertor = { path = "pallets/collab-ai/aiusd-convertor", default-features = false } diff --git a/parachain/pallets/collab-ai/halving-mint/Cargo.toml b/parachain/pallets/collab-ai/halving-mint/Cargo.toml new file mode 100644 index 0000000000..b6dc116c12 --- /dev/null +++ b/parachain/pallets/collab-ai/halving-mint/Cargo.toml @@ -0,0 +1,60 @@ +[package] +name = 'pallet-halving-mint' +description = 'pallet to mint tokens in a halving way similar to BTC' +authors = ['Trust Computing GmbH '] +edition = '2021' +homepage = 'https://litentry.com/' +license = 'GPL-3.0' +repository = 'https://github.com/litentry/litentry-parachain' +version = '0.1.0' + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[lints] +workspace = true + +[dependencies] +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } +serde = { workspace = true } + +frame-benchmarking = { workspace = true, optional = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +pallet-assets = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } + +[dev-dependencies] +sp-core = { workspace = true } +sp-io = { workspace = true } +pallet-balances = { workspace = true } + +[features] +default = ["std"] +std = [ + "parity-scale-codec/std", + "serde/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "scale-info/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "pallet-assets/std", + "pallet-balances/std", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/parachain/pallets/collab-ai/halving-mint/src/lib.rs b/parachain/pallets/collab-ai/halving-mint/src/lib.rs new file mode 100644 index 0000000000..e3d82912f9 --- /dev/null +++ b/parachain/pallets/collab-ai/halving-mint/src/lib.rs @@ -0,0 +1,353 @@ +// Copyright 2020-2024 Trust Computing GmbH. +// This file is part of Litentry. +// +// Litentry 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. +// +// Litentry 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 Litentry. If not, see . + +//! # Pallet halving-mint +//! +//! This pallet mints the (native) token in a halving way. +//! +//! It will be parameterized with the total issuance count and halving interval (in blocks), +//! The minted token is deposited to the `beneficiary` account, which should be a privated +//! account derived from the PalletId(similar to treasury). There's a trait `OnTokenMinted` +//! to hook the callback into other pallet. +//! +//! The main parameters: +//! - total issuance +//! - halving interval +//! - beneficiary account +//! are defined as runtime constants. It implies that once onboarded, they can be changed +//! only by runtime upgrade. Thus it has a stronger guarantee in comparison to extrinsics. + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::too_many_arguments)] + +use frame_support::traits::tokens::{ + fungibles::{metadata::Mutate as MMutate, Create, Inspect, Mutate}, + AssetId, Balance, +}; +pub use pallet::*; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +mod traits; +pub use traits::OnTokenMinted; + +/// an on/off flag, used in both `MintState` and `OnTokenMintedState` +#[derive( + PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, Encode, Decode, Debug, TypeInfo, +)] +pub enum State { + #[default] + #[codec(index = 0)] + Stopped, + #[codec(index = 1)] + Running, +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::{pallet_prelude::*, traits::StorageVersion, PalletId}; + use frame_system::pallet_prelude::{BlockNumberFor, *}; + use sp_runtime::{ + traits::{AccountIdConversion, One, Zero}, + Saturating, + }; + + const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + #[pallet::without_storage_info] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::config] + pub trait Config: frame_system::Config { + type Assets: Inspect + + Mutate + + Create + + MMutate; + type AssetId: AssetId + Copy; + type AssetBalance: Balance; + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; + /// The origin to control the minting configuration + type ManagerOrigin: EnsureOrigin; + /// The total issuance of the (native) token + #[pallet::constant] + type TotalIssuance: Get; + /// Halving internal in blocks, we force u32 type, BlockNumberFor implements + /// AtLeast32BitUnsigned so it's safe + #[pallet::constant] + type HalvingInterval: Get; + /// The beneficiary PalletId, used for deriving its sovereign AccountId + #[pallet::constant] + type BeneficiaryId: Get; + /// Hook for other pallets to deal with OnTokenMinted event + type OnTokenMinted: OnTokenMinted; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event, I: 'static = ()> { + MintStateChanged { new_state: State }, + OnTokenMintedStateChanged { new_state: State }, + MintStarted { asset_id: T::AssetId, start_block: BlockNumberFor }, + Minted { asset_id: T::AssetId, to: T::AccountId, amount: T::AssetBalance }, + } + + #[pallet::error] + pub enum Error { + MintStateUnchanged, + OnTokenMintedStateUnchanged, + MintAlreadyStarted, + MintNotStarted, + StartBlockTooEarly, + SkippedBlocksOverflow, + } + + #[pallet::storage] + #[pallet::getter(fn mint_asset_id)] + pub type MintAssetId, I: 'static = ()> = StorageValue<_, T::AssetId, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn mint_state)] + pub type MintState, I: 'static = ()> = StorageValue<_, State, ValueQuery>; + + /// If the `OnTokenMinted` callback is stopped or not + #[pallet::storage] + #[pallet::getter(fn on_token_minted_state)] + pub type OnTokenMintedState, I: 'static = ()> = StorageValue<_, State, ValueQuery>; + + /// the block number from which the minting is started, `None` means minting + /// is not started yet + #[pallet::storage] + #[pallet::getter(fn start_block)] + pub type StartBlock, I: 'static = ()> = + StorageValue<_, BlockNumberFor, OptionQuery>; + + /// Number of skipped blocks being counted when `MintState` is `Stopped` + #[pallet::storage] + #[pallet::getter(fn skipped_blocks)] + pub type SkippedBlocks, I: 'static = ()> = + StorageValue<_, BlockNumberFor, ValueQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + pub mint_state: State, + pub on_token_minted_state: State, + pub start_block: Option>, + #[serde(skip)] + pub phantom: PhantomData, + } + + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + Self { + mint_state: State::Stopped, + on_token_minted_state: State::Stopped, + start_block: None, + phantom: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl, I: 'static> BuildGenesisConfig for GenesisConfig { + fn build(&self) { + MintState::::put(self.mint_state); + OnTokenMintedState::::put(self.on_token_minted_state); + if let Some(n) = self.start_block { + StartBlock::::put(n); + } + } + } + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + fn on_initialize(now: BlockNumberFor) -> Weight { + let mut weight = Weight::zero(); + if let Some(start_block) = Self::start_block() { + if Self::mint_state() == State::Running { + let skipped_blocks = Self::skipped_blocks(); + // 3 reads: `mint_state`, `start_block`, `skipped_blocks` + weight = weight.saturating_add(T::DbWeight::get().reads_writes(3, 0)); + + if now < start_block.saturating_add(skipped_blocks) { + return weight; + } + + let halving_interval = T::HalvingInterval::get(); + + // calculate the amount of initially minted tokens before first halving + let mut minted = T::TotalIssuance::get() / (halving_interval * 2).into(); + // halving round index + let halving_round = (now - start_block.saturating_add(skipped_blocks)) + / halving_interval.into(); + // beneficiary account + let to = Self::beneficiary_account(); + + // 2 reads: `total_issuance`, `halving_interval` + weight = weight.saturating_add(T::DbWeight::get().reads_writes(2, 0)); + + // if we want to use bit shift, we need to: + // 1. know the overlfow limit similar to what bitcoin has: `if (halvings >= + // 64) return 0;` so 127 for u128 + // 2. coerce the `halving_round` to u32 + // but both `halving_round` and `minted` are associated types that need to be + // defined during runtime binding thus plain division is used + let mut i = BlockNumberFor::::zero(); + while i < halving_round { + minted /= 2u32.into(); + i += BlockNumberFor::::one(); + } + + // theoreticlaly we can deal with the minted tokens directly in the trait impl + // pallet, without depositing to an account first. + // but the purpose of having the extra logic is to make sure the tokens are + // minted to the beneficiary account, regardless of what happens callback. Even + // if the callback errors out, it's guaranteed that the tokens are + // already minted (and stored on an account), which resonates with the "fair + // launch" concept. + // + // Also imagine there's no callback impl, in this case the tokens will still be + // minted and accumulated. + if let Some(id) = Self::mint_asset_id() { + if let Ok(actual) = T::Assets::mint_into(id, &to, minted) { + Self::deposit_event(Event::Minted { + asset_id: id, + to: to.clone(), + amount: actual, + }) + } + + if Self::on_token_minted_state() == State::Running { + weight = weight + .saturating_add(T::OnTokenMinted::token_minted(id, to, minted)); + } + } + + // 2 reads: `asset_id`, `on_token_minted_state` + weight = weight.saturating_add(T::DbWeight::get().reads_writes(2, 0)); + } else { + // we should have minted tokens but it's forcibly stopped + let skipped_blocks = + Self::skipped_blocks().saturating_add(BlockNumberFor::::one()); + SkippedBlocks::::put(skipped_blocks); + // 1 read, 1 write: `SkippedBlocks` + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + } + } + weight + } + } + + // TODO: benchmarking and WeightInfo + // IMO it's not **that** bad to use constant weight for extrinsics now as they are simple calls + // and should only be called once or very few times. + #[pallet::call] + impl, I: 'static> Pallet { + /// Set the state of the minting, it essentially "pause" and "resume" the minting process. + #[pallet::call_index(0)] + #[pallet::weight((195_000_000, DispatchClass::Normal))] + pub fn set_mint_state(origin: OriginFor, state: State) -> DispatchResultWithPostInfo { + T::ManagerOrigin::ensure_origin(origin)?; + ensure!(StartBlock::::get().is_some(), Error::::MintNotStarted); + ensure!(state != Self::mint_state(), Error::::MintStateUnchanged); + MintState::::put(state); + Self::deposit_event(Event::MintStateChanged { new_state: state }); + Ok(Pays::No.into()) + } + + #[pallet::call_index(1)] + #[pallet::weight((195_000_000, DispatchClass::Normal))] + pub fn set_on_token_minted_state( + origin: OriginFor, + state: State, + ) -> DispatchResultWithPostInfo { + T::ManagerOrigin::ensure_origin(origin)?; + ensure!(StartBlock::::get().is_some(), Error::::MintNotStarted); + ensure!( + state != Self::on_token_minted_state(), + Error::::OnTokenMintedStateUnchanged + ); + OnTokenMintedState::::put(state); + Self::deposit_event(Event::OnTokenMintedStateChanged { new_state: state }); + Ok(Pays::No.into()) + } + + /// Start mint from next block, this is the earliest block the next minting can happen, + /// as we already missed the intialization of current block and we don't do retroactive + /// minting + #[pallet::call_index(2)] + #[pallet::weight((195_000_000, DispatchClass::Normal))] + pub fn start_mint_from_next_block( + origin: OriginFor, + id: T::AssetId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> DispatchResultWithPostInfo { + Self::start_mint_from_block( + origin, + frame_system::Pallet::::block_number() + BlockNumberFor::::one(), + id, + name, + symbol, + decimals, + ) + } + + /// Start mint from a given block that is larger than the current block number + #[pallet::call_index(3)] + #[pallet::weight((195_000_000, DispatchClass::Normal))] + pub fn start_mint_from_block( + origin: OriginFor, + start_block: BlockNumberFor, + id: T::AssetId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> DispatchResultWithPostInfo { + T::ManagerOrigin::ensure_origin(origin)?; + ensure!(StartBlock::::get().is_none(), Error::::MintAlreadyStarted); + ensure!( + start_block > frame_system::Pallet::::block_number(), + Error::::StartBlockTooEarly + ); + MintState::::put(State::Running); + OnTokenMintedState::::put(State::Running); + StartBlock::::put(start_block); + T::Assets::create(id, Self::beneficiary_account(), true, 1u32.into())?; + T::Assets::set(id, &Self::beneficiary_account(), name, symbol, decimals)?; + MintAssetId::::put(id); + Self::deposit_event(Event::MintStarted { asset_id: id, start_block }); + Ok(Pays::No.into()) + } + } + + impl, I: 'static> Pallet { + pub fn beneficiary_account() -> T::AccountId { + T::BeneficiaryId::get().into_account_truncating() + } + } +} diff --git a/parachain/pallets/collab-ai/halving-mint/src/mock.rs b/parachain/pallets/collab-ai/halving-mint/src/mock.rs new file mode 100644 index 0000000000..469bef0343 --- /dev/null +++ b/parachain/pallets/collab-ai/halving-mint/src/mock.rs @@ -0,0 +1,148 @@ +// Copyright 2020-2024 Trust Computing GmbH. +// This file is part of Litentry. +// +// Litentry 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. +// +// Litentry 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 Litentry. If not, see . + +use crate::{self as pallet_halving_mint, Config, Instance1, OnTokenMinted}; +use frame_support::pallet_prelude::*; +use frame_support::traits::tokens::{fungibles::Mutate, Preservation}; +use frame_support::{ + construct_runtime, derive_impl, parameter_types, traits::AsEnsureOriginWithArg, PalletId, +}; +use frame_system::{EnsureRoot, EnsureSigned}; +use sp_core::{ConstU32, ConstU64}; +use sp_runtime::BuildStorage; + +type AccountId = u64; +type Balance = u64; +type AssetId = u64; + +construct_runtime!( + pub enum Test + { + System: frame_system, + Assets: pallet_assets, + Balances: pallet_balances, + HalvingMint: pallet_halving_mint::, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type Block = frame_system::mocking::MockBlock; + type AccountData = pallet_balances::AccountData; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 1; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Test { + type Balance = Balance; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; +} + +parameter_types! { + pub const AssetDeposit: Balance = 0; + pub const AssetAccountDeposit: Balance = 0; + pub const ApprovalDeposit: Balance = 0; + pub const AssetsStringLimit: u32 = 50; + pub const MetadataDepositBase: Balance = 0; + pub const MetadataDepositPerByte: Balance = 0; +} + +impl pallet_assets::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type AssetId = AssetId; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; + type AssetDeposit = AssetDeposit; + type AssetAccountDeposit = AssetAccountDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type WeightInfo = (); + type RemoveItemsLimit = ConstU32<0>; + type AssetIdParameter = AssetId; + type CallbackHandle = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} + +parameter_types! { + pub const BeneficiaryId: PalletId = PalletId(*b"lty/hlvm"); + pub const TestAssetId: AssetId = 1; +} + +impl pallet_halving_mint::Config for Test { + type RuntimeEvent = RuntimeEvent; + type AssetBalance = Balance; + type AssetId = AssetId; + type Assets = Assets; + type ManagerOrigin = frame_system::EnsureRoot; + type TotalIssuance = ConstU64<1000>; + type HalvingInterval = ConstU32<10>; + type BeneficiaryId = BeneficiaryId; + type OnTokenMinted = TransferOnTokenMinted; +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(HalvingMint::beneficiary_account(), 10)], + } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext: sp_io::TestExternalities = t.into(); + ext.execute_with(|| { + System::set_block_number(1); + }); + ext +} + +pub fn run_to_block(n: u64) { + while System::block_number() < n { + if System::block_number() > 1 { + System::on_finalize(System::block_number()); + } + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + HalvingMint::on_initialize(System::block_number()); + } +} + +pub struct TransferOnTokenMinted(sp_std::marker::PhantomData<(T, I)>); + +impl OnTokenMinted for TransferOnTokenMinted +where + T: frame_system::Config + Config, + T::Assets: Mutate, +{ + fn token_minted( + asset_id: T::AssetId, + beneficiary: T::AccountId, + amount: T::AssetBalance, + ) -> Weight { + let _ = T::Assets::transfer(asset_id, &beneficiary, &1, amount, Preservation::Expendable) + .unwrap(); + Weight::zero() + } +} diff --git a/parachain/pallets/collab-ai/halving-mint/src/tests.rs b/parachain/pallets/collab-ai/halving-mint/src/tests.rs new file mode 100644 index 0000000000..074534ef8b --- /dev/null +++ b/parachain/pallets/collab-ai/halving-mint/src/tests.rs @@ -0,0 +1,224 @@ +// Copyright 2020-2024 Trust Computing GmbH. +// This file is part of Litentry. +// +// Litentry 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. +// +// Litentry 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 Litentry. If not, see . + +use crate::{mock::*, Error, Event, Inspect, Instance1, State}; +use frame_support::{assert_noop, assert_ok}; + +#[test] +fn set_mint_state_check_works() { + new_test_ext().execute_with(|| { + assert_eq!(HalvingMint::mint_state(), State::Stopped); + assert_noop!( + HalvingMint::set_mint_state(RuntimeOrigin::signed(1), State::Running), + sp_runtime::DispatchError::BadOrigin, + ); + assert_noop!( + HalvingMint::set_mint_state(RuntimeOrigin::root(), State::Running), + Error::::MintNotStarted, + ); + assert_ok!(HalvingMint::start_mint_from_next_block( + RuntimeOrigin::root(), + 1, + "Test".as_bytes().to_vec(), + "Test".as_bytes().to_vec(), + 18 + )); + assert_eq!(HalvingMint::mint_state(), State::Running); + assert_noop!( + HalvingMint::set_mint_state(RuntimeOrigin::root(), State::Running), + Error::::MintStateUnchanged, + ); + assert_ok!(HalvingMint::set_mint_state(RuntimeOrigin::root(), State::Stopped)); + assert_eq!(HalvingMint::mint_state(), State::Stopped); + System::assert_last_event(Event::MintStateChanged { new_state: State::Stopped }.into()); + }); +} + +#[test] +fn start_mint_too_early_fails() { + new_test_ext().execute_with(|| { + assert_eq!(System::block_number(), 1); + assert_noop!( + HalvingMint::start_mint_from_block( + RuntimeOrigin::root(), + 0, + 1, + "Test".as_bytes().to_vec(), + "Test".as_bytes().to_vec(), + 18 + ), + Error::::StartBlockTooEarly, + ); + assert_noop!( + HalvingMint::start_mint_from_block( + RuntimeOrigin::root(), + 1, + 1, + "Test".as_bytes().to_vec(), + "Test".as_bytes().to_vec(), + 18 + ), + Error::::StartBlockTooEarly, + ); + assert_ok!(HalvingMint::start_mint_from_block( + RuntimeOrigin::root(), + 2, + 1, + "Test".as_bytes().to_vec(), + "Test".as_bytes().to_vec(), + 18 + )); + System::assert_last_event(Event::MintStarted { asset_id: 1, start_block: 2 }.into()); + }); +} + +#[test] +fn halving_mint_works() { + new_test_ext().execute_with(|| { + let beneficiary = HalvingMint::beneficiary_account(); + + assert_eq!(System::block_number(), 1); + assert_eq!(Assets::total_issuance(1), 0); + assert_eq!(Assets::balance(1, beneficiary), 0); + assert_ok!(HalvingMint::start_mint_from_next_block( + RuntimeOrigin::root(), + 1, + "Test".as_bytes().to_vec(), + "Test".as_bytes().to_vec(), + 18 + )); + System::assert_last_event(Event::MintStarted { asset_id: 1, start_block: 2 }.into()); + + run_to_block(2); + // 50 tokens are minted + assert_eq!(Assets::total_issuance(1), 50); + assert_eq!(Assets::balance(1, beneficiary), 0); + assert_eq!(Assets::balance(1, 1), 50); + + run_to_block(11); + assert_eq!(Assets::total_issuance(1), 500); + assert_eq!(Assets::balance(1, 1), 500); + + run_to_block(12); + // the first halving + assert_eq!(Assets::total_issuance(1), 525); + assert_eq!(Assets::balance(1, 1), 525); + + run_to_block(22); + // the second halving + assert_eq!(Assets::total_issuance(1), 762); + assert_eq!(Assets::balance(1, 1), 762); + + run_to_block(52); + // the fifth halving - only 1 token is minted + assert_eq!(Assets::total_issuance(1), 961); + assert_eq!(Assets::balance(1, 1), 961); + + run_to_block(62); + // the sixth halving - but 0 tokens will be minted + assert_eq!(Assets::total_issuance(1), 970); + assert_eq!(Assets::balance(1, 1), 970); + + run_to_block(1_000); + // no changes since the sixth halving, the total minted token will be fixated on 970, + // the "missing" 30 comes from the integer division and the total_issuance is too small. + // + // we'll have much accurate result in reality where token unit is 18 decimal + assert_eq!(Assets::total_issuance(1), 970); + assert_eq!(Assets::balance(1, 1), 970); + }); +} + +#[test] +fn set_on_token_minted_state_works() { + new_test_ext().execute_with(|| { + let beneficiary = HalvingMint::beneficiary_account(); + + assert_ok!(HalvingMint::start_mint_from_next_block( + RuntimeOrigin::root(), + 1, + "Test".as_bytes().to_vec(), + "Test".as_bytes().to_vec(), + 18 + )); + assert_ok!(HalvingMint::set_on_token_minted_state(RuntimeOrigin::root(), State::Stopped)); + System::assert_last_event( + Event::OnTokenMintedStateChanged { new_state: State::Stopped }.into(), + ); + + run_to_block(2); + // 50 tokens are minted, but none is transferred away + assert_eq!(Assets::total_issuance(1), 50); + assert_eq!(Assets::balance(1, beneficiary), 50); + assert_eq!(Assets::balance(1, 1), 0); + + run_to_block(10); + assert_ok!(HalvingMint::set_on_token_minted_state(RuntimeOrigin::root(), State::Running)); + System::assert_last_event( + Event::OnTokenMintedStateChanged { new_state: State::Running }.into(), + ); + + run_to_block(11); + // start to transfer token + assert_eq!(Assets::total_issuance(1), 500); + assert_eq!(Assets::balance(1, beneficiary), 450); + assert_eq!(Assets::balance(1, 1), 50); + }); +} + +#[test] +fn set_mint_state_works() { + new_test_ext().execute_with(|| { + let beneficiary = HalvingMint::beneficiary_account(); + + assert_ok!(HalvingMint::start_mint_from_next_block( + RuntimeOrigin::root(), + 1, + "Test".as_bytes().to_vec(), + "Test".as_bytes().to_vec(), + 18 + )); + + run_to_block(2); + assert_eq!(Assets::total_issuance(1), 50); + assert_eq!(Assets::balance(1, beneficiary), 0); + assert_eq!(Assets::balance(1, 1), 50); + // stop the minting + assert_ok!(HalvingMint::set_mint_state(RuntimeOrigin::root(), State::Stopped)); + + run_to_block(3); + // no new tokens should be minted + assert_eq!(Assets::total_issuance(1), 50); + assert_eq!(Assets::balance(1, beneficiary), 0); + assert_eq!(Assets::balance(1, 1), 50); + + run_to_block(4); + // resume the minting + assert_ok!(HalvingMint::set_mint_state(RuntimeOrigin::root(), State::Running)); + + run_to_block(5); + assert_eq!(Assets::total_issuance(1), 100); + assert_eq!(Assets::balance(1, beneficiary), 0); + assert_eq!(Assets::balance(1, 1), 100); + assert_eq!(HalvingMint::skipped_blocks(), 2); + + // the first halving should be delayed to block 14 + run_to_block(14); + assert_eq!(Assets::total_issuance(1), 525); + assert_eq!(Assets::balance(1, beneficiary), 0); + assert_eq!(Assets::balance(1, 1), 525); + }); +} diff --git a/parachain/pallets/collab-ai/halving-mint/src/traits.rs b/parachain/pallets/collab-ai/halving-mint/src/traits.rs new file mode 100644 index 0000000000..19bfdcebf7 --- /dev/null +++ b/parachain/pallets/collab-ai/halving-mint/src/traits.rs @@ -0,0 +1,28 @@ +// Copyright 2020-2024 Trust Computing GmbH. +// This file is part of Litentry. +// +// Litentry 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. +// +// Litentry 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 Litentry. If not, see . + +/// Traits for pallet-halving-mint +use frame_support::pallet_prelude::Weight; + +pub trait OnTokenMinted { + fn token_minted(asset_id: AssetId, beneficiary: AccountId, amount: Balance) -> Weight; +} + +impl OnTokenMinted for () { + fn token_minted(_asset_id: AssetId, _beneficiary: AccountId, _amount: Balance) -> Weight { + Weight::zero() + } +}