difftreelog
Merge remote-tracking branch 'origin/develop' into develop
in: master
# Conflicts: # tests/src/contracts.test.ts
49 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12,11 +12,11 @@
[[package]]
name = "addr2line"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
+checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423"
dependencies = [
- "gimli 0.22.0",
+ "gimli 0.23.0",
]
[[package]]
@@ -55,7 +55,7 @@
"aes",
"block-cipher",
"ghash",
- "subtle 2.3.0",
+ "subtle 2.4.0",
]
[[package]]
@@ -95,10 +95,16 @@
checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
[[package]]
+name = "ahash"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
+
+[[package]]
name = "aho-corasick"
-version = "0.7.14"
+version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b476ce7103678b0c6d3d395dbbae31d48ff910bd28be979ba5d48c6351131d0d"
+checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
@@ -134,9 +140,9 @@
[[package]]
name = "anyhow"
-version = "1.0.33"
+version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c"
+checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4"
[[package]]
name = "approx"
@@ -149,9 +155,9 @@
[[package]]
name = "arc-swap"
-version = "0.4.7"
+version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
+checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8"
[[package]]
name = "arrayref"
@@ -170,9 +176,9 @@
[[package]]
name = "arrayvec"
-version = "0.5.1"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
+checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "asn1_der"
@@ -206,36 +212,36 @@
[[package]]
name = "async-executor"
-version = "1.3.0"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d373d78ded7d0b3fa8039375718cde0aace493f2e34fb60f51cbf567562ca801"
+checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146"
dependencies = [
"async-task",
"concurrent-queue",
"fastrand",
"futures-lite",
- "once_cell 1.4.1",
+ "once_cell 1.5.2",
"vec-arena",
]
[[package]]
name = "async-global-executor"
-version = "1.4.0"
+version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0659b83a146398616883aa5199cdd1b055ec088a83c9a338eab3534f33f0622e"
+checksum = "73079b49cd26b8fd5a15f68fc7707fc78698dc2a3d61430f2a7a9430230dfa04"
dependencies = [
"async-executor",
"async-io",
"futures-lite",
"num_cpus",
- "once_cell 1.4.1",
+ "once_cell 1.5.2",
]
[[package]]
name = "async-io"
-version = "1.1.10"
+version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d54bc4c1c7292475efb2253227dbcfad8fe1ca4c02bc62c510cc2f3da5c4704e"
+checksum = "9315f8f07556761c3e48fec2e6b276004acf426e6dc068b2c2251854d65ee0fd"
dependencies = [
"concurrent-queue",
"fastrand",
@@ -243,7 +249,7 @@
"libc",
"log",
"nb-connect",
- "once_cell 1.4.1",
+ "once_cell 1.5.2",
"parking",
"polling",
"vec-arena",
@@ -261,16 +267,34 @@
]
[[package]]
+name = "async-process"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8cea09c1fb10a317d1b5af8024eeba256d6554763e85ecd90ff8df31c7bbda"
+dependencies = [
+ "async-io",
+ "blocking",
+ "cfg-if 0.1.10",
+ "event-listener",
+ "futures-lite",
+ "once_cell 1.5.2",
+ "signal-hook",
+ "winapi 0.3.9",
+]
+
+[[package]]
name = "async-std"
-version = "1.6.5"
+version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9fa76751505e8df1c7a77762f60486f60c71bbd9b8557f4da6ad47d083732ed"
+checksum = "8f9f84f1280a2b436a2c77c2582602732b6c2f4321d5494d6e799e6c367859a8"
dependencies = [
+ "async-channel",
"async-global-executor",
"async-io",
"async-mutex",
+ "async-process",
"blocking",
- "crossbeam-utils",
+ "crossbeam-utils 0.8.1",
"futures-channel",
"futures-core",
"futures-io",
@@ -280,8 +304,8 @@
"log",
"memchr",
"num_cpus",
- "once_cell 1.4.1",
- "pin-project-lite",
+ "once_cell 1.5.2",
+ "pin-project-lite 0.2.0",
"pin-utils",
"slab",
"wasm-bindgen-futures",
@@ -289,9 +313,9 @@
[[package]]
name = "async-task"
-version = "4.0.2"
+version = "4.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ab27c1aa62945039e44edaeee1dc23c74cc0c303dd5fe0fb462a184f1c3a518"
+checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
[[package]]
name = "async-tls"
@@ -299,7 +323,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df097e3f506bec0e1a24f06bb3c962c228f36671de841ff579cb99f371772634"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"rustls",
"webpki",
"webpki-roots 0.19.0",
@@ -307,9 +331,9 @@
[[package]]
name = "async-trait"
-version = "0.1.41"
+version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0"
+checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d"
dependencies = [
"proc-macro2",
"quote",
@@ -353,15 +377,15 @@
[[package]]
name = "backtrace"
-version = "0.3.53"
+version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707b586e0e2f247cbde68cdd2c3ce69ea7b7be43e1c5b426e37c9319c4b9838e"
+checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598"
dependencies = [
"addr2line",
"cfg-if 1.0.0",
"libc",
"miniz_oxide",
- "object 0.21.1",
+ "object 0.22.0",
"rustc-demangle",
]
@@ -384,6 +408,12 @@
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
[[package]]
+name = "base64"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+
+[[package]]
name = "bincode"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -456,15 +486,13 @@
[[package]]
name = "blake2"
-version = "0.9.0"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84ce5b6108f8e154604bd4eb76a2f726066c3464d5a552a4229262a18c9bb471"
+checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4"
dependencies = [
- "byte-tools",
- "byteorder 1.3.4",
"crypto-mac 0.8.0",
"digest 0.9.0",
- "opaque-debug 0.2.3",
+ "opaque-debug 0.3.0",
]
[[package]]
@@ -479,23 +507,23 @@
[[package]]
name = "blake2b_simd"
-version = "0.5.10"
+version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
+checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
dependencies = [
"arrayref",
- "arrayvec 0.5.1",
+ "arrayvec 0.5.2",
"constant_time_eq",
]
[[package]]
name = "blake2s_simd"
-version = "0.5.10"
+version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44"
+checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2"
dependencies = [
"arrayref",
- "arrayvec 0.5.1",
+ "arrayvec 0.5.2",
"constant_time_eq",
]
@@ -556,7 +584,7 @@
"atomic-waker",
"fastrand",
"futures-lite",
- "once_cell 1.4.1",
+ "once_cell 1.5.2",
]
[[package]]
@@ -566,10 +594,16 @@
checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb"
[[package]]
+name = "bs58"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
+
+[[package]]
name = "bstr"
-version = "0.2.13"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931"
+checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf"
dependencies = [
"memchr",
]
@@ -635,9 +669,9 @@
[[package]]
name = "cc"
-version = "1.0.61"
+version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d"
+checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
dependencies = [
"jobserver",
]
@@ -669,7 +703,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "244fbce0d47e97e8ef2f63b81d5e05882cb518c68531eb33194990d7b7e85845"
dependencies = [
- "stream-cipher 0.7.1",
+ "stream-cipher",
"zeroize",
]
@@ -682,7 +716,7 @@
"aead",
"chacha20",
"poly1305",
- "stream-cipher 0.7.1",
+ "stream-cipher",
"zeroize",
]
@@ -730,15 +764,6 @@
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "cloudabi"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
dependencies = [
"bitflags",
]
@@ -754,9 +779,9 @@
[[package]]
name = "const-random"
-version = "0.1.11"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02dc82c12dc2ee6e1ded861cf7d582b46f66f796d1b6c93fa28b911ead95da02"
+checksum = "f590d95d011aa80b063ffe3253422ed5aa462af4e9867d43ce8337562bac77c4"
dependencies = [
"const-random-macro",
"proc-macro-hack",
@@ -764,15 +789,23 @@
[[package]]
name = "const-random-macro"
-version = "0.1.11"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc757bbb9544aa296c2ae00c679e81f886b37e28e59097defe0cf524306f6685"
+checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40"
dependencies = [
"getrandom 0.2.0",
+ "lazy_static",
"proc-macro-hack",
+ "tiny-keccak",
]
[[package]]
+name = "const_fn"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
+
+[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -801,6 +834,12 @@
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
[[package]]
+name = "cpuid-bool"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba"
+
+[[package]]
name = "cranelift-bforest"
version = "0.66.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -824,7 +863,7 @@
"log",
"regalloc",
"serde",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"target-lexicon",
"thiserror",
]
@@ -862,7 +901,7 @@
dependencies = [
"cranelift-codegen",
"log",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"target-lexicon",
]
@@ -894,21 +933,21 @@
[[package]]
name = "crc32fast"
-version = "1.2.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
+checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
]
[[package]]
name = "crossbeam-channel"
-version = "0.4.4"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
+checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
dependencies = [
- "crossbeam-utils",
- "maybe-uninit",
+ "cfg-if 1.0.0",
+ "crossbeam-utils 0.8.1",
]
[[package]]
@@ -917,12 +956,23 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
dependencies = [
- "crossbeam-epoch",
- "crossbeam-utils",
+ "crossbeam-epoch 0.8.2",
+ "crossbeam-utils 0.7.2",
"maybe-uninit",
]
[[package]]
+name = "crossbeam-deque"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crossbeam-epoch 0.9.1",
+ "crossbeam-utils 0.8.1",
+]
+
+[[package]]
name = "crossbeam-epoch"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -930,10 +980,24 @@
dependencies = [
"autocfg 1.0.1",
"cfg-if 0.1.10",
- "crossbeam-utils",
+ "crossbeam-utils 0.7.2",
"lazy_static",
"maybe-uninit",
- "memoffset",
+ "memoffset 0.5.6",
+ "scopeguard 1.1.0",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
+dependencies = [
+ "cfg-if 1.0.0",
+ "const_fn",
+ "crossbeam-utils 0.8.1",
+ "lazy_static",
+ "memoffset 0.6.1",
"scopeguard 1.1.0",
]
@@ -944,7 +1008,7 @@
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
dependencies = [
"cfg-if 0.1.10",
- "crossbeam-utils",
+ "crossbeam-utils 0.7.2",
"maybe-uninit",
]
@@ -960,6 +1024,17 @@
]
[[package]]
+name = "crossbeam-utils"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
+dependencies = [
+ "autocfg 1.0.1",
+ "cfg-if 1.0.0",
+ "lazy_static",
+]
+
+[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -982,7 +1057,7 @@
checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
dependencies = [
"generic-array 0.14.4",
- "subtle 2.3.0",
+ "subtle 2.4.0",
]
[[package]]
@@ -1013,7 +1088,7 @@
"byteorder 1.3.4",
"digest 0.8.1",
"rand_core 0.5.1",
- "subtle 2.3.0",
+ "subtle 2.4.0",
"zeroize",
]
@@ -1026,15 +1101,15 @@
"byteorder 1.3.4",
"digest 0.9.0",
"rand_core 0.5.1",
- "subtle 2.3.0",
+ "subtle 2.4.0",
"zeroize",
]
[[package]]
name = "data-encoding"
-version = "2.3.0"
+version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4d0e2d24e5ee3b23a01de38eefdcd978907890701f08ffffd4cb457ca4ee8d6"
+checksum = "993a608597367c6377b258c25d7120740f00ed23a2252b729b1932dd7866f908"
[[package]]
name = "derive_more"
@@ -1119,9 +1194,9 @@
[[package]]
name = "dyn-clone"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c53dc3a653e0f64081026e4bf048d48fec9fce90c66e8326ca7292df0ff2d82"
+checksum = "d55796afa1b20c2945ca8eabfc421839f2b766619209f1ede813cf2484f31804"
[[package]]
name = "ed25519"
@@ -1142,7 +1217,7 @@
"ed25519",
"rand 0.7.3",
"serde",
- "sha2 0.9.1",
+ "sha2 0.9.2",
"zeroize",
]
@@ -1153,6 +1228,26 @@
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
+name = "enumflags2"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0"
+dependencies = [
+ "enumflags2_derive",
+]
+
+[[package]]
+name = "enumflags2_derive"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1182,9 +1277,9 @@
[[package]]
name = "errno"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6eab5ee3df98a279d9b316b1af6ac95422127b1290317e6d18c1743c99418b01"
+checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe"
dependencies = [
"errno-dragonfly",
"libc",
@@ -1213,7 +1308,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
]
[[package]]
@@ -1285,7 +1380,7 @@
checksum = "8feb87a63249689640ac9c011742c33139204e3c134293d3054022276869133b"
dependencies = [
"either",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 2.0.2",
"log",
"num-traits",
@@ -1313,11 +1408,11 @@
[[package]]
name = "flate2"
-version = "1.0.18"
+version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da80be589a72651dcda34d8b35bcdc9b7254ad06325611074d9cc0fbb19f60ee"
+checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"crc32fast",
"libc",
"libz-sys",
@@ -1325,6 +1420,22 @@
]
[[package]]
+name = "flexi_logger"
+version = "0.15.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aaab3caedb4149800f91e8e4899f29cd9ddf3b569b04c365ca9334f92f7542bf"
+dependencies = [
+ "atty",
+ "chrono",
+ "glob",
+ "lazy_static",
+ "log",
+ "regex",
+ "thiserror",
+ "yansi",
+]
+
+[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1333,15 +1444,25 @@
[[package]]
name = "fork-tree"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
]
[[package]]
+name = "form_urlencoded"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
+dependencies = [
+ "matches",
+ "percent-encoding 2.1.0",
+]
+
+[[package]]
name = "frame-benchmarking"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
@@ -1359,7 +1480,7 @@
[[package]]
name = "frame-benchmarking-cli"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-benchmarking",
"parity-scale-codec",
@@ -1377,7 +1498,7 @@
[[package]]
name = "frame-executive"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
@@ -1393,7 +1514,7 @@
[[package]]
name = "frame-metadata"
version = "12.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"serde",
@@ -1404,18 +1525,18 @@
[[package]]
name = "frame-support"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"bitmask",
"frame-metadata",
"frame-support-procedural",
"impl-trait-for-tuples",
"log",
- "once_cell 1.4.1",
+ "once_cell 1.5.2",
"parity-scale-codec",
"paste",
"serde",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"sp-arithmetic",
"sp-core",
"sp-inherents",
@@ -1429,7 +1550,7 @@
[[package]]
name = "frame-support-procedural"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support-procedural-tools",
"proc-macro2",
@@ -1440,7 +1561,7 @@
[[package]]
name = "frame-support-procedural-tools"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support-procedural-tools-derive",
"proc-macro-crate",
@@ -1452,7 +1573,7 @@
[[package]]
name = "frame-support-procedural-tools-derive"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"proc-macro2",
"quote",
@@ -1462,7 +1583,7 @@
[[package]]
name = "frame-system"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"impl-trait-for-tuples",
@@ -1478,7 +1599,7 @@
[[package]]
name = "frame-system-benchmarking"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-benchmarking",
"frame-support",
@@ -1492,7 +1613,7 @@
[[package]]
name = "frame-system-rpc-runtime-api"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-api",
@@ -1500,9 +1621,9 @@
[[package]]
name = "fs-swap"
-version = "0.2.4"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb"
+checksum = "5839fda247e24ca4919c87c71dd5ca658f1f39e4f06829f80e3f15c3bafcfc2c"
dependencies = [
"lazy_static",
"libc",
@@ -1540,9 +1661,9 @@
[[package]]
name = "futures"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d8e3078b7b2a8a671cb7a3d17b4760e4181ea243227776ba83fd043b4ca034e"
+checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0"
dependencies = [
"futures-channel",
"futures-core",
@@ -1555,9 +1676,9 @@
[[package]]
name = "futures-channel"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a4d35f7401e948629c9c3d6638fb9bf94e0b2121e96c3b428cc4e631f3eb74"
+checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64"
dependencies = [
"futures-core",
"futures-sink",
@@ -1574,9 +1695,9 @@
[[package]]
name = "futures-core"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d674eaa0056896d5ada519900dbf97ead2e46a7b6621e8160d79e2f2e1e2784b"
+checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748"
[[package]]
name = "futures-core-preview"
@@ -1601,20 +1722,20 @@
checksum = "fdcef58a173af8148b182684c9f2d5250875adbcaff7b5794073894f9d8634a9"
dependencies = [
"futures 0.1.30",
- "futures 0.3.6",
+ "futures 0.3.8",
"lazy_static",
"log",
"parking_lot 0.9.0",
- "pin-project",
+ "pin-project 0.4.27",
"serde",
"serde_json",
]
[[package]]
name = "futures-executor"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc709ca1da6f66143b8c9bec8e6260181869893714e9b5a490b169b0414144ab"
+checksum = "4caa2b2b68b880003057c1dd49f1ed937e38f22fcf6c212188a121f08cf40a65"
dependencies = [
"futures-core",
"futures-task",
@@ -1624,30 +1745,30 @@
[[package]]
name = "futures-io"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fc94b64bb39543b4e432f1790b6bf18e3ee3b74653c5449f63310e9a74b123c"
+checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb"
[[package]]
name = "futures-lite"
-version = "1.11.1"
+version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "381a7ad57b1bad34693f63f6f377e1abded7a9c85c9d3eb6771e11c60aaadab9"
+checksum = "5e6c079abfac3ab269e2927ec048dabc89d009ebfdda6b8ee86624f30c689658"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"memchr",
"parking",
- "pin-project-lite",
+ "pin-project-lite 0.1.11",
"waker-fn",
]
[[package]]
name = "futures-macro"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f57ed14da4603b2554682e9f2ff3c65d7567b53188db96cb71538217fc64581b"
+checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556"
dependencies = [
"proc-macro-hack",
"proc-macro2",
@@ -1657,17 +1778,17 @@
[[package]]
name = "futures-sink"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d8764258ed64ebc5d9ed185cf86a95db5cac810269c5d20ececb32e0088abbd"
+checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d"
[[package]]
name = "futures-task"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dd26820a9f3637f1302da8bceba3ff33adbe53464b54ca24d4e2d4f1db30f94"
+checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d"
dependencies = [
- "once_cell 1.4.1",
+ "once_cell 1.5.2",
]
[[package]]
@@ -1684,9 +1805,9 @@
[[package]]
name = "futures-util"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a894a0acddba51a2d49a6f4263b1e64b8c579ece8af50fa86503d52cd1eea34"
+checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2"
dependencies = [
"futures 0.1.30",
"futures-channel",
@@ -1696,7 +1817,7 @@
"futures-sink",
"futures-task",
"memchr",
- "pin-project",
+ "pin-project 1.0.2",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
@@ -1722,9 +1843,9 @@
checksum = "ce54d63f8b0c75023ed920d46fd71d0cbbb830b0ee012726b5b4f506fb6dea5b"
dependencies = [
"bytes 0.5.6",
- "futures 0.3.6",
+ "futures 0.3.8",
"memchr",
- "pin-project",
+ "pin-project 0.4.27",
]
[[package]]
@@ -1734,6 +1855,19 @@
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]]
+name = "generator"
+version = "0.6.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cdc09201b2e8ca1b19290cf7e65de2246b8e91fb6874279722189c4de7b94dc"
+dependencies = [
+ "cc",
+ "libc",
+ "log",
+ "rustc_version",
+ "winapi 0.3.9",
+]
+
+[[package]]
name = "generic-array"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1818,9 +1952,9 @@
[[package]]
name = "gimli"
-version = "0.22.0"
+version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
+checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
[[package]]
name = "glob"
@@ -1830,9 +1964,9 @@
[[package]]
name = "globset"
-version = "0.4.5"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120"
+checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a"
dependencies = [
"aho-corasick",
"bstr",
@@ -1874,21 +2008,22 @@
[[package]]
name = "h2"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53"
+checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535"
dependencies = [
"bytes 0.5.6",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
- "http 0.2.1",
+ "http 0.2.2",
"indexmap",
"slab",
- "tokio 0.2.22",
+ "tokio 0.2.24",
"tokio-util",
"tracing",
+ "tracing-futures",
]
[[package]]
@@ -1941,6 +2076,9 @@
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
+dependencies = [
+ "ahash 0.4.7",
+]
[[package]]
name = "heck"
@@ -2012,9 +2150,9 @@
[[package]]
name = "http"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
+checksum = "84129d298a6d57d246960ff8eb831ca4af3f96d29e2e28848dae275408658e26"
dependencies = [
"bytes 0.5.6",
"fnv",
@@ -2040,7 +2178,7 @@
checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
dependencies = [
"bytes 0.5.6",
- "http 0.2.1",
+ "http 0.2.2",
]
[[package]]
@@ -2096,23 +2234,23 @@
[[package]]
name = "hyper"
-version = "0.13.8"
+version = "0.13.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f3afcfae8af5ad0576a31e768415edb627824129e8e5a29b8bfccb2f234e835"
+checksum = "f6ad767baac13b44d4529fcf58ba2cd0995e36e7b435bc5b039de6f47e880dbf"
dependencies = [
"bytes 0.5.6",
"futures-channel",
"futures-core",
"futures-util",
- "h2 0.2.6",
- "http 0.2.1",
+ "h2 0.2.7",
+ "http 0.2.2",
"http-body 0.3.1",
"httparse",
"httpdate",
"itoa",
- "pin-project",
+ "pin-project 1.0.2",
"socket2",
- "tokio 0.2.22",
+ "tokio 0.2.24",
"tower-service",
"tracing",
"want 0.3.0",
@@ -2127,11 +2265,11 @@
"bytes 0.5.6",
"ct-logs",
"futures-util",
- "hyper 0.13.8",
+ "hyper 0.13.9",
"log",
"rustls",
"rustls-native-certs",
- "tokio 0.2.22",
+ "tokio 0.2.24",
"tokio-rustls",
"webpki",
]
@@ -2189,9 +2327,9 @@
[[package]]
name = "indexmap"
-version = "1.6.0"
+version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
+checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
dependencies = [
"autocfg 1.0.1",
"hashbrown 0.9.1",
@@ -2200,11 +2338,11 @@
[[package]]
name = "instant"
-version = "0.1.7"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66"
+checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
]
[[package]]
@@ -2222,7 +2360,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 2.0.2",
]
@@ -2282,9 +2420,9 @@
[[package]]
name = "js-sys"
-version = "0.3.45"
+version = "0.3.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8"
+checksum = "cf3d7383929f7c9c7c2d0fa596f325832df98c3704f2c60553080f7127a58175"
dependencies = [
"wasm-bindgen",
]
@@ -2443,7 +2581,7 @@
checksum = "0315ef2f688e33844400b31f11c263f2b3dc21d8b9355c6891c5f185fae43f9a"
dependencies = [
"parity-util-mem",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
]
[[package]]
@@ -2472,7 +2610,7 @@
"parking_lot 0.10.2",
"regex",
"rocksdb",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
]
[[package]]
@@ -2495,9 +2633,9 @@
[[package]]
name = "libc"
-version = "0.2.79"
+version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743"
+checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
[[package]]
name = "libloading"
@@ -2523,7 +2661,7 @@
dependencies = [
"atomic",
"bytes 0.5.6",
- "futures 0.3.6",
+ "futures 0.3.8",
"lazy_static",
"libp2p-core",
"libp2p-core-derive",
@@ -2549,8 +2687,8 @@
"multihash",
"parity-multiaddr",
"parking_lot 0.10.2",
- "pin-project",
- "smallvec 1.4.2",
+ "pin-project 0.4.27",
+ "smallvec 1.5.1",
"wasm-timer",
]
@@ -2561,11 +2699,11 @@
checksum = "52f13ba8c7df0768af2eb391696d562c7de88cc3a35122531aaa6a7d77754d25"
dependencies = [
"asn1_der",
- "bs58",
+ "bs58 0.3.1",
"ed25519-dalek",
"either",
"fnv",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"lazy_static",
"libsecp256k1",
@@ -2574,14 +2712,14 @@
"multistream-select",
"parity-multiaddr",
"parking_lot 0.10.2",
- "pin-project",
+ "pin-project 0.4.27",
"prost",
"prost-build",
"rand 0.7.3",
"ring",
"rw-stream-sink",
"sha2 0.8.2",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"thiserror",
"unsigned-varint 0.4.0",
"void",
@@ -2605,7 +2743,7 @@
checksum = "74029ae187f35f4b8ddf26b9779a68b340045d708528a103917cdca49a296db5"
dependencies = [
"flate2",
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
]
@@ -2615,7 +2753,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cf319822e08dd65c8e060d2354e9f952895bbc433f5706c75ed010c152aee5e"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
"log",
]
@@ -2628,13 +2766,13 @@
dependencies = [
"cuckoofilter",
"fnv",
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
"libp2p-swarm",
"prost",
"prost-build",
"rand 0.7.3",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
]
[[package]]
@@ -2647,7 +2785,7 @@
"byteorder 1.3.4",
"bytes 0.5.6",
"fnv",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures_codec",
"hex_fmt",
"libp2p-core",
@@ -2658,7 +2796,7 @@
"prost-build",
"rand 0.7.3",
"sha2 0.8.2",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"unsigned-varint 0.4.0",
"wasm-timer",
]
@@ -2669,13 +2807,13 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56396ee63aa9164eacf40c2c5d2bda8c4133c2f57e1b0425d51d3a4e362583b1"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
"libp2p-swarm",
"log",
"prost",
"prost-build",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"wasm-timer",
]
@@ -2685,11 +2823,11 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc7fa9047f8b8f544278a35c2d9d45d3b2c1785f2d86d4e1629d6edf97be3955"
dependencies = [
- "arrayvec 0.5.1",
+ "arrayvec 0.5.2",
"bytes 0.5.6",
"either",
"fnv",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures_codec",
"libp2p-core",
"libp2p-swarm",
@@ -2699,7 +2837,7 @@
"prost-build",
"rand 0.7.3",
"sha2 0.8.2",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"uint",
"unsigned-varint 0.4.0",
"void",
@@ -2716,14 +2854,14 @@
"data-encoding",
"dns-parser",
"either",
- "futures 0.3.6",
+ "futures 0.3.8",
"lazy_static",
"libp2p-core",
"libp2p-swarm",
"log",
"net2",
"rand 0.7.3",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"void",
"wasm-timer",
]
@@ -2736,7 +2874,7 @@
dependencies = [
"bytes 0.5.6",
"fnv",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures_codec",
"libp2p-core",
"log",
@@ -2752,7 +2890,7 @@
dependencies = [
"bytes 0.5.6",
"curve25519-dalek 2.1.0",
- "futures 0.3.6",
+ "futures 0.3.8",
"lazy_static",
"libp2p-core",
"log",
@@ -2772,7 +2910,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad063c21dfcea4518ac9e8bd4119d33a5b26c41e674f602f41f05617a368a5c8"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
"libp2p-swarm",
"log",
@@ -2788,7 +2926,7 @@
checksum = "903a12e99c72dbebefea258de887982adeacc7025baa1ceb10b7fa9928f54791"
dependencies = [
"bytes 0.5.6",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures_codec",
"libp2p-core",
"log",
@@ -2801,16 +2939,16 @@
[[package]]
name = "libp2p-pnet"
-version = "0.19.1"
+version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d0db10e139d22d7af0b23ed7949449ec86262798aa0fd01595abdbcb02dc87"
+checksum = "96b3c2d5d26a9500e959a0e19743897239a6c4be78dadf99b70414301a70c006"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"log",
- "pin-project",
+ "pin-project 0.4.27",
"rand 0.7.3",
"salsa20",
- "sha3 0.8.2",
+ "sha3",
]
[[package]]
@@ -2821,14 +2959,14 @@
dependencies = [
"async-trait",
"bytes 0.5.6",
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
"libp2p-swarm",
"log",
- "lru 0.6.0",
+ "lru 0.6.2",
"minicbor",
"rand 0.7.3",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"unsigned-varint 0.5.1",
"wasm-timer",
]
@@ -2840,11 +2978,11 @@
checksum = "7193e444210132237b81b755ec7fe53f1c4bd2f53cf719729b94c0c72eb6eaa1"
dependencies = [
"either",
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
"log",
"rand 0.7.3",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"void",
"wasm-timer",
]
@@ -2856,7 +2994,7 @@
checksum = "44f42ec130d7a37a7e47bf4398026b7ad9185c08ed26972e2720f8b94112796f"
dependencies = [
"async-std",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"get_if_addrs",
"ipnet",
@@ -2872,7 +3010,7 @@
checksum = "dea7acb0a034f70d7db94c300eba3f65c0f6298820105624088a9609c9974d77"
dependencies = [
"async-std",
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
"log",
]
@@ -2883,7 +3021,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34c1faac6f92c21fbe155417957863ea822fba9e9fd5eb24c0912336a100e63f"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"js-sys",
"libp2p-core",
"parity-send-wrapper",
@@ -2899,14 +3037,14 @@
dependencies = [
"async-tls",
"either",
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
"log",
"quicksink",
"rustls",
"rw-stream-sink",
"soketto",
- "url 2.1.1",
+ "url 2.2.0",
"webpki",
"webpki-roots 0.18.0",
]
@@ -2917,9 +3055,9 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "781d9b9f043dcdabc40640807125368596b849fd4d96cdca2dcf052fdf6f33fd"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p-core",
- "parking_lot 0.11.0",
+ "parking_lot 0.11.1",
"thiserror",
"yamux",
]
@@ -2948,7 +3086,7 @@
"hmac-drbg",
"rand 0.7.3",
"sha2 0.8.2",
- "subtle 2.3.0",
+ "subtle 2.4.0",
"typenum",
]
@@ -3009,9 +3147,9 @@
[[package]]
name = "lock_api"
-version = "0.4.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
+checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
dependencies = [
"scopeguard 1.1.0",
]
@@ -3026,6 +3164,19 @@
]
[[package]]
+name = "loom"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0e8460f2f2121162705187214720353c517b97bdfb3494c0b1e33d83ebe4bed"
+dependencies = [
+ "cfg-if 0.1.10",
+ "generator",
+ "scoped-tls",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
name = "lru"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3036,11 +3187,11 @@
[[package]]
name = "lru"
-version = "0.6.0"
+version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "111b945ac72ec09eb7bc62a0fbdc3cc6e80555a7245f52a69d3921a75b53b153"
+checksum = "3abe07af102235a56ac9a6dd904aab1e05483e2e8afdfffec3598be55b1b7606"
dependencies = [
- "hashbrown 0.8.2",
+ "hashbrown 0.9.1",
]
[[package]]
@@ -3075,9 +3226,9 @@
[[package]]
name = "matrixmultiply"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f"
+checksum = "916806ba0031cd542105d916a97c8572e1fa6dd79c9c51e7eb43a09ec2dd84c1"
dependencies = [
"rawpointer",
]
@@ -3090,9 +3241,9 @@
[[package]]
name = "memchr"
-version = "2.3.3"
+version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "memmap"
@@ -3114,6 +3265,15 @@
]
[[package]]
+name = "memoffset"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
+dependencies = [
+ "autocfg 1.0.1",
+]
+
+[[package]]
name = "memory-db"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3174,9 +3334,9 @@
[[package]]
name = "mio"
-version = "0.6.22"
+version = "0.6.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
+checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
dependencies = [
"cfg-if 0.1.10",
"fuchsia-zircon",
@@ -3185,7 +3345,7 @@
"kernel32-sys",
"libc",
"log",
- "miow 0.2.1",
+ "miow 0.2.2",
"net2",
"slab",
"winapi 0.2.8",
@@ -3211,7 +3371,7 @@
dependencies = [
"log",
"mio",
- "miow 0.3.5",
+ "miow 0.3.6",
"winapi 0.3.9",
]
@@ -3228,9 +3388,9 @@
[[package]]
name = "miow"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
dependencies = [
"kernel32-sys",
"net2",
@@ -3240,9 +3400,9 @@
[[package]]
name = "miow"
-version = "0.3.5"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e"
+checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897"
dependencies = [
"socket2",
"winapi 0.3.9",
@@ -3263,9 +3423,9 @@
"blake2b_simd",
"blake2s_simd",
"digest 0.9.0",
- "sha-1 0.9.1",
- "sha2 0.9.1",
- "sha3 0.9.1",
+ "sha-1 0.9.2",
+ "sha2 0.9.2",
+ "sha3",
"unsigned-varint 0.5.1",
]
@@ -3277,16 +3437,16 @@
[[package]]
name = "multistream-select"
-version = "0.8.2"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9157e87afbc2ef0d84cc0345423d715f445edde00141c93721c162de35a05e5"
+checksum = "93faf2e41f9ee62fb01680ed48f3cc26652352327aa2e59869070358f6b7dd75"
dependencies = [
"bytes 0.5.6",
- "futures 0.3.6",
+ "futures 0.3.8",
"log",
- "pin-project",
- "smallvec 1.4.2",
- "unsigned-varint 0.4.0",
+ "pin-project 1.0.2",
+ "smallvec 1.5.1",
+ "unsigned-varint 0.5.1",
]
[[package]]
@@ -3327,9 +3487,9 @@
[[package]]
name = "net2"
-version = "0.2.35"
+version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853"
+checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
dependencies = [
"cfg-if 0.1.10",
"libc",
@@ -3340,9 +3500,10 @@
name = "nft"
version = "2.0.0"
dependencies = [
+ "flexi_logger",
"frame-benchmarking",
"frame-benchmarking-cli",
- "futures 0.3.6",
+ "futures 0.3.8",
"jsonrpc-core",
"log",
"nft-runtime",
@@ -3361,6 +3522,8 @@
"sc-rpc-api",
"sc-service",
"sc-transaction-pool",
+ "serde",
+ "serde_json",
"sp-api",
"sp-block-builder",
"sp-blockchain",
@@ -3400,6 +3563,7 @@
"pallet-transaction-payment",
"pallet-transaction-payment-rpc-runtime-api",
"pallet-treasury",
+ "pallet-vesting",
"parity-scale-codec",
"serde",
"sp-api",
@@ -3474,9 +3638,9 @@
[[package]]
name = "num-integer"
-version = "0.1.43"
+version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg 1.0.1",
"num-traits",
@@ -3496,9 +3660,9 @@
[[package]]
name = "num-traits"
-version = "0.2.12"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg 1.0.1",
"libm",
@@ -3533,9 +3697,9 @@
[[package]]
name = "object"
-version = "0.21.1"
+version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693"
+checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
[[package]]
name = "once_cell"
@@ -3548,11 +3712,11 @@
[[package]]
name = "once_cell"
-version = "1.4.1"
+version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
+checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
dependencies = [
- "parking_lot 0.11.0",
+ "parking_lot 0.11.1",
]
[[package]]
@@ -3585,7 +3749,7 @@
[[package]]
name = "pallet-aura"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
@@ -3604,7 +3768,7 @@
[[package]]
name = "pallet-authorship"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
@@ -3619,7 +3783,7 @@
[[package]]
name = "pallet-balances"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-benchmarking",
"frame-support",
@@ -3633,7 +3797,7 @@
[[package]]
name = "pallet-contracts"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"bitflags",
"frame-support",
@@ -3654,7 +3818,7 @@
[[package]]
name = "pallet-contracts-primitives"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-runtime",
@@ -3664,7 +3828,7 @@
[[package]]
name = "pallet-contracts-rpc"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"jsonrpc-core",
"jsonrpc-core-client",
@@ -3683,7 +3847,7 @@
[[package]]
name = "pallet-contracts-rpc-runtime-api"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"pallet-contracts-primitives",
"parity-scale-codec",
@@ -3695,7 +3859,7 @@
[[package]]
name = "pallet-finality-tracker"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
@@ -3711,7 +3875,7 @@
[[package]]
name = "pallet-grandpa"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-benchmarking",
"frame-support",
@@ -3754,7 +3918,7 @@
[[package]]
name = "pallet-randomness-collective-flip"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
@@ -3767,7 +3931,7 @@
[[package]]
name = "pallet-session"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
@@ -3787,7 +3951,7 @@
[[package]]
name = "pallet-sudo"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
@@ -3801,7 +3965,7 @@
[[package]]
name = "pallet-timestamp"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-benchmarking",
"frame-support",
@@ -3819,14 +3983,14 @@
[[package]]
name = "pallet-transaction-payment"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
"pallet-transaction-payment-rpc-runtime-api",
"parity-scale-codec",
"serde",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"sp-core",
"sp-io",
"sp-runtime",
@@ -3836,7 +4000,7 @@
[[package]]
name = "pallet-transaction-payment-rpc"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"jsonrpc-core",
"jsonrpc-core-client",
@@ -3854,7 +4018,7 @@
[[package]]
name = "pallet-transaction-payment-rpc-runtime-api"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"parity-scale-codec",
@@ -3867,7 +4031,7 @@
[[package]]
name = "pallet-treasury"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-support",
"frame-system",
@@ -3879,6 +4043,20 @@
]
[[package]]
+name = "pallet-vesting"
+version = "2.0.0"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
+dependencies = [
+ "enumflags2",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "serde",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
name = "parity-db"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3894,20 +4072,20 @@
[[package]]
name = "parity-multiaddr"
-version = "0.9.2"
+version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2165a93382a93de55868dcbfa11e4a8f99676a9164eee6a2b4a9479ad319c257"
+checksum = "43244a26dc1ddd3097216bb12eaa6cf8a07b060c72718d9ebd60fd297d6401df"
dependencies = [
"arrayref",
- "bs58",
+ "bs58 0.4.0",
"byteorder 1.3.4",
"data-encoding",
"multihash",
"percent-encoding 2.1.0",
"serde",
"static_assertions",
- "unsigned-varint 0.4.0",
- "url 2.1.1",
+ "unsigned-varint 0.5.1",
+ "url 2.2.0",
]
[[package]]
@@ -3916,7 +4094,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c740e5fbcb6847058b40ac7e5574766c6388f585e184d769910fe0d3a2ca861"
dependencies = [
- "arrayvec 0.5.1",
+ "arrayvec 0.5.2",
"bitvec",
"byte-slice-cast",
"parity-scale-codec-derive",
@@ -3952,7 +4130,7 @@
"libc",
"log",
"mio-named-pipes",
- "miow 0.3.5",
+ "miow 0.3.6",
"rand 0.7.3",
"tokio 0.1.22",
"tokio-named-pipes",
@@ -3972,7 +4150,7 @@
"parity-util-mem-derive",
"parking_lot 0.10.2",
"primitive-types",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"winapi 0.3.9",
]
@@ -4008,7 +4186,7 @@
"rand 0.7.3",
"sha-1 0.8.2",
"slab",
- "url 2.1.1",
+ "url 2.2.0",
]
[[package]]
@@ -4050,13 +4228,13 @@
[[package]]
name = "parking_lot"
-version = "0.11.0"
+version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
+checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
dependencies = [
"instant",
- "lock_api 0.4.1",
- "parking_lot_core 0.8.0",
+ "lock_api 0.4.2",
+ "parking_lot_core 0.8.1",
]
[[package]]
@@ -4079,7 +4257,7 @@
checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
dependencies = [
"cfg-if 0.1.10",
- "cloudabi 0.0.3",
+ "cloudabi",
"libc",
"redox_syscall",
"rustc_version",
@@ -4094,25 +4272,24 @@
checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
dependencies = [
"cfg-if 0.1.10",
- "cloudabi 0.0.3",
+ "cloudabi",
"libc",
"redox_syscall",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"winapi 0.3.9",
]
[[package]]
name = "parking_lot_core"
-version = "0.8.0"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
+checksum = "d7c6d9b8427445284a09c55be860a15855ab580a417ccad9da88f5a06787ced0"
dependencies = [
- "cfg-if 0.1.10",
- "cloudabi 0.1.0",
+ "cfg-if 1.0.0",
"instant",
"libc",
"redox_syscall",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"winapi 0.3.9",
]
@@ -4180,7 +4357,16 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15"
dependencies = [
- "pin-project-internal",
+ "pin-project-internal 0.4.27",
+]
+
+[[package]]
+name = "pin-project"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7"
+dependencies = [
+ "pin-project-internal 1.0.2",
]
[[package]]
@@ -4195,10 +4381,27 @@
]
[[package]]
+name = "pin-project-internal"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b"
+
+[[package]]
name = "pin-project-lite"
-version = "0.1.10"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e555d9e657502182ac97b539fb3dae8b79cda19e3e4f8ffb5e8de4f18df93c95"
+checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c"
[[package]]
name = "pin-utils"
@@ -4220,9 +4423,9 @@
[[package]]
name = "polling"
-version = "2.0.1"
+version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab773feb154f12c49ffcfd66ab8bdcf9a1843f950db48b0d8be9d4393783b058"
+checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4"
dependencies = [
"cfg-if 0.1.10",
"libc",
@@ -4233,34 +4436,35 @@
[[package]]
name = "poly1305"
-version = "0.6.1"
+version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22ce46de8e53ee414ca4d02bfefac75d8c12fba948b76622a40b4be34dfce980"
+checksum = "4b7456bc1ad2d4cf82b3a016be4c2ac48daf11bf990c1603ebd447fe6f30fca8"
dependencies = [
+ "cpuid-bool 0.2.0",
"universal-hash",
]
[[package]]
name = "polyval"
-version = "0.4.1"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5884790f1ce3553ad55fec37b5aaac5882e0e845a2612df744d6c85c9bf046c"
+checksum = "b4fd92d8e0c06d08525d2e2643cc2b5c80c69ae8eb12c18272d501cd7079ccc0"
dependencies = [
- "cfg-if 0.1.10",
+ "cpuid-bool 0.2.0",
"universal-hash",
]
[[package]]
name = "ppv-lite86"
-version = "0.2.9"
+version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "primitive-types"
-version = "0.7.2"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c55c21c64d0eaa4d7ed885d959ef2d62d9e488c27c0e02d9aa5ce6c877b7d5f8"
+checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809"
dependencies = [
"fixed-hash",
"impl-codec",
@@ -4303,9 +4507,9 @@
[[package]]
name = "proc-macro-hack"
-version = "0.5.18"
+version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
+checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro-nested"
@@ -4331,7 +4535,7 @@
"cfg-if 0.1.10",
"fnv",
"lazy_static",
- "parking_lot 0.11.0",
+ "parking_lot 0.11.1",
"regex",
"thiserror",
]
@@ -4412,7 +4616,7 @@
dependencies = [
"futures-core",
"futures-sink",
- "pin-project-lite",
+ "pin-project-lite 0.1.11",
]
[[package]]
@@ -4459,7 +4663,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
dependencies = [
- "cloudabi 0.0.3",
+ "cloudabi",
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
@@ -4587,7 +4791,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
dependencies = [
- "cloudabi 0.0.3",
+ "cloudabi",
"fuchsia-cprng",
"libc",
"rand_core 0.4.2",
@@ -4642,25 +4846,25 @@
[[package]]
name = "rayon"
-version = "1.4.1"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcf6960dc9a5b4ee8d3e4c5787b4a112a8818e0290a42ff664ad60692fdf2032"
+checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
dependencies = [
"autocfg 1.0.1",
- "crossbeam-deque",
+ "crossbeam-deque 0.8.0",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
-version = "1.8.1"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf"
+checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
dependencies = [
"crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-utils",
+ "crossbeam-deque 0.8.0",
+ "crossbeam-utils 0.8.1",
"lazy_static",
"num_cpus",
]
@@ -4693,18 +4897,18 @@
[[package]]
name = "ref-cast"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "745c1787167ddae5569661d5ffb8b25ae5fedbf46717eaa92d652221cec72623"
+checksum = "e17626b2f4bcf35b84bf379072a66e28cfe5c3c6ae58b38e4914bb8891dabece"
dependencies = [
"ref-cast-impl",
]
[[package]]
name = "ref-cast-impl"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d21b475ab879ef0e315ad99067fa25778c3b0377f57f1b00207448dac1a3144"
+checksum = "0c523ccaed8ac4b0288948849a350b37d3035827413c458b6a40ddb614bb4f72"
dependencies = [
"proc-macro2",
"quote",
@@ -4719,14 +4923,14 @@
dependencies = [
"log",
"rustc-hash",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
]
[[package]]
name = "regex"
-version = "1.4.1"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b"
+checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
dependencies = [
"aho-corasick",
"memchr",
@@ -4746,9 +4950,9 @@
[[package]]
name = "regex-syntax"
-version = "0.6.20"
+version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c"
+checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
[[package]]
name = "region"
@@ -4779,13 +4983,13 @@
[[package]]
name = "ring"
-version = "0.16.15"
+version = "0.16.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4"
+checksum = "024a1e66fea74c66c66624ee5622a7ff0e4b73a13b4f5c326ddb50c708944226"
dependencies = [
"cc",
"libc",
- "once_cell 1.4.1",
+ "once_cell 1.5.2",
"spin",
"untrusted",
"web-sys",
@@ -4814,21 +5018,21 @@
[[package]]
name = "rust-argon2"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19"
+checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
dependencies = [
- "base64 0.12.3",
+ "base64 0.13.0",
"blake2b_simd",
"constant_time_eq",
- "crossbeam-utils",
+ "crossbeam-utils 0.8.1",
]
[[package]]
name = "rustc-demangle"
-version = "0.1.17"
+version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2610b7f643d18c87dff3b489950269617e6601a51f1f05aa5daefee36f64f0b"
+checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
[[package]]
name = "rustc-hash"
@@ -4882,8 +5086,8 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020"
dependencies = [
- "futures 0.3.6",
- "pin-project",
+ "futures 0.3.8",
+ "pin-project 0.4.27",
"static_assertions",
]
@@ -4904,30 +5108,19 @@
[[package]]
name = "salsa20"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2324b0e8c3bb9a586a571fdb3136f70e7e2c748de00a78043f86e0cff91f91fe"
-dependencies = [
- "byteorder 1.3.4",
- "salsa20-core",
- "stream-cipher 0.3.2",
-]
-
-[[package]]
-name = "salsa20-core"
-version = "0.2.3"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fe6cc1b9f5a5867853ade63099de70f042f7679e408d1ffe52821c9248e6e69"
+checksum = "c7f47b10fa80f6969bbbd9c8e7cc998f082979d402a9e10579e2303a87955395"
dependencies = [
- "stream-cipher 0.3.2",
+ "stream-cipher",
]
[[package]]
name = "sc-basic-authorship"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"log",
"parity-scale-codec",
@@ -4949,7 +5142,7 @@
[[package]]
name = "sc-block-builder"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sc-client-api",
@@ -4966,7 +5159,7 @@
[[package]]
name = "sc-chain-spec"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"impl-trait-for-tuples",
"parity-scale-codec",
@@ -4983,7 +5176,7 @@
[[package]]
name = "sc-chain-spec-derive"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@@ -4994,7 +5187,7 @@
[[package]]
name = "sc-cli"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"ansi_term 0.12.1",
"atty",
@@ -5002,7 +5195,8 @@
"chrono",
"derive_more",
"fdlimit",
- "futures 0.3.6",
+ "flexi_logger",
+ "futures 0.3.8",
"hex",
"lazy_static",
"libp2p",
@@ -5034,7 +5228,7 @@
"structopt",
"substrate-prometheus-endpoint",
"time",
- "tokio 0.2.22",
+ "tokio 0.2.24",
"tracing",
"tracing-log",
"tracing-subscriber",
@@ -5043,11 +5237,11 @@
[[package]]
name = "sc-client-api"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
"fnv",
- "futures 0.3.6",
+ "futures 0.3.8",
"hash-db",
"hex-literal",
"kvdb",
@@ -5079,7 +5273,7 @@
[[package]]
name = "sc-client-db"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"blake2-rfc",
"hash-db",
@@ -5109,7 +5303,7 @@
[[package]]
name = "sc-consensus"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"sc-client-api",
"sp-blockchain",
@@ -5120,10 +5314,10 @@
[[package]]
name = "sc-consensus-aura"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"log",
"parity-scale-codec",
@@ -5151,9 +5345,9 @@
[[package]]
name = "sc-consensus-slots"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"log",
"parity-scale-codec",
@@ -5174,7 +5368,7 @@
[[package]]
name = "sc-executor"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
"lazy_static",
@@ -5202,7 +5396,7 @@
[[package]]
name = "sc-executor-common"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
"log",
@@ -5219,7 +5413,7 @@
[[package]]
name = "sc-executor-wasmi"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"log",
"parity-scale-codec",
@@ -5234,7 +5428,7 @@
[[package]]
name = "sc-executor-wasmtime"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"log",
"parity-scale-codec",
@@ -5252,17 +5446,17 @@
[[package]]
name = "sc-finality-grandpa"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
"finality-grandpa",
"fork-tree",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"log",
"parity-scale-codec",
"parking_lot 0.10.2",
- "pin-project",
+ "pin-project 0.4.27",
"rand 0.7.3",
"sc-block-builder",
"sc-client-api",
@@ -5289,10 +5483,10 @@
[[package]]
name = "sc-informant"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"ansi_term 0.12.1",
- "futures 0.3.6",
+ "futures 0.3.8",
"log",
"parity-util-mem",
"sc-client-api",
@@ -5307,7 +5501,7 @@
[[package]]
name = "sc-keystore"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
"hex",
@@ -5317,13 +5511,13 @@
"serde_json",
"sp-application-crypto",
"sp-core",
- "subtle 2.3.0",
+ "subtle 2.4.0",
]
[[package]]
name = "sc-light"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"hash-db",
"lazy_static",
@@ -5342,19 +5536,19 @@
[[package]]
name = "sc-network"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"async-std",
"async-trait",
"bitflags",
- "bs58",
+ "bs58 0.3.1",
"bytes 0.5.6",
"derive_more",
"either",
"erased-serde",
"fnv",
"fork-tree",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"futures_codec",
"hex",
@@ -5367,7 +5561,7 @@
"nohash-hasher",
"parity-scale-codec",
"parking_lot 0.10.2",
- "pin-project",
+ "pin-project 0.4.27",
"prost",
"prost-build",
"rand 0.7.3",
@@ -5396,9 +5590,9 @@
[[package]]
name = "sc-network-gossip"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"libp2p",
"log",
@@ -5411,13 +5605,13 @@
[[package]]
name = "sc-offchain"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"bytes 0.5.6",
"fnv",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
- "hyper 0.13.8",
+ "hyper 0.13.9",
"hyper-rustls",
"log",
"num_cpus",
@@ -5438,9 +5632,9 @@
[[package]]
name = "sc-peerset"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"libp2p",
"log",
"serde_json",
@@ -5451,7 +5645,7 @@
[[package]]
name = "sc-proposer-metrics"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"log",
"substrate-prometheus-endpoint",
@@ -5460,9 +5654,9 @@
[[package]]
name = "sc-rpc"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"hash-db",
"jsonrpc-core",
"jsonrpc-pubsub",
@@ -5492,10 +5686,10 @@
[[package]]
name = "sc-rpc-api"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
- "futures 0.3.6",
+ "futures 0.3.8",
"jsonrpc-core",
"jsonrpc-core-client",
"jsonrpc-derive",
@@ -5516,7 +5710,7 @@
[[package]]
name = "sc-rpc-server"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"futures 0.1.30",
"jsonrpc-core",
@@ -5534,13 +5728,13 @@
[[package]]
name = "sc-service"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
"directories",
"exit-future",
"futures 0.1.30",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"hash-db",
"jsonrpc-core",
@@ -5550,7 +5744,7 @@
"parity-scale-codec",
"parity-util-mem",
"parking_lot 0.10.2",
- "pin-project",
+ "pin-project 0.4.27",
"rand 0.7.3",
"sc-block-builder",
"sc-chain-spec",
@@ -5596,7 +5790,7 @@
[[package]]
name = "sc-state-db"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"log",
"parity-scale-codec",
@@ -5610,14 +5804,14 @@
[[package]]
name = "sc-telemetry"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"libp2p",
"log",
"parking_lot 0.10.2",
- "pin-project",
+ "pin-project 0.4.27",
"rand 0.7.3",
"serde",
"slog",
@@ -5631,7 +5825,7 @@
[[package]]
name = "sc-tracing"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"erased-serde",
"log",
@@ -5650,10 +5844,10 @@
[[package]]
name = "sc-transaction-graph"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
- "futures 0.3.6",
+ "futures 0.3.8",
"linked-hash-map",
"log",
"parity-util-mem",
@@ -5671,10 +5865,10 @@
[[package]]
name = "sc-transaction-pool"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-diagnose",
"intervalier",
"log",
@@ -5711,14 +5905,14 @@
checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862"
dependencies = [
"arrayref",
- "arrayvec 0.5.1",
+ "arrayvec 0.5.2",
"curve25519-dalek 2.1.0",
"getrandom 0.1.15",
"merlin",
"rand 0.7.3",
"rand_core 0.5.1",
"sha2 0.8.2",
- "subtle 2.3.0",
+ "subtle 2.4.0",
"zeroize",
]
@@ -5751,9 +5945,9 @@
[[package]]
name = "scroll_derive"
-version = "0.10.3"
+version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6dfde5d1531034db129e95c76ac857e2baecea3443579d493d02224950b0fb6d"
+checksum = "b12bd20b94c7cdfda8c7ba9b92ad0d9a56e3fa018c25fca83b51aa664c9b4c0d"
dependencies = [
"proc-macro2",
"quote",
@@ -5819,18 +6013,18 @@
[[package]]
name = "serde"
-version = "1.0.117"
+version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
+checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.117"
+version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
+checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
dependencies = [
"proc-macro2",
"quote",
@@ -5839,9 +6033,9 @@
[[package]]
name = "serde_json"
-version = "1.0.59"
+version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
+checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779"
dependencies = [
"itoa",
"ryu",
@@ -5862,13 +6056,13 @@
[[package]]
name = "sha-1"
-version = "0.9.1"
+version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770"
+checksum = "ce3cdf1b5e620a498ee6f2a171885ac7e22f0e12089ec4b3d22b84921792507c"
dependencies = [
"block-buffer 0.9.0",
- "cfg-if 0.1.10",
- "cpuid-bool",
+ "cfg-if 1.0.0",
+ "cpuid-bool 0.1.2",
"digest 0.9.0",
"opaque-debug 0.3.0",
]
@@ -5887,28 +6081,15 @@
[[package]]
name = "sha2"
-version = "0.9.1"
+version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1"
+checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8"
dependencies = [
"block-buffer 0.9.0",
- "cfg-if 0.1.10",
- "cpuid-bool",
+ "cfg-if 1.0.0",
+ "cpuid-bool 0.1.2",
"digest 0.9.0",
"opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "sha3"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf"
-dependencies = [
- "block-buffer 0.7.3",
- "byte-tools",
- "digest 0.8.1",
- "keccak",
- "opaque-debug 0.2.3",
]
[[package]]
@@ -5925,11 +6106,12 @@
[[package]]
name = "sharded-slab"
-version = "0.0.9"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e"
+checksum = "7b4921be914e16899a80adefb821f8ddb7974e3f1250223575a44ed994882127"
dependencies = [
"lazy_static",
+ "loom",
]
[[package]]
@@ -5939,12 +6121,21 @@
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]]
+name = "signal-hook"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "604508c1418b99dfe1925ca9224829bb2a8a9a04dda655cc01fcad46f4ab05ed"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
name = "signal-hook-registry"
-version = "1.2.1"
+version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035"
+checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab"
dependencies = [
- "arc-swap",
"libc",
]
@@ -5962,9 +6153,9 @@
[[package]]
name = "slog"
-version = "2.5.2"
+version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99"
+checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06"
dependencies = [
"erased-serde",
]
@@ -6015,9 +6206,9 @@
[[package]]
name = "smallvec"
-version = "1.4.2"
+version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
+checksum = "ae524f056d7d770e174287294f562e95044c68e88dec909a00d2094805db9d75"
[[package]]
name = "snow"
@@ -6032,20 +6223,19 @@
"rand_core 0.5.1",
"ring",
"rustc_version",
- "sha2 0.9.1",
- "subtle 2.3.0",
+ "sha2 0.9.2",
+ "subtle 2.4.0",
"x25519-dalek 1.1.0",
]
[[package]]
name = "socket2"
-version = "0.3.15"
+version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
+checksum = "97e0e9fd577458a4f61fb91fcb559ea2afecc54c934119421f9f5d3d5b1a1057"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"libc",
- "redox_syscall",
"winapi 0.3.9",
]
@@ -6058,17 +6248,17 @@
"base64 0.12.3",
"bytes 0.5.6",
"flate2",
- "futures 0.3.6",
+ "futures 0.3.8",
"httparse",
"log",
"rand 0.7.3",
- "sha-1 0.9.1",
+ "sha-1 0.9.2",
]
[[package]]
name = "sp-allocator"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
"log",
@@ -6080,7 +6270,7 @@
[[package]]
name = "sp-api"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"hash-db",
"parity-scale-codec",
@@ -6095,7 +6285,7 @@
[[package]]
name = "sp-api-proc-macro"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"blake2-rfc",
"proc-macro-crate",
@@ -6107,7 +6297,7 @@
[[package]]
name = "sp-application-crypto"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"serde",
@@ -6119,7 +6309,7 @@
[[package]]
name = "sp-arithmetic"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"integer-sqrt",
"num-traits",
@@ -6132,7 +6322,7 @@
[[package]]
name = "sp-authorship"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-inherents",
@@ -6143,7 +6333,7 @@
[[package]]
name = "sp-block-builder"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-api",
@@ -6155,7 +6345,7 @@
[[package]]
name = "sp-blockchain"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
"log",
@@ -6172,7 +6362,7 @@
[[package]]
name = "sp-chain-spec"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"serde",
"serde_json",
@@ -6181,10 +6371,10 @@
[[package]]
name = "sp-consensus"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-timer 3.0.2",
"libp2p",
"log",
@@ -6207,7 +6397,7 @@
[[package]]
name = "sp-consensus-aura"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-api",
@@ -6221,7 +6411,7 @@
[[package]]
name = "sp-consensus-slots"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-runtime",
@@ -6230,7 +6420,7 @@
[[package]]
name = "sp-core"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"base58",
"blake2-rfc",
@@ -6238,7 +6428,7 @@
"derive_more",
"dyn-clonable",
"ed25519-dalek",
- "futures 0.3.6",
+ "futures 0.3.8",
"hash-db",
"hash256-std-hasher",
"hex",
@@ -6274,7 +6464,7 @@
[[package]]
name = "sp-database"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"kvdb",
"parking_lot 0.10.2",
@@ -6283,7 +6473,7 @@
[[package]]
name = "sp-debug-derive"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"proc-macro2",
"quote",
@@ -6293,7 +6483,7 @@
[[package]]
name = "sp-externalities"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"environmental",
"parity-scale-codec",
@@ -6304,7 +6494,7 @@
[[package]]
name = "sp-finality-grandpa"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"finality-grandpa",
"log",
@@ -6320,7 +6510,7 @@
[[package]]
name = "sp-finality-tracker"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-inherents",
@@ -6330,7 +6520,7 @@
[[package]]
name = "sp-inherents"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
"parity-scale-codec",
@@ -6342,9 +6532,9 @@
[[package]]
name = "sp-io"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"hash-db",
"libsecp256k1",
"log",
@@ -6365,7 +6555,7 @@
[[package]]
name = "sp-keyring"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"lazy_static",
"sp-core",
@@ -6376,7 +6566,7 @@
[[package]]
name = "sp-offchain"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"sp-api",
"sp-core",
@@ -6386,7 +6576,7 @@
[[package]]
name = "sp-panic-handler"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"backtrace",
"log",
@@ -6395,7 +6585,7 @@
[[package]]
name = "sp-rpc"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"serde",
"sp-core",
@@ -6404,7 +6594,7 @@
[[package]]
name = "sp-runtime"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"either",
"hash256-std-hasher",
@@ -6426,7 +6616,7 @@
[[package]]
name = "sp-runtime-interface"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"primitive-types",
@@ -6442,7 +6632,7 @@
[[package]]
name = "sp-runtime-interface-proc-macro"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"Inflector",
"proc-macro-crate",
@@ -6454,7 +6644,7 @@
[[package]]
name = "sp-sandbox"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-core",
@@ -6467,7 +6657,7 @@
[[package]]
name = "sp-serializer"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"serde",
"serde_json",
@@ -6476,7 +6666,7 @@
[[package]]
name = "sp-session"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-api",
@@ -6489,7 +6679,7 @@
[[package]]
name = "sp-staking"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"parity-scale-codec",
"sp-runtime",
@@ -6499,7 +6689,7 @@
[[package]]
name = "sp-state-machine"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"hash-db",
"log",
@@ -6507,7 +6697,7 @@
"parity-scale-codec",
"parking_lot 0.10.2",
"rand 0.7.3",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"sp-core",
"sp-externalities",
"sp-panic-handler",
@@ -6520,12 +6710,12 @@
[[package]]
name = "sp-std"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
[[package]]
name = "sp-storage"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"impl-serde",
"parity-scale-codec",
@@ -6538,7 +6728,7 @@
[[package]]
name = "sp-timestamp"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"impl-trait-for-tuples",
"parity-scale-codec",
@@ -6552,7 +6742,7 @@
[[package]]
name = "sp-tracing"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"log",
"parity-scale-codec",
@@ -6565,10 +6755,10 @@
[[package]]
name = "sp-transaction-pool"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"derive_more",
- "futures 0.3.6",
+ "futures 0.3.8",
"log",
"parity-scale-codec",
"serde",
@@ -6580,7 +6770,7 @@
[[package]]
name = "sp-trie"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"hash-db",
"memory-db",
@@ -6594,9 +6784,9 @@
[[package]]
name = "sp-utils"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"futures-core",
"futures-timer 3.0.2",
"lazy_static",
@@ -6606,7 +6796,7 @@
[[package]]
name = "sp-version"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"impl-serde",
"parity-scale-codec",
@@ -6618,7 +6808,7 @@
[[package]]
name = "sp-wasm-interface"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"impl-trait-for-tuples",
"parity-scale-codec",
@@ -6651,15 +6841,6 @@
checksum = "10102ac8d55e35db2b3fafc26f81ba8647da2e15879ab686a67e6d19af2685e8"
dependencies = [
"rand 0.5.6",
-]
-
-[[package]]
-name = "stream-cipher"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c"
-dependencies = [
- "generic-array 0.12.3",
]
[[package]]
@@ -6689,9 +6870,9 @@
[[package]]
name = "structopt"
-version = "0.3.20"
+version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8"
+checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c"
dependencies = [
"clap",
"lazy_static",
@@ -6700,9 +6881,9 @@
[[package]]
name = "structopt-derive"
-version = "0.4.13"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8"
+checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90"
dependencies = [
"heck",
"proc-macro-error",
@@ -6748,7 +6929,7 @@
[[package]]
name = "substrate-build-script-utils"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"platforms",
]
@@ -6756,10 +6937,10 @@
[[package]]
name = "substrate-frame-rpc-system"
version = "2.0.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"frame-system-rpc-runtime-api",
- "futures 0.3.6",
+ "futures 0.3.8",
"jsonrpc-core",
"jsonrpc-core-client",
"jsonrpc-derive",
@@ -6779,15 +6960,15 @@
[[package]]
name = "substrate-prometheus-endpoint"
version = "0.8.0"
-source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+source = "git+https://github.com/usetech-llc/substrate.git?branch=release_flexi#59646c902484d9c5e8933a80cbed551228b81274"
dependencies = [
"async-std",
"derive_more",
"futures-util",
- "hyper 0.13.8",
+ "hyper 0.13.9",
"log",
"prometheus",
- "tokio 0.2.22",
+ "tokio 0.2.24",
]
[[package]]
@@ -6804,15 +6985,15 @@
[[package]]
name = "subtle"
-version = "2.3.0"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd"
+checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
[[package]]
name = "syn"
-version = "1.0.44"
+version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e03e57e4fcbfe7749842d53e24ccb9aa12b7252dbe5e91d2acad31834c8b8fdd"
+checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
dependencies = [
"proc-macro2",
"quote",
@@ -6859,9 +7040,9 @@
[[package]]
name = "termcolor"
-version = "1.1.0"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
@@ -6877,18 +7058,18 @@
[[package]]
name = "thiserror"
-version = "1.0.21"
+version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "318234ffa22e0920fe9a40d7b8369b5f649d490980cf7aadcf1eb91594869b42"
+checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.21"
+version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab"
+checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
dependencies = [
"proc-macro2",
"quote",
@@ -6932,7 +7113,7 @@
dependencies = [
"failure",
"hmac",
- "once_cell 1.4.1",
+ "once_cell 1.5.2",
"pbkdf2",
"rand 0.7.3",
"rustc-hash",
@@ -6951,9 +7132,18 @@
[[package]]
name = "tinyvec"
-version = "0.3.4"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
@@ -6981,9 +7171,9 @@
[[package]]
name = "tokio"
-version = "0.2.22"
+version = "0.2.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
+checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48"
dependencies = [
"bytes 0.5.6",
"fnv",
@@ -6995,7 +7185,7 @@
"mio",
"mio-uds",
"num_cpus",
- "pin-project-lite",
+ "pin-project-lite 0.1.11",
"signal-hook-registry",
"slab",
"winapi 0.3.9",
@@ -7039,7 +7229,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671"
dependencies = [
- "crossbeam-utils",
+ "crossbeam-utils 0.7.2",
"futures 0.1.30",
]
@@ -7095,7 +7285,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351"
dependencies = [
- "crossbeam-utils",
+ "crossbeam-utils 0.7.2",
"futures 0.1.30",
"lazy_static",
"log",
@@ -7116,7 +7306,7 @@
dependencies = [
"futures-core",
"rustls",
- "tokio 0.2.22",
+ "tokio 0.2.24",
"webpki",
]
@@ -7170,9 +7360,9 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89"
dependencies = [
- "crossbeam-deque",
+ "crossbeam-deque 0.7.3",
"crossbeam-queue",
- "crossbeam-utils",
+ "crossbeam-utils 0.7.2",
"futures 0.1.30",
"lazy_static",
"log",
@@ -7187,7 +7377,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296"
dependencies = [
- "crossbeam-utils",
+ "crossbeam-utils 0.7.2",
"futures 0.1.30",
"slab",
"tokio-executor 0.1.10",
@@ -7236,8 +7426,8 @@
"futures-core",
"futures-sink",
"log",
- "pin-project-lite",
- "tokio 0.2.22",
+ "pin-project-lite 0.1.11",
+ "tokio 0.2.24",
]
[[package]]
@@ -7257,13 +7447,13 @@
[[package]]
name = "tracing"
-version = "0.1.21"
+version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27"
+checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"log",
- "pin-project-lite",
+ "pin-project-lite 0.2.0",
"tracing-attributes",
"tracing-core",
]
@@ -7289,6 +7479,16 @@
]
[[package]]
+name = "tracing-futures"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
+dependencies = [
+ "pin-project 0.4.27",
+ "tracing",
+]
+
+[[package]]
name = "tracing-log"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -7311,9 +7511,9 @@
[[package]]
name = "tracing-subscriber"
-version = "0.2.13"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ef0a5e15477aa303afbfac3a44cba9b6430fdaad52423b1e6c0dbbe28c3eedd"
+checksum = "a1fa8f0c8f4c594e4fc9debc1990deab13238077271ba84dd853d54902ee3401"
dependencies = [
"ansi_term 0.12.1",
"chrono",
@@ -7323,7 +7523,7 @@
"serde",
"serde_json",
"sharded-slab",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"thread_local",
"tracing",
"tracing-core",
@@ -7341,7 +7541,7 @@
"hashbrown 0.8.2",
"log",
"rustc-hex",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
]
[[package]]
@@ -7408,18 +7608,18 @@
[[package]]
name = "unicode-normalization"
-version = "0.1.13"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
+checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
-version = "1.6.0"
+version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
+checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
[[package]]
name = "unicode-width"
@@ -7440,7 +7640,7 @@
checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402"
dependencies = [
"generic-array 0.14.4",
- "subtle 2.3.0",
+ "subtle 2.4.0",
]
[[package]]
@@ -7484,10 +7684,11 @@
[[package]]
name = "url"
-version = "2.1.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
+checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
dependencies = [
+ "form_urlencoded",
"idna 0.2.0",
"matches",
"percent-encoding 2.1.0",
@@ -7495,9 +7696,9 @@
[[package]]
name = "vcpkg"
-version = "0.2.10"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
+checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
[[package]]
name = "vec-arena"
@@ -7564,19 +7765,19 @@
[[package]]
name = "wasm-bindgen"
-version = "0.2.68"
+version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
+checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.68"
+version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
+checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62"
dependencies = [
"bumpalo",
"lazy_static",
@@ -7589,11 +7790,11 @@
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.18"
+version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da"
+checksum = "1fe9756085a84584ee9457a002b7cdfe0bfff169f45d2591d8be1345a6780e35"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"js-sys",
"wasm-bindgen",
"web-sys",
@@ -7601,9 +7802,9 @@
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.68"
+version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
+checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -7611,9 +7812,9 @@
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.68"
+version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
+checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549"
dependencies = [
"proc-macro2",
"quote",
@@ -7624,9 +7825,9 @@
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.68"
+version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
+checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158"
[[package]]
name = "wasm-timer"
@@ -7634,9 +7835,9 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"js-sys",
- "parking_lot 0.11.0",
+ "parking_lot 0.11.1",
"pin-utils",
"wasm-bindgen",
"wasm-bindgen-futures",
@@ -7692,7 +7893,7 @@
"log",
"region",
"rustc-demangle",
- "smallvec 1.4.2",
+ "smallvec 1.5.1",
"target-lexicon",
"wasmparser 0.59.0",
"wasmtime-environ",
@@ -7825,7 +8026,7 @@
"lazy_static",
"libc",
"log",
- "memoffset",
+ "memoffset 0.5.6",
"more-asserts",
"region",
"thiserror",
@@ -7835,27 +8036,27 @@
[[package]]
name = "wast"
-version = "26.0.0"
+version = "30.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d54b3678343bfdf1768c16308a4b53823b70f7bb148d3d38225123d4306ec731"
+checksum = "9b79907b22f740634810e882d8d1d9d0f9563095a8ab94e786e370242bff5cd2"
dependencies = [
"leb128",
]
[[package]]
name = "wat"
-version = "1.0.27"
+version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26b2dccbce4d0e14875091846e110a2369267b18ddd0d6423479b88dad914d71"
+checksum = "a8279a02835bf12e61ed2b3c3cbc6ecf9918762fd97e036917c11a09ec20ca44"
dependencies = [
"wast",
]
[[package]]
name = "web-sys"
-version = "0.3.45"
+version = "0.3.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d"
+checksum = "222b1ef9334f92a21d3fb53dc3fd80f30836959a90f9274a626d7e06315ba3c3"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -7863,9 +8064,9 @@
[[package]]
name = "webpki"
-version = "0.21.3"
+version = "0.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae"
+checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
dependencies = [
"ring",
"untrusted",
@@ -7891,9 +8092,9 @@
[[package]]
name = "wepoll-sys"
-version = "3.0.0"
+version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "142bc2cba3fe88be1a8fcb55c727fa4cd5b0cf2d7438722792e22f26f04bc1e0"
+checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff"
dependencies = [
"cc",
]
@@ -7988,19 +8189,25 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aeb8c4043cac71c3c299dff107171c220d179492350ea198e109a414981b83c"
dependencies = [
- "futures 0.3.6",
+ "futures 0.3.8",
"log",
"nohash-hasher",
- "parking_lot 0.11.0",
+ "parking_lot 0.11.1",
"rand 0.7.3",
"static_assertions",
]
[[package]]
+name = "yansi"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71"
+
+[[package]]
name = "zeroize"
-version = "1.1.1"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a"
+checksum = "81a974bcdd357f0dca4d41677db03436324d45a4c9ed2d0b873a5a360ce41c36"
dependencies = [
"zeroize_derive",
]
@@ -8019,18 +8226,18 @@
[[package]]
name = "zstd"
-version = "0.5.3+zstd.1.4.5"
+version = "0.5.4+zstd.1.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8"
+checksum = "69996ebdb1ba8b1517f61387a883857818a66c8a295f487b1ffd8fd9d2c82910"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
-version = "2.0.5+zstd.1.4.5"
+version = "2.0.6+zstd.1.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055"
+checksum = "98aa931fb69ecee256d44589d19754e61851ae4769bf963b385119b1cc37a49e"
dependencies = [
"libc",
"zstd-sys",
@@ -8038,9 +8245,9 @@
[[package]]
name = "zstd-sys"
-version = "1.4.17+zstd.1.4.5"
+version = "1.4.18+zstd.1.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b"
+checksum = "a1e6e8778706838f43f771d80d37787cb2fe06dafe89dd3aebaf6721b9eaec81"
dependencies = [
"cc",
"glob",
LICENSEdiffbeforeafterboth--- a/LICENSE
+++ b/LICENSE
@@ -1,24 +1,15 @@
-This is free and unencumbered software released into the public domain.
-
-Anyone is free to copy, modify, publish, use, compile, sell, or
-distribute this software, either in source code form or as a compiled
-binary, for any purpose, commercial or non-commercial, and by any
-means.
-
-In jurisdictions that recognize copyright laws, the author or authors
-of this software dedicate any and all copyright interest in the
-software to the public domain. We make this dedication for the benefit
-of the public at large and to the detriment of our heirs and
-successors. We intend this dedication to be an overt act of
-relinquishment in perpetuity of all present and future rights to this
-software under copyright law.
+USETECH PROFESSIONAL CONFIDENTIAL
+__________________
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
+ [2019] - [2020] UseTech Professional LTD.
+ All Rights Reserved.
-For more information, please refer to <http://unlicense.org>
+NOTICE: All information contained herein is, and remains
+the property of UseTech Professional LTD. and its suppliers,
+if any. The intellectual and technical concepts contained
+herein are proprietary to UseTech Professional LTD.
+and its suppliers and may be covered by U.S. and Foreign Patents,
+patents in process, and are protected by trade secret or copyright law.
+Dissemination of this information or reproduction of this material
+is strictly forbidden unless prior written permission is obtained
+from UseTech Professional LTD..
README.mddiffbeforeafterboth--- a/README.md
+++ b/README.md
@@ -52,28 +52,27 @@
2. Remove all installed toolchains with `rustup toolchain list` and `rustup toolchain uninstall <toolchain>`.
-3. Install Rust Toolchain 1.44.0:
+3. Install Toolchain and make it default:
```bash
-rustup install 1.44.0
+rustup toolchain install nightly-2020-10-01
+rustup default nightly-2020-10-01
```
-4. Make it default (actual toochain version may be different, so do a `rustup toolchain list` first)
+4. Add wasm target for default toolchain:
+
```bash
-rustup toolchain list
-rustup default 1.44.0-x86_64-unknown-linux-gnu
+rustup target add wasm32-unknown-unknown
```
-5. Install nightly toolchain and add wasm target for it:
-
+5. Build:
```bash
-rustup toolchain install nightly-2020-05-01
-rustup target add wasm32-unknown-unknown --toolchain nightly-2020-05-01-x86_64-unknown-linux-gnu
+cargo build
```
-6. Build:
+optionally, build in release:
```bash
-cargo build
+cargo build --release
```
## Run
@@ -134,4 +133,8 @@
## UI custom types
-Moved to [runtime_types.json](./runtime_types.json).
\ No newline at end of file
+Moved to [runtime_types.json](./runtime_types.json).
+
+## Running Integration Tests
+
+See [tests/README.md](./tests/README.md).
\ No newline at end of file
doc/builders_walk_through.mddiffbeforeafterboth--- /dev/null
+++ b/doc/builders_walk_through.md
@@ -0,0 +1,244 @@
+# Builders Program Walk-Through
+
+This document walks through current state of Uniquch Chain as of end of October 2020.
+
+## Unique Chain Source code
+
+Unique chain is a substrate based chain, which mainly consists of NFT pallet (developed by Unique Network) and Smart Contracts pallet.
+
+As of now, it is based off Substrate 2.0 release and supports Ink! 3.0 smart contracts.
+
+[Unique Chain](https://github.com/usetech-llc/nft_private)
+
+### Unique TestNet
+
+The TestNet public node is avaiable at wss://unique.usetech.com. It connects to the standard AppsUI (works best with our version of AppsUI, see below, but connection can be still tested with Polkadot.js.org):
+
+1. Open the [Apps UI](https://polkadot.js.org/apps/#)
+2. Click on the network icon in the top left corner
+3. Scroll down the list and input `wss://unique.usetech.com` under "custom endpoint"
+4. After connection is established, copy these [UI Custom Types](https://github.com/usetech-llc/nft_parachain#ui-custom-types) and paste them in [Developer Settings](https://polkadot.js.org/apps/#/settings/developer). Hit "Save" button.
+5. Now the NFT node is connected with AppsUI.
+6. Go to [Chain State](https://polkadot.js.org/apps/#/chainstate) and verify that NFT pallet is visible and you can read information from it.
+7. For example, select nft -> collection, and enter collection ID 4 (for SubstraPunks) and click "+" button. You will see the collection properties such as UTF-16 encoded collection name and description, UTF-8 encoded token prefix, the size of custom data, etc.
+
+#### Getting some Unique Tokens
+
+1. Install Polkadot{.js} extension if you don't have it already installed. Here are the links for [Chrome](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd) and [Firefox](https://addons.mozilla.org/en-US/firefox/addon/polkadot-js-extension/) extensions.
+2. Create an address
+3. Use Unique Faucet Telegram bot: @UniqueFaucetBot
+
+### Smart Contracts Pallet
+
+1. Open [Contracts](https://polkadot.js.org/apps/#/contracts) tab. It only appears in the UI when Smart Contracts pallet is included in the runtime.
+2. Additionally, we can find an existing smart contract. Click on "Add an existing contract" link.
+3. Input this contract address: `5GdNqKMv4Sszq3SRd3TkXNa6a9ct4D3nXvtTWTFR7rTyccVJ`
+4. Input any contract name, for example `Claim Substrapunks`
+5. Download and drag-and-drop this [metadata.json](https://github.com/usetech-llc/substrapunks/releases/download/v1.0.2/metadata.json) file into contract ABI field.
+6. Click Save. The contract appears in the page. If the contract did not exist at that address, the UI would display an error message: "Unable to find deployed contract code at the specified address".
+
+### Integration Between Smart Contracts and NFT Pallet
+
+#### TestNet
+
+This is one of the most technically challenging parts. The pre-RC4 versions of Substrate did not function properly when we tried to use `ext_dispatch_call` to dispatch a runtime call to NFT pallet from Contracts pallet, and RC4 had the `ext_dispatch_call` already removed to "free space" for some friendlier way of interaction between pallets, that was not yet implemented. Thanks to Alexander Theißen who reverted the removal of `ext_dispatch_call` and created a special branch based on RC4 for us!
+
+The smart contract source code exists in this [repository folder](https://github.com/usetech-llc/nft_parachain/tree/master/smart_contract/ink-types-node-runtime), but the best way to test how the interaction between smart contracts and NFT pallet works is to see it in action using the [SubstraPunks Game Example](https://ipfs-gateway.usetech.com/ipns/QmaMtDqE9nhMX9RQLTpaCboqg7bqkb6Gi67iCKMe8NDpCE/) that uses smart contract to claim free characters. The complete demo of this game will come later, so please bare with us and let's put this item demonstration for a bit later.
+
+#### MainNet
+
+The Ink! 3.0 Chain Extensions will allow calling pallets from smart contracts with env() object in Ink!, as soon as they are ready. Our code is prewired for this and waiting for Chain Extensions to release.
+
+### Fungibility and Re-Fungibility support
+
+Fungible and Re-Fungible modes are fully implemented and ready for QA as of now. Fungible mode allows creation of ERC-20-like tokens, and Re-Fungible allows sharing NFT tokens between multiple addresses.
+
+#### Re-Fungibility
+
+Re-fungible feature is best demonstrated in action using our NFT wallet. First, you need to have some Unique and Re-Fungible tokens. [This section](#getting-some-unique-tokens) tells how to get them.
+
+1. Open the [NFT Wallet](https://uniqueapps.usetech.com/#/nft)
+2. Search for collection called "Artwork". Search can be done either by collection name or collection ID (which is 2).
+3. Click on "+ Add collection" in search results. The collection will appear under "My collections"
+4. Expand the "Artwork" collection and see that you own a token with a partial balance
+5. Transfer the token to some other address: Click "Transfer token" and enter address and the amount. Amount should be entered as decimal fraction. For example "0.01" to transfer 1/100th part of the token.
+6. Observe that your balance decreased by the amount you entered.
+
+#### Fungibility
+
+Fungible tokens can be created manually by calling extrinsics:
+1. Open [Extrinsics page in UI](https://uniqueapps.usetech.com/#/extrinsics)
+2. Select nft - createCollection
+3. In the CollectionMode select Fungible, enter decimal points number and click "Submit Transaction"
+4. Switch to [Explorer](https://uniqueapps.usetech.com/#/explorer) and find the block where the transaction was mined.
+5. Find nft.Created Event, which will contain the ID of the Fungible token you just created
+6. In order to mint a token, use nft - createItem extrinsic. Enter the collection ID (that you found in the previous step) and submit transaction. One token will be minted. (We also support Batch minting for minting different amounts, etc).
+
+#### Re-fungibility The Hard Way
+
+Also, the Re-Fungible support can be demonstrated using the standard UI features without NFT wallet.
+
+1. Open [Chain State](https://uniqueapps.usetech.com/#/chainstate).
+2. Select "nft" - "reFungbleItemList"
+3. Enter parameters: 2 and 1, click "+" button
+4. Observe the following data structure returned:
+
+```
+{
+ Collection: 2,
+ Owner: [
+ {
+ owner: 5FNujvbtMyKoJC2zTrfGVaQek7jhfR1L558BMhogfFfD7veH,
+ fraction: 3,000
+ },
+ {
+ owner: 5D73wtH5pqN99auP4b6KQRQAbketaSj4StkBJxACPBUAUdiq,
+ fraction: 3,000
+ },
+ {
+ owner: 5FZeTmbZQZsJcyEevjGVK1HHkcKfWBYxWpbgEffQ2M1SqAnP,
+ fraction: 2,000
+ },
+ {
+ owner: 5EnzEXBuxFHdymceAAtstym8FETQqH4inx29XJSP6uHaCUiP,
+ fraction: 1,000
+ },
+ {
+ owner: 5GU6iHnc3qTMaufmKYzHUpDmVN2CgzA2JMcGFQLcKNDbE7c6,
+ fraction: 1,000
+ }
+ ],
+ Data:
+}
+```
+
+The Owner field contains a list of owners with the fractions they own. The fractions are represented as fixed point decimals. The number of decimal points in this fraction is determined by collection properties. For example, in the Artwork collection this property is equal to 4. The owned fraction is then determined as `fraction` divided by 10^DecimalPoints, i.e. 10,000 in this case.
+
+5. Staying in Chain State, select "nft" - "colection"
+6. Input "2" and click "+"
+7. Observe the following structure returned. It tells that collection is ReFungible and DecimalPoints field is equal to 4.
+
+```
+{
+ Owner: 5FNujvbtMyKoJC2zTrfGVaQek7jhfR1L558BMhogfFfD7veH,
+ Mode: {
+ ReFungible: [
+ 0,
+ 4
+ ]
+ },
+ Access: 0,
+ DecimalPoints: 4,
+ Name: [
+...
+```
+
+### Off-Chain Schema to store token image URLs
+
+This feature is best demonstrated in action using our NFT wallet. First, you need to have some Unique and Re-Fungible tokens. [This section](#getting-some-unique-tokens) tells how to get them.
+
+1. Open the [NFT Wallet](https://uniqueapps.usetech.com/#/nft)
+2. Search for collection called "Artwork". Search can be done either by collection name or collection ID (which is 2).
+3. Expand "Artwork" collection
+4. Click on the image to zoom in.
+5. Right-click on the image and select "Open Image in New Tab"
+6. Note the image URL:
+```
+https://ipfs-gateway.usetech.com/ipfs/QmUSv64cUmL2m44QYkUFWmH89qykC8VLPFwjhpeAScjejS/image1.jpg
+```
+7. Open [Chain State](https://uniqueapps.usetech.com/#/chainstate).
+8. Select "nft" - "colection"
+9. Input "2" and click "+"
+10. Scroll down:
+```
+ ],
+ TokenPrefix: ARTu0000,
+ CustomDataSize: 0,
+ OffchainSchema: https://ipfs-gateway.usetech.com/ipfs/QmUSv64cUmL2m44QYkUFWmH89qykC8VLPFwjhpeAScjejS/image{id}.jpg,
+ Sponsor: 5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM,
+ UnconfirmedSponsor: 5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM
+}
+```
+11. Observe the field called `OffchainSchema`. This field defines the URL schema that is used to contruct token URLs based on the token ID. In this particular example, the {id} template variable is replaced with token id 1, which results in the proper image URL.
+
+### New economic models
+
+This feature is best demonstrated when you own a SubstraPunk character. Please proceed with the demonstration, and then come back after you claim one.
+
+1. Create a new address in Polkadot{.js} extension. We need an address that has zero balance in Unique tokens. Let's call it "ZERO BALANCE" address.
+2. Open the [NFT Wallet](https://uniqueapps.usetech.com/#/nft)
+3. Search for collection called "SubstraPunks" (partial search also works, so you can just type "punk" and hit Enter)
+4. Add collection
+5. Expand substrapunks collection and transfer your PNK token to your "ZERO BALANCE" address.
+6. Now select your "ZERO BALANCE" address in the drop-down list and repeat searching and adding the collection for this address.
+7. Transfer token back to your main address. Observe that despite the zero balance, the transfer is successful.
+
+### White Lists and Public Mint Permission
+
+We did not complete these features in time by Hackusama deadline, but because they are important for security of the network, we completed them after the deadline anyway. They can be seen in branch [feature/white_list](https://github.com/usetech-llc/nft_parachain/tree/feature/white_list). Here are the permalinks to essential functions:
+
+[white_lists](https://github.com/usetech-llc/nft_parachain/blob/b7c59f0085ed2bc1922e937adf68ef4174a8ba36/pallets/nft/src/lib.rs#L659)
+
+[mint_permission](https://github.com/usetech-llc/nft_parachain/blob/b7c59f0085ed2bc1922e937adf68ef4174a8ba36/pallets/nft/src/lib.rs#L373)
+
+## NFT Wallet
+
+[Project Description](https://github.com/usetech-llc/apps/blob/master/README.md)
+
+All features of the NFT Wallet were already demonstrated previously:
+
+* Enables adding favorite collections
+* Shows tokens owned
+* Allows NFT and Re-Fungible transfers
+* Shows Re-Fungible Balances
+* Shows Token Images
+
+## Our version of AppsUI
+
+The UI was also mainly demonstrated. We only need to show some configuration that happens behind the scenes:
+
+### Loads appropriate custom API types
+1. Open the [NFT Wallet Developer Settings](https://uniqueapps.usetech.com/#/settings/developer)
+2. Observe that Custom UI types are already in place
+
+### Defaults to NFT TestNet
+
+1. Open the [NFT Wallet](https://uniqueapps.usetech.com/)
+2. Observe that Unique Network icon appears in the left top corner without a need to specify the network
+3. Click on Unique Network icon and see that `NFT Testnet` is in the network list
+
+## Unity API and SDK PoC
+
+[Project Description](https://github.com/usetech-llc/nft_unity/blob/master/README.md)
+
+In order to see Unity Asset in action, please follow the instructions in this README file:
+
+[Demonstration](https://github.com/usetech-llc/nft_unity/blob/master/src/DemoApplication/readme.md)
+
+## SubstraPunks Game and Marketplace
+
+[Project Description](https://github.com/usetech-llc/substrapunks/blob/master/README.md)
+
+First, you will need some Unique balance. [This section](#getting-some-unique-tokens) tells how to get the TestNet currency.
+
+This game initially was meant as a demonstration, but all Punks were quickly claimed, and we had to develop the marketplace to keep demonstrating capability of it. [Here](https://github.com/usetech-llc/nft_parachain/blob/master/doc/hackusama_walk_through.md#substrapunks-game) is the original description.
+
+Here is how one can test Marketplace:
+
+1. Open [Substrapunks Marketplace](https://ipfs-gateway.usetech.com/ipns/QmaMtDqE9nhMX9RQLTpaCboqg7bqkb6Gi67iCKMe8NDpCE/)
+2. Contact us in [Unique Telegram channel](https://t.me/Uniquechain), so we can place a test NFT for you buy on the marketplace.
+3. Refresh the marketplace page and click on the NFT to buy (the one we placed)
+4. Go through buying process
+5. Let us know to exchange KSM back for the NFT (if you would not like to keep the punk of course :) )
+
+### How Marketplace works
+
+Marketplace is a PoC and it consists a PoC bridge between Kusama and Unique and a Matcher smart contract.
+
+#### Kusama Bridge
+
+The bridge works mainly as an escrow that locks NFTs and KSM allowing users to trustlessly exchange their assets.
+
+#### Matcher Smart Contract
+
+The matcher smart contract allows placing punks on sale and buying. It operates assets that are locked in the bridge and releases them once the trade happens or the offer is cancelled.
node/Cargo.tomldiffbeforeafterboth--- a/node/Cargo.toml
+++ b/node/Cargo.toml
@@ -58,6 +58,9 @@
substrate-frame-rpc-system = {version = '2.0.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
pallet-contracts-rpc = {version = '0.8.0', git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi'}
+serde = { version = "1.0.102", features = ["derive"] }
+serde_json = "1.0.41"
+
[features]
default = []
runtime-benchmarks = ['nft-runtime/runtime-benchmarks']
node/build.rsdiffbeforeafterboth--- a/node/build.rs
+++ b/node/build.rs
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed};
fn main() {
node/src/chain_spec.rsdiffbeforeafterboth--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
// use nft_runtime::{
// AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig,
// SystemConfig, WASM_BINARY,
@@ -9,6 +14,7 @@
use sp_core::{sr25519, Pair, Public};
use sp_finality_grandpa::AuthorityId as GrandpaId;
use sp_runtime::traits::{IdentifyAccount, Verify};
+use serde_json::map::Map;
// Note this is the URL for the telemetry server
//const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
@@ -41,6 +47,11 @@
pub fn development_config() -> Result<ChainSpec, String> {
let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?;
+ let mut properties = Map::new();
+ properties.insert("tokenSymbol".into(), "UniqueTest".into());
+ properties.insert("tokenDecimals".into(), 15.into());
+ properties.insert("ss58Format".into(), 42.into()); // Generic Substrate wildcard (SS58 checksum preimage)
+
Ok(ChainSpec::from_genesis(
// Name
"Development",
@@ -71,7 +82,7 @@
// Protocol ID
None,
// Properties
- None,
+ Some(properties),
// Extensions
None,
))
@@ -132,6 +143,11 @@
endowed_accounts: Vec<AccountId>,
enable_println: bool,
) -> GenesisConfig {
+
+ let vested_accounts = vec![
+ get_account_id_from_seed::<sr25519::Public>("Bob"),
+ ];
+
GenesisConfig {
system: Some(SystemConfig {
code: wasm_binary.to_vec(),
@@ -154,7 +170,14 @@
.collect(),
}),
pallet_treasury: Some(Default::default()),
- pallet_sudo: Some(SudoConfig { key: root_key }),
+ pallet_sudo: Some(SudoConfig { key: root_key }),
+ pallet_vesting: Some(VestingConfig {
+ vesting: vested_accounts
+ .iter()
+ .cloned()
+ .map(|k| (k, 1000, 100, 1 << 98))
+ .collect(),
+ }),
pallet_nft: Some(NftConfig {
collection: vec![(
1,
@@ -170,7 +193,7 @@
offchain_schema: vec![],
schema_version: SchemaVersion::default(),
sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),
- unconfirmed_sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),
+ sponsor_confirmed: true,
const_on_chain_schema: vec![],
variable_on_chain_schema: vec![],
limits: CollectionLimits::default()
@@ -180,8 +203,8 @@
fungible_item_id: vec![],
refungible_item_id: vec![],
chain_limit: ChainLimits {
- collection_numbers_limit: 10,
- account_token_ownership_limit: 10,
+ collection_numbers_limit: 100000,
+ account_token_ownership_limit: 1000000,
collections_admins_limit: 5,
custom_data_limit: 2048,
nft_sponsor_transfer_timeout: 15,
node/src/main.rsdiffbeforeafterboth--- a/node/src/main.rs
+++ b/node/src/main.rs
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
//! Substrate Node Template CLI library.
#![warn(missing_docs)]
node/src/service.rsdiffbeforeafterboth--- a/node/src/service.rs
+++ b/node/src/service.rs
@@ -1,5 +1,10 @@
//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
use std::sync::Arc;
use std::time::Duration;
use sc_client_api::{ExecutorProvider, RemoteBackend};
pallets/nft/src/benchmarking.rsdiffbeforeafterboth--- a/pallets/nft/src/benchmarking.rs
+++ b/pallets/nft/src/benchmarking.rs
@@ -355,4 +355,66 @@
Nft::<T>::create_item(RawOrigin::Signed(caller.clone()).into(), 2, caller.clone(), data)?;
}: set_variable_meta_data(RawOrigin::Signed(caller.clone()), 2, 1, [1, 2, 3].to_vec())
+
+ set_schema_version {
+ let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
+ let mode: CollectionMode = CollectionMode::NFT;
+ let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
+ Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+ }: set_schema_version(RawOrigin::Signed(caller.clone()), 2, SchemaVersion::Unique)
+
+ set_chain_limits {
+ let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
+ let limits = ChainLimits {
+ collection_numbers_limit: 0,
+ account_token_ownership_limit: 0,
+ collections_admins_limit: 0,
+ custom_data_limit: 0,
+ nft_sponsor_transfer_timeout: 0,
+ fungible_sponsor_transfer_timeout: 0,
+ refungible_sponsor_transfer_timeout: 0
+ };
+ }: set_chain_limits(RawOrigin::Signed(caller.clone()), limits)
+
+ set_contract_sponsoring_rate_limit {
+ let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
+ let mode: CollectionMode = CollectionMode::NFT;
+ let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
+ Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+ let block_number: T::BlockNumber = 0.into();
+ }: set_contract_sponsoring_rate_limit(RawOrigin::Signed(caller.clone()), caller.clone(), block_number)
+
+ set_collection_limits{
+ let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
+ let mode: CollectionMode = CollectionMode::NFT;
+ let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
+ Nft::<T>::create_collection(RawOrigin::Signed(caller.clone()).into(), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode.clone())?;
+
+ let cl = CollectionLimits {
+ account_token_ownership_limit: 0,
+ sponsored_data_size: 0,
+ token_limit: 0,
+ sponsor_transfer_timeout: 0
+ };
+
+ }: set_collection_limits(RawOrigin::Signed(caller.clone()), 2, cl)
+
+ add_to_contract_white_list{
+ let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
+ }: add_to_contract_white_list(RawOrigin::Signed(caller.clone()), caller.clone(), caller.clone())
+
+ remove_from_contract_white_list{
+ let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
+ Nft::<T>::add_to_contract_white_list(RawOrigin::Signed(caller.clone()).into(), caller.clone(), caller.clone())?;
+ }: remove_from_contract_white_list(RawOrigin::Signed(caller.clone()), caller.clone(), caller.clone())
+
+ toggle_contract_white_list{
+ let caller: T::AccountId = T::AccountId::from(whitelisted_caller());
+ }: toggle_contract_white_list(RawOrigin::Signed(caller.clone()), caller.clone(), true)
}
\ No newline at end of file
pallets/nft/src/default_weights.rsdiffbeforeafterboth--- a/pallets/nft/src/default_weights.rs
+++ b/pallets/nft/src/default_weights.rs
@@ -107,19 +107,44 @@
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
- // fn set_chain_limits() -> Weight {
- // (0 as Weight)
- // .saturating_add(DbWeight::get().reads(1 as Weight))
- // .saturating_add(DbWeight::get().writes(1 as Weight))
- // }
fn enable_contract_sponsoring() -> Weight {
(13_000_000 as Weight)
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
- // fn set_contract_sponsoring_rate_limit() -> Weight {
- // (0 as Weight)
- // .saturating_add(DbWeight::get().reads(1 as Weight))
- // .saturating_add(DbWeight::get().writes(1 as Weight))
- // }
+ fn set_schema_version() -> Weight {
+ (8_500_000 as Weight)
+ .saturating_add(DbWeight::get().reads(2 as Weight))
+ .saturating_add(DbWeight::get().writes(1 as Weight))
+ }
+ fn set_chain_limits() -> Weight {
+ (1_300_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(1 as Weight))
+ }
+ fn set_contract_sponsoring_rate_limit() -> Weight {
+ (3_500_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(2 as Weight))
+ }
+ fn toggle_contract_white_list() -> Weight {
+ (3_000_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(2 as Weight))
+ }
+ fn add_to_contract_white_list() -> Weight {
+ (3_000_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(2 as Weight))
+ }
+ fn remove_from_contract_white_list() -> Weight {
+ (3_200_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(2 as Weight))
+ }
+ fn set_collection_limits() -> Weight {
+ (8_900_000 as Weight)
+ .saturating_add(DbWeight::get().reads(2 as Weight))
+ .saturating_add(DbWeight::get().writes(1 as Weight))
+ }
}
pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
#![recursion_limit = "1024"]
#![cfg_attr(not(feature = "std"), no_std)]
@@ -29,10 +34,10 @@
use sp_runtime::sp_std::prelude::Vec;
use sp_runtime::{
traits::{
- DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Saturating, SignedExtension, Zero,
+ DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Saturating, SaturatedConversion, SignedExtension, Zero,
},
transaction_validity::{
- InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
+ TransactionPriority, InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
},
FixedPointOperand, FixedU128,
};
@@ -131,7 +136,7 @@
pub offchain_schema: Vec<u8>,
pub schema_version: SchemaVersion,
pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender
- pub unconfirmed_sponsor: AccountId, // Sponsor address that has not yet confirmed sponsorship
+ pub sponsor_confirmed: bool, // False if sponsor address has not yet confirmed sponsorship. True otherwise.
pub limits: CollectionLimits, // Collection private restrictions
pub variable_on_chain_schema: Vec<u8>, //
pub const_on_chain_schema: Vec<u8>, //
@@ -140,7 +145,6 @@
#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct NftItemType<AccountId> {
- pub collection: CollectionId,
pub owner: AccountId,
pub const_data: Vec<u8>,
pub variable_data: Vec<u8>,
@@ -148,45 +152,28 @@
#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-pub struct FungibleItemType<AccountId> {
- pub collection: CollectionId,
- pub owner: AccountId,
+pub struct FungibleItemType {
pub value: u128,
}
#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ReFungibleItemType<AccountId> {
- pub collection: CollectionId,
pub owner: Vec<Ownership<AccountId>>,
pub const_data: Vec<u8>,
pub variable_data: Vec<u8>,
}
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-pub struct ApprovePermissions<AccountId> {
- pub approved: AccountId,
- pub amount: u128,
-}
-
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-pub struct VestingItem<AccountId, Moment> {
- pub sender: AccountId,
- pub recipient: AccountId,
- pub collection_id: CollectionId,
- pub item_id: TokenId,
- pub amount: u64,
- pub vesting_date: Moment,
-}
-
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-pub struct BasketItem<AccountId, BlockNumber> {
- pub address: AccountId,
- pub start_block: BlockNumber,
-}
+// #[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+// pub struct VestingItem<AccountId, Moment> {
+// pub sender: AccountId,
+// pub recipient: AccountId,
+// pub collection_id: CollectionId,
+// pub item_id: TokenId,
+// pub amount: u64,
+// pub vesting_date: Moment,
+// }
#[derive(Encode, Decode, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
@@ -246,6 +233,13 @@
fn set_variable_on_chain_schema() -> Weight;
fn set_variable_meta_data() -> Weight;
fn enable_contract_sponsoring() -> Weight;
+ fn set_schema_version() -> Weight;
+ fn set_chain_limits() -> Weight;
+ fn set_contract_sponsoring_rate_limit() -> Weight;
+ fn toggle_contract_white_list() -> Weight;
+ fn add_to_contract_white_list() -> Weight;
+ fn remove_from_contract_white_list() -> Weight;
+ fn set_collection_limits() -> Weight;
}
#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
@@ -258,6 +252,7 @@
#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct CreateFungibleData {
+ pub value: u128,
}
#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
@@ -407,17 +402,17 @@
// Basic collections
pub Collection get(fn collection) config(): map hasher(identity) CollectionId => CollectionType<T::AccountId>;
pub AdminList get(fn admin_list_collection): map hasher(identity) CollectionId => Vec<T::AccountId>;
- pub WhiteList get(fn white_list): map hasher(identity) CollectionId => Vec<T::AccountId>;
+ pub WhiteList get(fn white_list): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => bool;
/// Balance owner per collection map
pub Balance get(fn balance_count): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => u128;
- /// second parameter: item id + owner account id
- pub ApprovedList get(fn approved): double_map hasher(identity) CollectionId, hasher(twox_64_concat) (TokenId, T::AccountId) => Vec<ApprovePermissions<T::AccountId>>;
+ /// second parameter: item id + owner account id + spender account id
+ pub Allowances get(fn approved): double_map hasher(identity) CollectionId, hasher(twox_64_concat) (TokenId, T::AccountId, T::AccountId) => u128;
/// Item collections
pub NftItemList get(fn nft_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => NftItemType<T::AccountId>;
- pub FungibleItemList get(fn fungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => FungibleItemType<T::AccountId>;
+ pub FungibleItemList get(fn fungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => FungibleItemType;
pub ReFungibleItemList get(fn refungible_item_id) config(): double_map hasher(identity) CollectionId, hasher(identity) TokenId => ReFungibleItemType<T::AccountId>;
/// Index list
@@ -425,7 +420,7 @@
/// Tokens transfer baskets
pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;
- pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => Vec<BasketItem<T::AccountId, T::BlockNumber>>;
+ pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => T::BlockNumber;
pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(identity) CollectionId, hasher(identity) TokenId => T::BlockNumber;
// Contract Sponsorship and Ownership
@@ -433,6 +428,8 @@
pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;
pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) (T::AccountId, T::AccountId) => T::BlockNumber;
pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;
+ pub ContractWhiteListEnabled get(fn contract_white_list_enabled): map hasher(twox_64_concat) T::AccountId => bool;
+ pub ContractWhiteList get(fn contract_white_list): double_map hasher(twox_64_concat) T::AccountId, hasher(twox_64_concat) T::AccountId => bool;
}
add_extra_genesis {
build(|config: &GenesisConfig<T>| {
@@ -441,16 +438,16 @@
<Module<T>>::init_collection(_c);
}
- for (_num, _q, _i) in &config.nft_item_id {
- <Module<T>>::init_nft_token(_i);
+ for (_num, _c, _i) in &config.nft_item_id {
+ <Module<T>>::init_nft_token(*_c, _i);
}
- for (_num, _q, _i) in &config.fungible_item_id {
- <Module<T>>::init_fungible_token(_i);
+ for (collection_id, account_id, fungible_item) in &config.fungible_item_id {
+ <Module<T>>::init_fungible_token(*collection_id, account_id, fungible_item);
}
- for (_num, _q, _i) in &config.refungible_item_id {
- <Module<T>>::init_refungible_token(_i);
+ for (_num, _c, _i) in &config.refungible_item_id {
+ <Module<T>>::init_refungible_token(*_c, _i);
}
})
}
@@ -586,7 +583,7 @@
offchain_schema: Vec::new(),
schema_version: SchemaVersion::ImageURL,
sponsor: T::AccountId::default(),
- unconfirmed_sponsor: T::AccountId::default(),
+ sponsor_confirmed: false,
variable_on_chain_schema: Vec::new(),
const_on_chain_schema: Vec::new(),
limits: CollectionLimits::default(),
@@ -617,12 +614,12 @@
Self::check_owner_permissions(collection_id, sender)?;
<AddressTokens<T>>::remove_prefix(collection_id);
- <ApprovedList<T>>::remove_prefix(collection_id);
+ <Allowances<T>>::remove_prefix(collection_id);
<Balance<T>>::remove_prefix(collection_id);
<ItemListIndex>::remove(collection_id);
<AdminList<T>>::remove(collection_id);
<Collection<T>>::remove(collection_id);
- <WhiteList<T>>::remove(collection_id);
+ <WhiteList<T>>::remove_prefix(collection_id);
<NftItemList<T>>::remove_prefix(collection_id);
<FungibleItemList<T>>::remove_prefix(collection_id);
@@ -663,20 +660,8 @@
let sender = ensure_signed(origin)?;
Self::check_owner_or_admin_permissions(collection_id, sender)?;
- let mut white_list_collection: Vec<T::AccountId>;
- if <WhiteList<T>>::contains_key(collection_id) {
- white_list_collection = <WhiteList<T>>::get(collection_id);
- if !white_list_collection.contains(&address.clone())
- {
- white_list_collection.push(address.clone());
- }
- }
- else {
- white_list_collection = Vec::new();
- white_list_collection.push(address.clone());
- }
-
- <WhiteList<T>>::insert(collection_id, white_list_collection);
+ <WhiteList<T>>::insert(collection_id, address, true);
+
Ok(())
}
@@ -698,14 +683,7 @@
let sender = ensure_signed(origin)?;
Self::check_owner_or_admin_permissions(collection_id, sender)?;
- if <WhiteList<T>>::contains_key(collection_id) {
- let mut white_list_collection = <WhiteList<T>>::get(collection_id);
- if white_list_collection.contains(&address.clone())
- {
- white_list_collection.retain(|i| *i != address.clone());
- <WhiteList<T>>::insert(collection_id, white_list_collection);
- }
- }
+ <WhiteList<T>>::remove(collection_id, address);
Ok(())
}
@@ -864,7 +842,8 @@
let mut target_collection = <Collection<T>>::get(collection_id);
ensure!(sender == target_collection.owner, Error::<T>::NoPermission);
- target_collection.unconfirmed_sponsor = new_sponsor;
+ target_collection.sponsor = new_sponsor;
+ target_collection.sponsor_confirmed = false;
<Collection<T>>::insert(collection_id, target_collection);
Ok(())
@@ -884,10 +863,9 @@
ensure!(<Collection<T>>::contains_key(collection_id), Error::<T>::CollectionNotFound);
let mut target_collection = <Collection<T>>::get(collection_id);
- ensure!(sender == target_collection.unconfirmed_sponsor, Error::<T>::ConfirmUnsetSponsorFail);
+ ensure!(sender == target_collection.sponsor, Error::<T>::ConfirmUnsetSponsorFail);
- target_collection.sponsor = target_collection.unconfirmed_sponsor;
- target_collection.unconfirmed_sponsor = T::AccountId::default();
+ target_collection.sponsor_confirmed = true;
<Collection<T>>::insert(collection_id, target_collection);
Ok(())
@@ -912,6 +890,7 @@
ensure!(sender == target_collection.owner, Error::<T>::NoPermission);
target_collection.sponsor = T::AccountId::default();
+ target_collection.sponsor_confirmed = false;
<Collection<T>>::insert(collection_id, target_collection);
Ok(())
@@ -1012,7 +991,7 @@
///
/// * item_id: ID of NFT to burn.
#[weight = T::WeightInfo::burn_item()]
- pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId) -> DispatchResult {
+ pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {
let sender = ensure_signed(origin)?;
Self::collection_exists(collection_id)?;
@@ -1030,7 +1009,7 @@
match target_collection.mode
{
CollectionMode::NFT => Self::burn_nft_item(collection_id, item_id)?,
- CollectionMode::Fungible(_) => Self::burn_fungible_item(collection_id, item_id)?,
+ CollectionMode::Fungible(_) => Self::burn_fungible_item(&sender, collection_id, value)?,
CollectionMode::ReFungible(_) => Self::burn_refungible_item(collection_id, item_id, sender.clone())?,
_ => ()
};
@@ -1086,7 +1065,7 @@
match target_collection.mode
{
CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient)?,
- CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, item_id, value, sender.clone(), recipient)?,
+ CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, value, &sender, &recipient)?,
CollectionMode::ReFungible(_) => Self::transfer_refungible(collection_id, item_id, value, sender.clone(), recipient)?,
_ => ()
};
@@ -1110,7 +1089,7 @@
///
/// * item_id: ID of the item.
#[weight = T::WeightInfo::approve()]
- pub fn approve(origin, approved: T::AccountId, collection_id: CollectionId, item_id: TokenId) -> DispatchResult {
+ pub fn approve(origin, spender: T::AccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {
let sender = ensure_signed(origin)?;
@@ -1122,28 +1101,15 @@
if target_collection.access == AccessMode::WhiteList {
Self::check_white_list(collection_id, &sender)?;
- Self::check_white_list(collection_id, &approved)?;
+ Self::check_white_list(collection_id, &spender)?;
}
- // amount param stub
- let amount = 100000000;
-
- let list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, sender.clone()));
- if list_exists {
-
- let mut list = <ApprovedList<T>>::get(collection_id, (item_id, sender.clone()));
- let item_contains = list.iter().any(|i| i.approved == approved);
-
- if !item_contains {
- list.push(ApprovePermissions { approved: approved.clone(), amount: amount });
- <ApprovedList<T>>::insert(collection_id, (item_id, sender.clone()), list);
- }
- } else {
-
- let mut list = Vec::new();
- list.push(ApprovePermissions { approved: approved.clone(), amount: amount });
- <ApprovedList<T>>::insert(collection_id, (item_id, sender.clone()), list);
+ let allowance_exists = <Allowances<T>>::contains_key(collection_id, (item_id, &sender, &spender));
+ let mut allowance: u128 = amount;
+ if allowance_exists {
+ allowance += <Allowances<T>>::get(collection_id, (item_id, &sender, &spender));
}
+ <Allowances<T>>::insert(collection_id, (item_id, sender.clone(), spender.clone()), allowance);
Ok(())
}
@@ -1173,15 +1139,12 @@
let sender = ensure_signed(origin)?;
let mut appoved_transfer = false;
- // Check approve
- if <ApprovedList<T>>::contains_key(collection_id, (item_id, from.clone())) {
- let list_itm = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()));
- let opt_item = list_itm.iter().find(|i| i.approved == sender.clone());
- if opt_item.is_some()
- {
- appoved_transfer = true;
- ensure!(opt_item.unwrap().amount >= value, Error::<T>::TokenValueNotEnough);
- }
+ // Check approval
+ let mut approval: u128 = 0;
+ if <Allowances<T>>::contains_key(collection_id, (item_id, &from, &recipient)) {
+ approval = <Allowances<T>>::get(collection_id, (item_id, &from, &recipient));
+ ensure!(approval >= value, Error::<T>::TokenValueNotEnough);
+ appoved_transfer = true;
}
let target_collection = <Collection<T>>::get(collection_id);
@@ -1191,23 +1154,25 @@
// Transfer permissions check
ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
- Error::<T>::NoPermission);
+ Error::<T>::NoPermission);
if target_collection.access == AccessMode::WhiteList {
Self::check_white_list(collection_id, &sender)?;
Self::check_white_list(collection_id, &recipient)?;
}
- // remove approve
- let approve_list: Vec<ApprovePermissions<T::AccountId>> = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()))
- .into_iter().filter(|i| i.approved != sender.clone()).collect();
- <ApprovedList<T>>::insert(collection_id, (item_id, from.clone()), approve_list);
+ // Reduce approval by transferred amount or remove if remaining approval drops to 0
+ if approval - value > 0 {
+ <Allowances<T>>::insert(collection_id, (item_id, &from, &recipient), approval - value);
+ }
+ else {
+ <Allowances<T>>::remove(collection_id, (item_id, &from, &recipient));
+ }
-
match target_collection.mode
{
CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, from, recipient)?,
- CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, item_id, value, from.clone(), recipient)?,
+ CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, value, &from, &recipient)?,
CollectionMode::ReFungible(_) => Self::transfer_refungible(collection_id, item_id, value, from.clone(), recipient)?,
_ => ()
};
@@ -1288,7 +1253,7 @@
/// * collection_id.
///
/// * schema: SchemaVersion: enum
- #[weight = 0]
+ #[weight = T::WeightInfo::set_schema_version()]
pub fn set_schema_version(
origin,
collection_id: CollectionId,
@@ -1388,12 +1353,15 @@
}
// Sudo permissions function
- #[weight = 0]
+ #[weight = T::WeightInfo::set_chain_limits()]
pub fn set_chain_limits(
origin,
limits: ChainLimits
) -> DispatchResult {
+
+ #[cfg(not(feature = "runtime-benchmarks"))]
ensure_root(origin)?;
+
<ChainLimit>::put(limits);
Ok(())
}
@@ -1421,12 +1389,7 @@
#[cfg(feature = "runtime-benchmarks")]
<ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
- let mut is_owner = false;
- if <ContractOwner<T>>::contains_key(contract_address.clone()) {
- let owner = <ContractOwner<T>>::get(&contract_address);
- is_owner = sender == owner;
- }
- ensure!(is_owner, Error::<T>::NoPermission);
+ Self::ensure_contract_owned(sender, &contract_address)?;
<ContractSelfSponsoring<T>>::insert(contract_address, enable);
Ok(())
@@ -1449,25 +1412,104 @@
/// -`contract_address`: Address of the contract to sponsor
/// -`rate_limit`: Number of blocks to wait until the next sponsored transaction is allowed
///
- #[weight = 0]
+ #[weight = T::WeightInfo::set_contract_sponsoring_rate_limit()]
pub fn set_contract_sponsoring_rate_limit(
origin,
contract_address: T::AccountId,
rate_limit: T::BlockNumber
) -> DispatchResult {
let sender = ensure_signed(origin)?;
- let mut is_owner = false;
- if <ContractOwner<T>>::contains_key(contract_address.clone()) {
- let owner = <ContractOwner<T>>::get(&contract_address);
- is_owner = sender == owner;
- }
- ensure!(is_owner, Error::<T>::NoPermission);
+ #[cfg(feature = "runtime-benchmarks")]
+ <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
+
+ Self::ensure_contract_owned(sender, &contract_address)?;
<ContractSponsoringRateLimit<T>>::insert(contract_address, rate_limit);
Ok(())
}
- #[weight = 0]
+ /// Enable the white list for a contract. Only addresses added to the white list with addToContractWhiteList will be able to call this smart contract.
+ ///
+ /// # Permissions
+ ///
+ /// * Address that deployed smart contract.
+ ///
+ /// # Arguments
+ ///
+ /// -`contract_address`: Address of the contract.
+ ///
+ /// - `enable`: .
+ #[weight = T::WeightInfo::toggle_contract_white_list()]
+ pub fn toggle_contract_white_list(
+ origin,
+ contract_address: T::AccountId,
+ enable: bool
+ ) -> DispatchResult {
+ let sender = ensure_signed(origin)?;
+
+ #[cfg(feature = "runtime-benchmarks")]
+ <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
+
+ Self::ensure_contract_owned(sender, &contract_address)?;
+ <ContractWhiteListEnabled<T>>::insert(contract_address, enable);
+ Ok(())
+ }
+
+ /// Add an address to smart contract white list.
+ ///
+ /// # Permissions
+ ///
+ /// * Address that deployed smart contract.
+ ///
+ /// # Arguments
+ ///
+ /// -`contract_address`: Address of the contract.
+ ///
+ /// -`account_address`: Address to add.
+ #[weight = T::WeightInfo::add_to_contract_white_list()]
+ pub fn add_to_contract_white_list(
+ origin,
+ contract_address: T::AccountId,
+ account_address: T::AccountId
+ ) -> DispatchResult {
+ let sender = ensure_signed(origin)?;
+
+ #[cfg(feature = "runtime-benchmarks")]
+ <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
+
+ Self::ensure_contract_owned(sender, &contract_address)?;
+ <ContractWhiteList<T>>::insert(contract_address, account_address, true);
+ Ok(())
+ }
+
+ /// Remove an address from smart contract white list.
+ ///
+ /// # Permissions
+ ///
+ /// * Address that deployed smart contract.
+ ///
+ /// # Arguments
+ ///
+ /// -`contract_address`: Address of the contract.
+ ///
+ /// -`account_address`: Address to remove.
+ #[weight = T::WeightInfo::remove_from_contract_white_list()]
+ pub fn remove_from_contract_white_list(
+ origin,
+ contract_address: T::AccountId,
+ account_address: T::AccountId
+ ) -> DispatchResult {
+ let sender = ensure_signed(origin)?;
+
+ #[cfg(feature = "runtime-benchmarks")]
+ <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
+
+ Self::ensure_contract_owned(sender, &contract_address)?;
+ <ContractWhiteList<T>>::remove(contract_address, account_address);
+ Ok(())
+ }
+
+ #[weight = T::WeightInfo::set_collection_limits()]
pub fn set_collection_limits(
origin,
collection_id: u32,
@@ -1564,22 +1606,15 @@
{
CreateItemData::NFT(data) => {
let item = NftItemType {
- collection: collection_id,
owner,
const_data: data.const_data,
variable_data: data.variable_data
};
- Self::add_nft_item(item)?;
+ Self::add_nft_item(collection_id, item)?;
},
- CreateItemData::Fungible(_) => {
- let item = FungibleItemType {
- collection: collection_id,
- owner,
- value: (10 as u128).pow(collection.decimal_points as u32)
- };
-
- Self::add_fungible_item(item)?;
+ CreateItemData::Fungible(data) => {
+ Self::add_fungible_item(collection_id, &owner, data.value)?;
},
CreateItemData::ReFungible(data) => {
let mut owner_list = Vec::new();
@@ -1587,13 +1622,12 @@
owner_list.push(Ownership {owner: owner.clone(), fraction: value});
let item = ReFungibleItemType {
- collection: collection_id,
owner: owner_list,
const_data: data.const_data,
variable_data: data.variable_data
};
- Self::add_refungible_item(item)?;
+ Self::add_refungible_item(collection_id, item)?;
}
};
@@ -1603,33 +1637,31 @@
Ok(())
}
- fn add_fungible_item(item: FungibleItemType<T::AccountId>) -> DispatchResult {
- let current_index = <ItemListIndex>::get(item.collection)
- .checked_add(1)
- .ok_or(Error::<T>::NumOverflow)?;
- let itemcopy = item.clone();
- let owner = item.owner.clone();
+ fn add_fungible_item(collection_id: CollectionId, owner: &T::AccountId, value: u128) -> DispatchResult {
- Self::add_token_index(item.collection, current_index, owner.clone())?;
+ // Does new owner already have an account?
+ let mut balance: u128 = 0;
+ if <FungibleItemList<T>>::contains_key(collection_id, owner) {
+ balance = <FungibleItemList<T>>::get(collection_id, owner).value;
+ }
- <ItemListIndex>::insert(item.collection, current_index);
- <FungibleItemList<T>>::insert(item.collection, current_index, itemcopy);
+ // Mint
+ let item = FungibleItemType {
+ value: balance + value
+ };
+ <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), item);
- // Add current block
- let v: Vec<BasketItem<T::AccountId, T::BlockNumber>> = Vec::new();
- <FungibleTransferBasket<T>>::insert(item.collection, current_index, v);
-
// Update balance
- let new_balance = <Balance<T>>::get(item.collection, owner.clone())
- .checked_add(item.value)
+ let new_balance = <Balance<T>>::get(collection_id, owner)
+ .checked_add(value)
.ok_or(Error::<T>::NumOverflow)?;
- <Balance<T>>::insert(item.collection, owner.clone(), new_balance);
+ <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);
Ok(())
}
- fn add_refungible_item(item: ReFungibleItemType<T::AccountId>) -> DispatchResult {
- let current_index = <ItemListIndex>::get(item.collection)
+ fn add_refungible_item(collection_id: CollectionId, item: ReFungibleItemType<T::AccountId>) -> DispatchResult {
+ let current_index = <ItemListIndex>::get(collection_id)
.checked_add(1)
.ok_or(Error::<T>::NumOverflow)?;
let itemcopy = item.clone();
@@ -1637,40 +1669,31 @@
let value = item.owner.first().unwrap().fraction;
let owner = item.owner.first().unwrap().owner.clone();
- Self::add_token_index(item.collection, current_index, owner.clone())?;
+ Self::add_token_index(collection_id, current_index, owner.clone())?;
- <ItemListIndex>::insert(item.collection, current_index);
- <ReFungibleItemList<T>>::insert(item.collection, current_index, itemcopy);
-
- // Add current block
- let block_number: T::BlockNumber = 0.into();
- <ReFungibleTransferBasket<T>>::insert(item.collection, current_index, block_number);
+ <ItemListIndex>::insert(collection_id, current_index);
+ <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);
// Update balance
- let new_balance = <Balance<T>>::get(item.collection, owner.clone())
+ let new_balance = <Balance<T>>::get(collection_id, owner.clone())
.checked_add(value)
.ok_or(Error::<T>::NumOverflow)?;
- <Balance<T>>::insert(item.collection, owner.clone(), new_balance);
+ <Balance<T>>::insert(collection_id, owner.clone(), new_balance);
Ok(())
}
- fn add_nft_item(item: NftItemType<T::AccountId>) -> DispatchResult {
- let current_index = <ItemListIndex>::get(item.collection)
+ fn add_nft_item(collection_id: CollectionId, item: NftItemType<T::AccountId>) -> DispatchResult {
+ let current_index = <ItemListIndex>::get(collection_id)
.checked_add(1)
.ok_or(Error::<T>::NumOverflow)?;
let item_owner = item.owner.clone();
- let collection_id = item.collection.clone();
Self::add_token_index(collection_id, current_index, item.owner.clone())?;
<ItemListIndex>::insert(collection_id, current_index);
<NftItemList<T>>::insert(collection_id, current_index, item);
- // Add current block
- let block_number: T::BlockNumber = 0.into();
- <NftTransferBasket<T>>::insert(collection_id, current_index, block_number);
-
// Update balance
let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())
.checked_add(1)
@@ -1697,9 +1720,6 @@
.next()
.unwrap();
Self::remove_token_index(collection_id, item_id, owner.clone())?;
-
- // remove approve list
- <ApprovedList<T>>::remove(collection_id, (item_id, owner.clone()));
// update balance
let new_balance = <Balance<T>>::get(collection_id, item.owner.clone())
@@ -1719,9 +1739,6 @@
);
let item = <NftItemList<T>>::get(collection_id, item_id);
Self::remove_token_index(collection_id, item_id, item.owner.clone())?;
-
- // remove approve list
- <ApprovedList<T>>::remove(collection_id, (item_id, item.owner.clone()));
// update balance
let new_balance = <Balance<T>>::get(collection_id, item.owner.clone())
@@ -1733,24 +1750,27 @@
Ok(())
}
- fn burn_fungible_item(collection_id: CollectionId, item_id: TokenId) -> DispatchResult {
+ fn burn_fungible_item(owner: &T::AccountId, collection_id: CollectionId, value: u128) -> DispatchResult {
ensure!(
- <FungibleItemList<T>>::contains_key(collection_id, item_id),
+ <FungibleItemList<T>>::contains_key(collection_id, owner),
Error::<T>::TokenNotFound
);
- let item = <FungibleItemList<T>>::get(collection_id, item_id);
- Self::remove_token_index(collection_id, item_id, item.owner.clone())?;
-
- // remove approve list
- <ApprovedList<T>>::remove(collection_id, (item_id, item.owner.clone()));
+ let mut balance = <FungibleItemList<T>>::get(collection_id, owner);
+ ensure!(balance.value >= value, Error::<T>::TokenValueNotEnough);
// update balance
- let new_balance = <Balance<T>>::get(collection_id, item.owner.clone())
- .checked_sub(item.value)
+ let new_balance = <Balance<T>>::get(collection_id, owner)
+ .checked_sub(value)
.ok_or(Error::<T>::NumOverflow)?;
- <Balance<T>>::insert(collection_id, item.owner.clone(), new_balance);
+ <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);
- <FungibleItemList<T>>::remove(collection_id, item_id);
+ if balance.value - value > 0 {
+ balance.value -= value;
+ <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), balance);
+ }
+ else {
+ <FungibleItemList<T>>::remove(collection_id, owner);
+ }
Ok(())
}
@@ -1811,7 +1831,7 @@
<NftItemList<T>>::get(collection_id, item_id).owner == subject
}
CollectionMode::Fungible(_) => {
- <FungibleItemList<T>>::get(collection_id, item_id).owner == subject
+ <FungibleItemList<T>>::contains_key(collection_id, &subject)
}
CollectionMode::ReFungible(_) => {
<ReFungibleItemList<T>>::get(collection_id, item_id)
@@ -1825,95 +1845,38 @@
fn check_white_list(collection_id: CollectionId, address: &T::AccountId) -> DispatchResult {
let mes = Error::<T>::AddresNotInWhiteList;
- ensure!(<WhiteList<T>>::contains_key(collection_id), mes);
- let wl = <WhiteList<T>>::get(collection_id);
- ensure!(wl.contains(address), mes);
+ ensure!(<WhiteList<T>>::contains_key(collection_id, address), mes);
Ok(())
}
fn transfer_fungible(
collection_id: CollectionId,
- item_id: TokenId,
value: u128,
- owner: T::AccountId,
- new_owner: T::AccountId,
+ owner: &T::AccountId,
+ recipient: &T::AccountId,
) -> DispatchResult {
ensure!(
- <FungibleItemList<T>>::contains_key(collection_id, item_id),
+ <FungibleItemList<T>>::contains_key(collection_id, owner),
Error::<T>::TokenNotFound
);
- let full_item = <FungibleItemList<T>>::get(collection_id, item_id);
- let amount = full_item.value;
+ let mut balance = <FungibleItemList<T>>::get(collection_id, owner);
+ ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);
- ensure!(amount >= value, Error::<T>::TokenValueTooLow);
+ // Send balance to recipient (updates balanceOf of recipient)
+ Self::add_fungible_item(collection_id, recipient, value)?;
- // update balance
- let balance_old_owner = <Balance<T>>::get(collection_id, owner.clone())
- .checked_sub(value)
- .ok_or(Error::<T>::NumOverflow)?;
- <Balance<T>>::insert(collection_id, owner.clone(), balance_old_owner);
+ // update balanceOf of sender
+ <Balance<T>>::insert(collection_id, (*owner).clone(), balance.value - value);
- let mut new_owner_account_id = 0;
- let new_owner_items = <AddressTokens<T>>::get(collection_id, new_owner.clone());
- if new_owner_items.len() > 0 {
- new_owner_account_id = new_owner_items[0];
+ // Reduce or remove sender
+ if balance.value == value {
+ <FungibleItemList<T>>::remove(collection_id, owner);
}
-
- // transfer
- if amount == value && new_owner_account_id == 0 {
- // change owner
- // new owner do not have account
- let mut new_full_item = full_item.clone();
- new_full_item.owner = new_owner.clone();
- <FungibleItemList<T>>::insert(collection_id, item_id, new_full_item);
-
- // update balance
- let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.clone())
- .checked_add(value)
- .ok_or(Error::<T>::NumOverflow)?;
- <Balance<T>>::insert(collection_id, new_owner.clone(), balance_new_owner);
-
- // update index collection
- Self::move_token_index(collection_id, item_id, owner.clone(), new_owner.clone())?;
- } else {
- let mut new_full_item = full_item.clone();
- new_full_item.value -= value;
-
- // separate amount
- if new_owner_account_id > 0 {
- // new owner has account
- let mut item = <FungibleItemList<T>>::get(collection_id, new_owner_account_id);
- item.value += value;
-
- // update balance
- let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.clone())
- .checked_add(value)
- .ok_or(Error::<T>::NumOverflow)?;
- <Balance<T>>::insert(collection_id, new_owner.clone(), balance_new_owner);
-
- <FungibleItemList<T>>::insert(collection_id, new_owner_account_id, item);
- } else {
- // new owner do not have account
- let item = FungibleItemType {
- collection: collection_id,
- owner: new_owner.clone(),
- value
- };
-
- Self::add_fungible_item(item)?;
- }
-
- if amount == value {
- Self::remove_token_index(collection_id, item_id, full_item.owner.clone())?;
-
- // remove approve list
- <ApprovedList<T>>::remove(collection_id, (item_id, full_item.owner.clone()));
- <FungibleItemList<T>>::remove(collection_id, item_id);
- }
-
- <FungibleItemList<T>>::insert(collection_id, item_id, new_full_item);
+ else {
+ balance.value -= value;
+ <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), balance);
}
Ok(())
@@ -1948,10 +1911,10 @@
.ok_or(Error::<T>::NumOverflow)?;
<Balance<T>>::insert(collection_id, item.owner.clone(), balance_old_owner);
- let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.clone())
+ let balancenew_owner = <Balance<T>>::get(collection_id, new_owner.clone())
.checked_add(value)
.ok_or(Error::<T>::NumOverflow)?;
- <Balance<T>>::insert(collection_id, new_owner.clone(), balance_new_owner);
+ <Balance<T>>::insert(collection_id, new_owner.clone(), balancenew_owner);
let old_owner = item.owner.clone();
let new_owner_has_account = full_item.owner.iter().any(|i| i.owner == new_owner);
@@ -2028,10 +1991,10 @@
.ok_or(Error::<T>::NumOverflow)?;
<Balance<T>>::insert(collection_id, item.owner.clone(), balance_old_owner);
- let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.clone())
+ let balancenew_owner = <Balance<T>>::get(collection_id, new_owner.clone())
.checked_add(1)
.ok_or(Error::<T>::NumOverflow)?;
- <Balance<T>>::insert(collection_id, new_owner.clone(), balance_new_owner);
+ <Balance<T>>::insert(collection_id, new_owner.clone(), balancenew_owner);
// change owner
let old_owner = item.owner.clone();
@@ -2041,8 +2004,6 @@
// update index collection
Self::move_token_index(collection_id, item_id, old_owner.clone(), new_owner.clone())?;
- // reset approved list
- <ApprovedList<T>>::remove(collection_id, (item_id, old_owner));
Ok(())
}
@@ -2054,7 +2015,6 @@
match mode {
CollectionMode::NFT => ensure!(<NftItemList<T>>::contains_key(collection_id, item_id), Error::<T>::TokenNotFound),
CollectionMode::ReFungible(_) => ensure!(<ReFungibleItemList<T>>::contains_key(collection_id, item_id), Error::<T>::TokenNotFound),
- CollectionMode::Fungible(_) => ensure!(<FungibleItemList<T>>::contains_key(collection_id, item_id), Error::<T>::TokenNotFound),
_ => ()
};
@@ -2116,13 +2076,12 @@
CreatedCollectionCount::put(next_id);
}
- fn init_nft_token(item: &NftItemType<T::AccountId>) {
- let current_index = <ItemListIndex>::get(item.collection)
+ fn init_nft_token(collection_id: CollectionId, item: &NftItemType<T::AccountId>) {
+ let current_index = <ItemListIndex>::get(collection_id)
.checked_add(1)
.unwrap();
let item_owner = item.owner.clone();
- let collection_id = item.collection.clone();
Self::add_token_index(collection_id, current_index, item.owner.clone()).unwrap();
<ItemListIndex>::insert(collection_id, current_index);
@@ -2134,40 +2093,39 @@
<Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);
}
- fn init_fungible_token(item: &FungibleItemType<T::AccountId>) {
- let current_index = <ItemListIndex>::get(item.collection)
+ fn init_fungible_token(collection_id: CollectionId, owner: &T::AccountId, item: &FungibleItemType) {
+ let current_index = <ItemListIndex>::get(collection_id)
.checked_add(1)
.unwrap();
- let owner = item.owner.clone();
- Self::add_token_index(item.collection, current_index, owner.clone()).unwrap();
+ Self::add_token_index(collection_id, current_index, (*owner).clone()).unwrap();
- <ItemListIndex>::insert(item.collection, current_index);
+ <ItemListIndex>::insert(collection_id, current_index);
// Update balance
- let new_balance = <Balance<T>>::get(item.collection, owner.clone())
+ let new_balance = <Balance<T>>::get(collection_id, owner)
.checked_add(item.value)
.unwrap();
- <Balance<T>>::insert(item.collection, owner.clone(), new_balance);
+ <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);
}
- fn init_refungible_token(item: &ReFungibleItemType<T::AccountId>) {
- let current_index = <ItemListIndex>::get(item.collection)
+ fn init_refungible_token(collection_id: CollectionId, item: &ReFungibleItemType<T::AccountId>) {
+ let current_index = <ItemListIndex>::get(collection_id)
.checked_add(1)
.unwrap();
let value = item.owner.first().unwrap().fraction;
let owner = item.owner.first().unwrap().owner.clone();
- Self::add_token_index(item.collection, current_index, owner.clone()).unwrap();
+ Self::add_token_index(collection_id, current_index, owner.clone()).unwrap();
- <ItemListIndex>::insert(item.collection, current_index);
+ <ItemListIndex>::insert(collection_id, current_index);
// Update balance
- let new_balance = <Balance<T>>::get(item.collection, owner.clone())
+ let new_balance = <Balance<T>>::get(collection_id, owner.clone())
.checked_add(value)
.unwrap();
- <Balance<T>>::insert(item.collection, owner.clone(), new_balance);
+ <Balance<T>>::insert(collection_id, owner.clone(), new_balance);
}
fn add_token_index(collection_id: CollectionId, item_index: TokenId, owner: T::AccountId) -> DispatchResult {
@@ -2245,6 +2203,17 @@
Ok(())
}
+
+ fn ensure_contract_owned(account: T::AccountId, contract: &T::AccountId) -> DispatchResult {
+ if <ContractOwner<T>>::contains_key(contract.clone()) {
+ let owner = <ContractOwner<T>>::get(contract);
+ ensure!(account == owner, Error::<T>::NoPermission);
+ } else {
+ fail!(Error::<T>::NoPermission);
+ }
+
+ Ok(())
+ }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2302,6 +2271,13 @@
<transaction_payment::Module<T>>::compute_fee(len as u32, info, tip)
}
+ fn get_priority(len: usize, info: &DispatchInfoOf<T::Call>, final_fee: BalanceOf<T>) -> TransactionPriority {
+ let weight_saturation = T::MaximumBlockWeight::get() / info.weight.max(1);
+ let len_saturation = T::MaximumBlockLength::get() as u64 / (len as u64).max(1);
+ let coefficient: BalanceOf<T> = weight_saturation.min(len_saturation).saturated_into::<BalanceOf<T>>();
+ final_fee.saturating_mul(coefficient).saturated_into::<TransactionPriority>()
+ }
+
fn withdraw_fee(
&self,
who: &T::AccountId,
@@ -2320,99 +2296,111 @@
// };
let fee = Self::traditional_fee(len, info, tip);
+ // Only mess with balances if fee is not zero.
+ if fee.is_zero() {
+ return Ok((fee, None));
+ }
+
// Determine who is paying transaction fee based on ecnomic model
// Parse call to extract collection ID and access collection sponsor
let mut sponsor: T::AccountId = match IsSubType::<Call<T>>::is_sub_type(call) {
Some(Call::create_item(collection_id, _owner, _properties)) => {
// check free create limit
- if <Collection<T>>::get(collection_id).limits.sponsored_data_size >= (_properties.len() as u32)
+ if (<Collection<T>>::get(collection_id).limits.sponsored_data_size >= (_properties.len() as u32)) &&
+ (<Collection<T>>::get(collection_id).sponsor_confirmed)
{
<Collection<T>>::get(collection_id).sponsor
} else {
T::AccountId::default()
}
}
- Some(Call::transfer(_new_owner, collection_id, _item_id, _value)) => {
+ Some(Call::transfer(_new_owner, collection_id, item_id, _value)) => {
- let _collection_limits = <Collection<T>>::get(collection_id).limits;
- let _collection_mode = <Collection<T>>::get(collection_id).mode;
+ let mut sponsor_transfer = false;
+ if <Collection<T>>::get(collection_id).sponsor_confirmed {
- // sponsor timeout
- let sponsor_transfer = match _collection_mode {
- CollectionMode::NFT => {
+ let collection_limits = <Collection<T>>::get(collection_id).limits;
+ let collection_mode = <Collection<T>>::get(collection_id).mode;
+
+ // sponsor timeout
+ let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
+ sponsor_transfer = match collection_mode {
+ CollectionMode::NFT => {
+
+ // get correct limit
+ let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
+ collection_limits.sponsor_transfer_timeout
+ } else {
+ ChainLimit::get().nft_sponsor_transfer_timeout
+ };
+
+ let mut sponsored = true;
+ if <NftTransferBasket<T>>::contains_key(collection_id, item_id) {
+ let last_tx_block = <NftTransferBasket<T>>::get(collection_id, item_id);
+ let limit_time = last_tx_block + limit.into();
+ if block_number <= limit_time {
+ sponsored = false;
+ }
+ }
+ if sponsored {
+ <NftTransferBasket<T>>::insert(collection_id, item_id, block_number);
+ }
- // get correct limit
- let limit: u32 = if _collection_limits.sponsor_transfer_timeout > 0 {
- _collection_limits.sponsor_transfer_timeout
- } else {
- ChainLimit::get().nft_sponsor_transfer_timeout
- };
-
- let basket = <NftTransferBasket<T>>::get(collection_id, _item_id);
- let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
- let limit_time = basket + limit.into();
- if block_number >= limit_time {
- <NftTransferBasket<T>>::insert(collection_id, _item_id, block_number);
- true
+ sponsored
}
- else {
- false
- }
- }
- CollectionMode::Fungible(_) => {
-
- // get correct limit
- let limit: u32 = if _collection_limits.sponsor_transfer_timeout > 0 {
- _collection_limits.sponsor_transfer_timeout
- } else {
- ChainLimit::get().fungible_sponsor_transfer_timeout
- };
-
- let mut basket = <FungibleTransferBasket<T>>::get(collection_id, _item_id);
- let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
- if basket.iter().any(|i| i.address == _new_owner.clone())
- {
- let item = basket.iter_mut().find(|i| i.address == _new_owner.clone()).unwrap().clone();
- let limit_time = item.start_block + limit.into();
- if block_number >= limit_time {
- basket.retain(|x| x.address == item.address);
- basket.push(BasketItem { start_block: block_number, address: _new_owner.clone() });
- <FungibleTransferBasket<T>>::insert(collection_id, _item_id, basket);
- true
+ CollectionMode::Fungible(_) => {
+
+ // get correct limit
+ let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
+ collection_limits.sponsor_transfer_timeout
+ } else {
+ ChainLimit::get().fungible_sponsor_transfer_timeout
+ };
+
+ let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
+ let mut sponsored = true;
+ if <FungibleTransferBasket<T>>::contains_key(collection_id, who) {
+ let last_tx_block = <FungibleTransferBasket<T>>::get(collection_id, who);
+ let limit_time = last_tx_block + limit.into();
+ if block_number <= limit_time {
+ sponsored = false;
+ }
}
- else {
- false
+ if sponsored {
+ <FungibleTransferBasket<T>>::insert(collection_id, who, block_number);
}
+
+ sponsored
}
- else {
- basket.push(BasketItem { start_block: block_number, address: _new_owner.clone()});
- true
- }
- }
- CollectionMode::ReFungible(_) => {
-
- // get correct limit
- let limit: u32 = if _collection_limits.sponsor_transfer_timeout > 0 {
- _collection_limits.sponsor_transfer_timeout
- } else {
- ChainLimit::get().refungible_sponsor_transfer_timeout
- };
+ CollectionMode::ReFungible(_) => {
+
+ // get correct limit
+ let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
+ collection_limits.sponsor_transfer_timeout
+ } else {
+ ChainLimit::get().refungible_sponsor_transfer_timeout
+ };
+
+ let mut sponsored = true;
+ if <ReFungibleTransferBasket<T>>::contains_key(collection_id, item_id) {
+ let last_tx_block = <ReFungibleTransferBasket<T>>::get(collection_id, item_id);
+ let limit_time = last_tx_block + limit.into();
+ if block_number <= limit_time {
+ sponsored = false;
+ }
+ }
+ if sponsored {
+ <ReFungibleTransferBasket<T>>::insert(collection_id, item_id, block_number);
+ }
- let basket = <ReFungibleTransferBasket<T>>::get(collection_id, _item_id);
- let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
- let limit_time = basket + limit.into();
- if block_number >= limit_time {
- <ReFungibleTransferBasket<T>>::insert(collection_id, _item_id, block_number);
- true
- } else {
- false
+ sponsored
}
- }
- _ => {
- false
- },
- };
+ _ => {
+ false
+ },
+ };
+ }
if !sponsor_transfer {
T::AccountId::default()
@@ -2445,6 +2433,16 @@
let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());
+ let owned_contract = <ContractOwner<T>>::contains_key(called_contract.clone())
+ && <ContractOwner<T>>::get(called_contract.clone()) == *who;
+ let white_list_enabled = <ContractWhiteListEnabled<T>>::contains_key(called_contract.clone()) && <ContractWhiteListEnabled<T>>::get(called_contract.clone());
+
+ if !owned_contract && white_list_enabled {
+ if !<ContractWhiteList<T>>::contains_key(called_contract.clone(), who) {
+ return Err(InvalidTransaction::Call.into());
+ }
+ }
+
let mut sponsor_transfer = false;
if <ContractSponsoringRateLimit<T>>::contains_key(called_contract.clone()) {
let last_tx_block = <ContractSponsorBasket<T>>::get((&called_contract, &who));
@@ -2481,11 +2479,6 @@
who_pays_fee = who.clone();
}
- // Only mess with balances if fee is not zero.
- if fee.is_zero() {
- return Ok((fee, None));
- }
-
match <T as transaction_payment::Trait>::Currency::withdraw(
&who_pays_fee,
fee,
@@ -2525,12 +2518,16 @@
fn validate(
&self,
- _who: &Self::AccountId,
- _call: &Self::Call,
- _info: &DispatchInfoOf<Self::Call>,
- _len: usize,
+ who: &Self::AccountId,
+ call: &Self::Call,
+ info: &DispatchInfoOf<Self::Call>,
+ len: usize,
) -> TransactionValidity {
- Ok(ValidTransaction::default())
+ let (fee, _) = self.withdraw_fee(who, call, info, len)?;
+ Ok(ValidTransaction {
+ priority: Self::get_priority(len, info, fee),
+ ..Default::default()
+ })
}
fn pre_dispatch(
pallets/nft/src/tests.rsdiffbeforeafterboth1// Tests to be written here2use super::*;3use crate::mock::*;4use crate::{AccessMode, ApprovePermissions, CollectionMode,5 Ownership, ChainLimits, CreateItemData, CreateNftData, CreateFungibleData, CreateReFungibleData,6 CollectionId, TokenId, MAX_DECIMAL_POINTS};7use frame_support::{assert_noop, assert_ok};8use frame_system::{ RawOrigin };910fn default_collection_numbers_limit() -> u32 {11 1012}1314fn default_limits() {15 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 16 collection_numbers_limit: default_collection_numbers_limit(),17 account_token_ownership_limit: 10,18 collections_admins_limit: 5,19 custom_data_limit: 2048,20 nft_sponsor_transfer_timeout: 15,21 fungible_sponsor_transfer_timeout: 15,22 refungible_sponsor_transfer_timeout: 15, 23 }));24}2526fn default_nft_data() -> CreateNftData {27 CreateNftData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] }28}2930fn default_fungible_data () -> CreateFungibleData {31 CreateFungibleData { }32}3334fn default_re_fungible_data () -> CreateReFungibleData {35 CreateReFungibleData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] }36}3738fn create_test_collection_for_owner(mode: &CollectionMode, owner: u64, id: CollectionId) -> CollectionId {39 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();40 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();41 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();4243 let origin1 = Origin::signed(owner);44 assert_ok!(TemplateModule::create_collection(45 origin1.clone(),46 col_name1.clone(),47 col_desc1.clone(),48 token_prefix1.clone(),49 mode.clone()50 ));5152 let saved_col_name: Vec<u16> = "Test1\0\0".encode_utf16().collect::<Vec<u16>>();53 let saved_description: Vec<u16> = "TestDescription1\0\0".encode_utf16().collect::<Vec<u16>>();54 let saved_prefix: Vec<u8> = b"token_prefix1\0\0".to_vec();55 assert_eq!(TemplateModule::collection(id).owner, owner);56 assert_eq!(TemplateModule::collection(id).name, saved_col_name);57 assert_eq!(TemplateModule::collection(id).mode, *mode);58 assert_eq!(TemplateModule::collection(id).description, saved_description);59 assert_eq!(TemplateModule::collection(id).token_prefix, saved_prefix);60 id61}6263fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {64 create_test_collection_for_owner(&mode, 1, id)65}6667fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {68 let origin1 = Origin::signed(1);69 assert_ok!(TemplateModule::create_item(70 origin1.clone(),71 collection_id,72 1,73 data.clone()74 ));7576}7778// Use cases tests region79// #region8081#[test]82fn set_version_schema() {83 new_test_ext().execute_with(|| {84 default_limits();85 let origin1 = Origin::signed(1);86 let collection_id = create_test_collection(&CollectionMode::NFT, 1);87 88 assert_ok!(TemplateModule::set_schema_version(origin1, collection_id, SchemaVersion::Unique));89 assert_eq!(TemplateModule::collection(collection_id).schema_version, SchemaVersion::Unique);90 });91}9293#[test]94fn create_fungible_collection_fails_with_large_decimal_numbers() {95 new_test_ext().execute_with(|| {96 default_limits();9798 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();99 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();100 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();101102 let origin1 = Origin::signed(1);103 assert_noop!(TemplateModule::create_collection(104 origin1,105 col_name1,106 col_desc1,107 token_prefix1,108 CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1)109 ), Error::<Test>::CollectionDecimalPointLimitExceeded);110 }); 111}112113#[test]114fn create_re_fungible_collection_fails_with_large_decimal_numbers() {115 new_test_ext().execute_with(|| {116 default_limits();117118 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();119 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();120 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();121122 let origin1 = Origin::signed(1);123 assert_noop!(TemplateModule::create_collection(124 origin1,125 col_name1,126 col_desc1,127 token_prefix1,128 CollectionMode::ReFungible(MAX_DECIMAL_POINTS + 1)129 ), Error::<Test>::CollectionDecimalPointLimitExceeded);130 });131}132133#[test]134fn create_nft_item() {135 new_test_ext().execute_with(|| {136 default_limits();137 let collection_id = create_test_collection(&CollectionMode::NFT, 1);138 139 let data = default_nft_data();140 create_test_item(collection_id, &data.clone().into());141 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).const_data, data.const_data);142 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, data.variable_data);143 });144}145146// Use cases tests region147// #region148#[test]149fn create_nft_multiple_items() {150 new_test_ext().execute_with(|| {151 default_limits();152 153 create_test_collection(&CollectionMode::NFT, 1);154155 let origin1 = Origin::signed(1);156157 let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];158159 assert_ok!(TemplateModule::create_multiple_items(160 origin1.clone(),161 1,162 1,163 items_data.clone().into_iter().map(|d| { d.into() }).collect()164 ));165 for (index, data) in items_data.iter().enumerate() {166 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).const_data.to_vec(), data.const_data);167 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).variable_data.to_vec(), data.variable_data);168 }169 });170}171172#[test]173fn create_refungible_item() {174 new_test_ext().execute_with(|| {175 default_limits();176 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);177178 let data = default_re_fungible_data();179 create_test_item(collection_id, &data.clone().into());180 assert_eq!(181 TemplateModule::refungible_item_id(collection_id, 1).const_data,182 data.const_data183 );184 assert_eq!(185 TemplateModule::refungible_item_id(collection_id, 1).variable_data,186 data.variable_data187 );188 assert_eq!(189 TemplateModule::refungible_item_id(collection_id, 1).owner[0],190 Ownership {191 owner: 1,192 fraction: 1000193 }194 );195 });196}197198#[test]199fn create_multiple_refungible_items() {200 new_test_ext().execute_with(|| {201 default_limits();202 203 create_test_collection(&CollectionMode::ReFungible(3), 1);204205 let origin1 = Origin::signed(1);206207 let items_data = vec![default_re_fungible_data(), default_re_fungible_data(), default_re_fungible_data()];208209 assert_ok!(TemplateModule::create_multiple_items(210 origin1.clone(),211 1,212 1,213 items_data.clone().into_iter().map(|d| { d.into() }).collect()214 ));215 for (index, data) in items_data.iter().enumerate() {216217 let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId);218 assert_eq!(item.const_data.to_vec(), data.const_data);219 assert_eq!(item.variable_data.to_vec(), data.variable_data);220 assert_eq!(221 item.owner[0],222 Ownership {223 owner: 1,224 fraction: 1000225 }226 );227 }228 });229}230231#[test]232fn create_fungible_item() {233 new_test_ext().execute_with(|| {234 default_limits();235 236 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);237238 let data = default_fungible_data();239 create_test_item(collection_id, &data.into());240241 assert_eq!(TemplateModule::fungible_item_id(collection_id, 1).owner, 1);242 });243}244245#[test]246fn create_multiple_fungible_items() {247 new_test_ext().execute_with(|| {248 default_limits();249250 create_test_collection(&CollectionMode::Fungible(3), 1);251252 let origin1 = Origin::signed(1);253254 let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];255256 assert_ok!(TemplateModule::create_multiple_items(257 origin1.clone(),258 1,259 1,260 items_data.clone().into_iter().map(|d| { d.into() }).collect()261 ));262 263 for (index, _) in items_data.iter().enumerate() {264 assert_eq!(TemplateModule::fungible_item_id(1, (index + 1) as TokenId).owner, 1);265 }266 assert_eq!(TemplateModule::balance_count(1, 1), 3000);267 assert_eq!(TemplateModule::address_tokens(1, 1), [1, 2, 3]);268 });269}270271#[test]272fn transfer_fungible_item() {273 new_test_ext().execute_with(|| {274 default_limits();275 276 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);277278 let origin1 = Origin::signed(1);279 let origin2 = Origin::signed(2);280281 let data = default_fungible_data();282 create_test_item(collection_id, &data.into());283284 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 1);285 assert_eq!(TemplateModule::balance_count(1, 1), 1000);286 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);287288 // change owner scenario289 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));290 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);291 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 1000);292 assert_eq!(TemplateModule::balance_count(1, 1), 0);293 assert_eq!(TemplateModule::balance_count(1, 2), 1000);294 // assert_eq!(TemplateModule::address_tokens(1, 1), []);295 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);296297 // split item scenario298 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));299 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);300 assert_eq!(TemplateModule::fungible_item_id(1, 2).owner, 3);301 assert_eq!(TemplateModule::balance_count(1, 2), 500);302 assert_eq!(TemplateModule::balance_count(1, 3), 500);303 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);304 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);305306 // split item and new owner has account scenario307 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));308 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 300);309 assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 700);310 assert_eq!(TemplateModule::balance_count(1, 2), 300);311 assert_eq!(TemplateModule::balance_count(1, 3), 700);312 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);313 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);314 });315}316317#[test]318fn transfer_refungible_item() {319 new_test_ext().execute_with(|| {320 default_limits();321 322 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);323324 let data = default_re_fungible_data();325 create_test_item(collection_id, &data.clone().into());326327 let origin1 = Origin::signed(1);328 let origin2 = Origin::signed(2);329 assert_eq!(330 TemplateModule::refungible_item_id(collection_id, 1).const_data,331 data.const_data332 );333 assert_eq!(334 TemplateModule::refungible_item_id(collection_id, 1).variable_data,335 data.variable_data336 );337 assert_eq!(338 TemplateModule::refungible_item_id(collection_id, 1).owner[0],339 Ownership {340 owner: 1,341 fraction: 1000342 }343 );344 assert_eq!(TemplateModule::balance_count(1, 1), 1000);345 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);346347 // change owner scenario348 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));349 assert_eq!(350 TemplateModule::refungible_item_id(1, 1).owner[0],351 Ownership {352 owner: 2,353 fraction: 1000354 }355 );356 assert_eq!(TemplateModule::balance_count(1, 1), 0);357 assert_eq!(TemplateModule::balance_count(1, 2), 1000);358 // assert_eq!(TemplateModule::address_tokens(1, 1), []);359 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);360361 // split item scenario362 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));363 assert_eq!(364 TemplateModule::refungible_item_id(1, 1).owner[0],365 Ownership {366 owner: 2,367 fraction: 500368 }369 );370 assert_eq!(371 TemplateModule::refungible_item_id(1, 1).owner[1],372 Ownership {373 owner: 3,374 fraction: 500375 }376 );377 assert_eq!(TemplateModule::balance_count(1, 2), 500);378 assert_eq!(TemplateModule::balance_count(1, 3), 500);379 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);380 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);381382 // split item and new owner has account scenario383 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));384 assert_eq!(385 TemplateModule::refungible_item_id(1, 1).owner[0],386 Ownership {387 owner: 2,388 fraction: 300389 }390 );391 assert_eq!(392 TemplateModule::refungible_item_id(1, 1).owner[1],393 Ownership {394 owner: 3,395 fraction: 700396 }397 );398 assert_eq!(TemplateModule::balance_count(1, 2), 300);399 assert_eq!(TemplateModule::balance_count(1, 3), 700);400 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);401 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);402 });403}404405#[test]406fn transfer_nft_item() {407 new_test_ext().execute_with(|| {408 default_limits();409 410 let collection_id = create_test_collection(&CollectionMode::NFT, 1);411412 let data = default_nft_data();413 create_test_item(collection_id, &data.into());414 assert_eq!(TemplateModule::balance_count(1, 1), 1);415 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);416417 let origin1 = Origin::signed(1);418 // default scenario419 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));420 assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2);421 assert_eq!(TemplateModule::balance_count(1, 1), 0);422 assert_eq!(TemplateModule::balance_count(1, 2), 1);423 // assert_eq!(TemplateModule::address_tokens(1, 1), []);424 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);425 });426}427428#[test]429fn nft_approve_and_transfer_from() {430 new_test_ext().execute_with(|| {431 default_limits();432 433 let collection_id = create_test_collection(&CollectionMode::NFT, 1);434435 let data = default_nft_data();436 create_test_item(collection_id, &data.into());437438 let origin1 = Origin::signed(1);439 let origin2 = Origin::signed(2);440441 assert_eq!(TemplateModule::balance_count(1, 1), 1);442 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);443444 // neg transfer445 assert_noop!(TemplateModule::transfer_from(446 origin2.clone(),447 1,448 2,449 1,450 1,451 1), Error::<Test>::NoPermission);452453 // do approve454 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));455 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);456 assert_eq!(457 TemplateModule::approved(1, (1, 1))[0],458 ApprovePermissions {459 approved: 2,460 amount: 100000000461 }462 );463464 assert_ok!(TemplateModule::transfer_from(465 origin2.clone(),466 1,467 2,468 1,469 1,470 1471 ));472 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);473 });474}475476#[test]477fn nft_approve_and_transfer_from_white_list() {478 new_test_ext().execute_with(|| {479 default_limits();480 481 let collection_id = create_test_collection(&CollectionMode::NFT, 1);482483 let origin1 = Origin::signed(1);484 let origin2 = Origin::signed(2);485486 let data = default_nft_data();487 create_test_item(collection_id, &data.clone().into());488489 assert_eq!(TemplateModule::nft_item_id(1, 1).const_data, data.const_data);490 assert_eq!(TemplateModule::balance_count(1, 1), 1);491 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);492493 assert_ok!(TemplateModule::set_mint_permission(494 origin1.clone(),495 1,496 true497 ));498 assert_ok!(TemplateModule::set_public_access_mode(499 origin1.clone(),500 1,501 AccessMode::WhiteList502 ));503 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));504 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));505 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));506507 // do approve508 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));509 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);510 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));511 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);512 assert_eq!(513 TemplateModule::approved(1, (1, 1))[0],514 ApprovePermissions {515 approved: 2,516 amount: 100000000517 }518 );519520 assert_ok!(TemplateModule::transfer_from(521 origin2.clone(),522 1,523 3,524 1,525 1,526 1527 ));528 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);529 });530}531532#[test]533fn refungible_approve_and_transfer_from() {534 new_test_ext().execute_with(|| {535 default_limits();536 537 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);538 539 let origin1 = Origin::signed(1);540 let origin2 = Origin::signed(2);541542 let data = default_re_fungible_data();543 create_test_item(collection_id, &data.into());544545 assert_eq!(TemplateModule::balance_count(1, 1), 1000);546 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);547548 assert_ok!(TemplateModule::set_mint_permission(549 origin1.clone(),550 1,551 true552 ));553 assert_ok!(TemplateModule::set_public_access_mode(554 origin1.clone(),555 1,556 AccessMode::WhiteList557 ));558 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));559 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));560 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));561562 // do approve563 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));564 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);565 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));566 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);567 assert_eq!(568 TemplateModule::approved(1, (1, 1))[0],569 ApprovePermissions {570 approved: 2,571 amount: 100000000572 }573 );574575 assert_ok!(TemplateModule::transfer_from(576 origin2.clone(),577 1,578 3,579 1,580 1,581 100582 ));583 assert_eq!(TemplateModule::balance_count(1, 1), 900);584 assert_eq!(TemplateModule::balance_count(1, 3), 100);585 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);586 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);587588 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);589 assert_eq!(590 TemplateModule::approved(1, (1, 1))[0],591 ApprovePermissions {592 approved: 3,593 amount: 100000000594 }595 );596 });597}598599#[test]600fn fungible_approve_and_transfer_from() {601 new_test_ext().execute_with(|| {602 default_limits();603 604 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);605 606 let data = default_fungible_data();607 create_test_item(collection_id, &data.into());608609 let origin1 = Origin::signed(1);610 let origin2 = Origin::signed(2);611612 assert_eq!(TemplateModule::balance_count(1, 1), 1000);613 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);614615 assert_ok!(TemplateModule::set_mint_permission(616 origin1.clone(),617 1,618 true619 ));620 assert_ok!(TemplateModule::set_public_access_mode(621 origin1.clone(),622 1,623 AccessMode::WhiteList624 ));625 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));626 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));627 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));628629 // do approve630 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));631 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);632 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));633 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);634 assert_eq!(635 TemplateModule::approved(1, (1, 1))[0],636 ApprovePermissions {637 approved: 2,638 amount: 100000000639 }640 );641642 assert_ok!(TemplateModule::transfer_from(643 origin2.clone(),644 1,645 3,646 1,647 1,648 100649 ));650 assert_eq!(TemplateModule::balance_count(1, 1), 900);651 assert_eq!(TemplateModule::balance_count(1, 3), 100);652 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);653 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);654655 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);656 assert_eq!(657 TemplateModule::approved(1, (1, 1))[0],658 ApprovePermissions {659 approved: 3,660 amount: 100000000661 }662 );663664 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));665 assert_ok!(TemplateModule::transfer_from(666 origin2.clone(),667 1,668 3,669 1,670 1,671 900672 ));673 assert_eq!(TemplateModule::balance_count(1, 1), 0);674 assert_eq!(TemplateModule::balance_count(1, 3), 1000);675 // assert_eq!(TemplateModule::address_tokens(1, 1), []);676 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);677678 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);679 });680}681682#[test]683fn change_collection_owner() {684 new_test_ext().execute_with(|| {685 default_limits();686 687 let collection_id = create_test_collection(&CollectionMode::NFT, 1);688 689 let origin1 = Origin::signed(1);690 assert_ok!(TemplateModule::change_collection_owner(691 origin1.clone(),692 collection_id,693 2694 ));695 assert_eq!(TemplateModule::collection(collection_id).owner, 2);696 });697}698699#[test]700fn destroy_collection() {701 new_test_ext().execute_with(|| {702 default_limits();703 704 let collection_id = create_test_collection(&CollectionMode::NFT, 1);705 706 let origin1 = Origin::signed(1);707 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));708 });709}710711#[test]712fn burn_nft_item() {713 new_test_ext().execute_with(|| {714 default_limits();715 716 let collection_id = create_test_collection(&CollectionMode::NFT, 1);717718 let origin1 = Origin::signed(1);719 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));720 721 let data = default_nft_data();722 create_test_item(collection_id, &data.into());723724 // check balance (collection with id = 1, user id = 1)725 assert_eq!(TemplateModule::balance_count(1, 1), 1);726727 // burn item728 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));729 assert_noop!(730 TemplateModule::burn_item(origin1.clone(), 1, 1),731 Error::<Test>::TokenNotFound732 );733734 assert_eq!(TemplateModule::balance_count(1, 1), 0);735 });736}737738#[test]739fn burn_fungible_item() {740 new_test_ext().execute_with(|| {741 default_limits();742 743 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);744 745 let origin1 = Origin::signed(1);746 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));747 748 let data = default_fungible_data();749 create_test_item(collection_id, &data.into());750751 // check balance (collection with id = 1, user id = 1)752 assert_eq!(TemplateModule::balance_count(1, 1), 1000);753754 // burn item755 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));756 assert_noop!(757 TemplateModule::burn_item(origin1.clone(), 1, 1),758 Error::<Test>::TokenNotFound759 );760761 assert_eq!(TemplateModule::balance_count(1, 1), 0);762 });763}764765#[test]766fn burn_refungible_item() {767 new_test_ext().execute_with(|| {768 default_limits();769 770 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);771 let origin1 = Origin::signed(1);772773 assert_ok!(TemplateModule::set_mint_permission(774 origin1.clone(),775 collection_id,776 true777 ));778 assert_ok!(TemplateModule::set_public_access_mode(779 origin1.clone(),780 collection_id,781 AccessMode::WhiteList782 ));783 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));784785 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));786 787 let data = default_re_fungible_data();788 create_test_item(collection_id, &data.into());789790 // check balance (collection with id = 1, user id = 2)791 assert_eq!(TemplateModule::balance_count(1, 1), 1000);792793 // burn item794 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));795 assert_noop!(796 TemplateModule::burn_item(origin1.clone(), 1, 1),797 Error::<Test>::TokenNotFound798 );799800 assert_eq!(TemplateModule::balance_count(1, 1), 0);801 });802}803804#[test]805fn add_collection_admin() {806 new_test_ext().execute_with(|| {807 default_limits();808 809 let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);810 create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);811 create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);812 813 let origin1 = Origin::signed(1);814815 // collection admin816 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));817 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));818819 assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&2), true);820 assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&3), true);821 });822}823824#[test]825fn remove_collection_admin() {826 new_test_ext().execute_with(|| {827 default_limits();828 829 let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);830 create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);831 create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);832833 let origin1 = Origin::signed(1);834 let origin2 = Origin::signed(2);835836 // collection admin837 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));838 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));839840 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);841 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);842843 // remove admin844 assert_ok!(TemplateModule::remove_collection_admin(845 origin2.clone(),846 1,847 3848 ));849 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), false);850 });851}852853#[test]854fn balance_of() {855 new_test_ext().execute_with(|| {856 default_limits();857 858 let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);859 let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);860 let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible(3), 3);861 862 // check balance before863 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);864 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);865 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 0);866867 let nft_data = default_nft_data();868 create_test_item(nft_collection_id, &nft_data.into());869 870 let fungible_data = default_fungible_data();871 create_test_item(fungible_collection_id, &fungible_data.into());872 873 let re_fungible_data = default_re_fungible_data();874 create_test_item(re_fungible_collection_id, &re_fungible_data.into());875876 // check balance (collection with id = 1, user id = 1)877 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1);878 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 1000);879 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 1000);880 assert_eq!(TemplateModule::nft_item_id(nft_collection_id, 1).owner, 1);881 assert_eq!(TemplateModule::fungible_item_id(fungible_collection_id, 1).owner, 1);882 assert_eq!(TemplateModule::refungible_item_id(re_fungible_collection_id, 1).owner[0].owner, 1);883 });884}885886#[test]887fn approve() {888 new_test_ext().execute_with(|| {889 default_limits();890 891 let collection_id = create_test_collection(&CollectionMode::NFT, 1);892 893 let data = default_nft_data();894 create_test_item(collection_id, &data.into());895896 let origin1 = Origin::signed(1);897 898 // approve899 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));900 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);901 });902}903904#[test]905fn transfer_from() {906 new_test_ext().execute_with(|| {907 default_limits();908 909 let collection_id = create_test_collection(&CollectionMode::NFT, 1);910 let origin1 = Origin::signed(1);911 let origin2 = Origin::signed(2);912913 let data = default_nft_data();914 create_test_item(collection_id, &data.into());915916 // approve917 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));918 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);919920 assert_ok!(TemplateModule::set_mint_permission(921 origin1.clone(),922 1,923 true924 ));925 assert_ok!(TemplateModule::set_public_access_mode(926 origin1.clone(),927 1,928 AccessMode::WhiteList929 ));930 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));931 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));932 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));933934 assert_ok!(TemplateModule::transfer_from(935 origin2.clone(),936 1,937 2,938 1,939 1,940 1941 ));942943 // after transfer944 assert_eq!(TemplateModule::balance_count(1, 1), 0);945 assert_eq!(TemplateModule::balance_count(1, 2), 1);946 });947}948949// #endregion950951// Coverage tests region952// #region953954#[test]955fn owner_can_add_address_to_white_list() {956 new_test_ext().execute_with(|| {957 default_limits();958 959 let collection_id = create_test_collection(&CollectionMode::NFT, 1);960961 let origin1 = Origin::signed(1);962 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));963 assert_eq!(TemplateModule::white_list(collection_id)[0], 2);964 });965}966967#[test]968fn admin_can_add_address_to_white_list() {969 new_test_ext().execute_with(|| {970 default_limits();971 972 let collection_id = create_test_collection(&CollectionMode::NFT, 1);973 let origin1 = Origin::signed(1);974 let origin2 = Origin::signed(2);975976 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));977 assert_ok!(TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3));978 assert_eq!(TemplateModule::white_list(collection_id)[0], 3);979 });980}981982#[test]983fn nonprivileged_user_cannot_add_address_to_white_list() {984 new_test_ext().execute_with(|| {985 default_limits();986 987 let collection_id = create_test_collection(&CollectionMode::NFT, 1);988989 let origin2 = Origin::signed(2);990 assert_noop!(991 TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3),992 Error::<Test>::NoPermission993 );994 });995}996997#[test]998fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {999 new_test_ext().execute_with(|| {1000 default_limits();10011002 let origin1 = Origin::signed(1);10031004 assert_noop!(1005 TemplateModule::add_to_white_list(origin1.clone(), 1, 2),1006 Error::<Test>::CollectionNotFound1007 );1008 });1009}10101011#[test]1012fn nobody_can_add_address_to_white_list_of_deleted_collection() {1013 new_test_ext().execute_with(|| {1014 default_limits();1015 1016 let collection_id = create_test_collection(&CollectionMode::NFT, 1);10171018 let origin1 = Origin::signed(1);1019 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1020 assert_noop!(1021 TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2),1022 Error::<Test>::CollectionNotFound1023 );1024 });1025}10261027// If address is already added to white list, nothing happens1028#[test]1029fn address_is_already_added_to_white_list() {1030 new_test_ext().execute_with(|| {1031 default_limits();1032 1033 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1034 let origin1 = Origin::signed(1);1035 1036 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1037 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1038 assert_eq!(TemplateModule::white_list(collection_id)[0], 2);1039 assert_eq!(TemplateModule::white_list(collection_id).len(), 1);1040 });1041}10421043#[test]1044fn owner_can_remove_address_from_white_list() {1045 new_test_ext().execute_with(|| {1046 default_limits();1047 1048 let collection_id = create_test_collection(&CollectionMode::NFT, 1);10491050 let origin1 = Origin::signed(1);1051 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1052 assert_ok!(TemplateModule::remove_from_white_list(1053 origin1.clone(),1054 collection_id,1055 21056 ));1057 assert_eq!(TemplateModule::white_list(collection_id).len(), 0);1058 });1059}10601061#[test]1062fn admin_can_remove_address_from_white_list() {1063 new_test_ext().execute_with(|| {1064 default_limits();1065 1066 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1067 let origin1 = Origin::signed(1);1068 let origin2 = Origin::signed(2);10691070 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));10711072 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 3));1073 assert_ok!(TemplateModule::remove_from_white_list(1074 origin2.clone(),1075 collection_id,1076 31077 ));1078 assert_eq!(TemplateModule::white_list(collection_id).len(), 0);1079 });1080}10811082#[test]1083fn nonprivileged_user_cannot_remove_address_from_white_list() {1084 new_test_ext().execute_with(|| {1085 default_limits();1086 1087 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1088 let origin1 = Origin::signed(1);1089 let origin2 = Origin::signed(2);10901091 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1092 assert_noop!(1093 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1094 Error::<Test>::NoPermission1095 );1096 assert_eq!(TemplateModule::white_list(collection_id)[0], 2);1097 });1098}10991100#[test]1101fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1102 new_test_ext().execute_with(|| {1103 default_limits();1104 let origin1 = Origin::signed(1);11051106 assert_noop!(1107 TemplateModule::remove_from_white_list(origin1.clone(), 1, 2),1108 Error::<Test>::CollectionNotFound1109 );1110 });1111}11121113#[test]1114fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1115 new_test_ext().execute_with(|| {1116 default_limits();1117 1118 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1119 let origin1 = Origin::signed(1);1120 let origin2 = Origin::signed(2);11211122 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1123 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1124 assert_noop!(1125 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1126 Error::<Test>::CollectionNotFound1127 );1128 assert_eq!(TemplateModule::white_list(collection_id).len(), 0);1129 });1130}11311132// If address is already removed from white list, nothing happens1133#[test]1134fn address_is_already_removed_from_white_list() {1135 new_test_ext().execute_with(|| {1136 default_limits();1137 1138 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1139 let origin1 = Origin::signed(1);11401141 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1142 assert_ok!(TemplateModule::remove_from_white_list(1143 origin1.clone(),1144 collection_id,1145 21146 ));1147 assert_ok!(TemplateModule::remove_from_white_list(1148 origin1.clone(),1149 collection_id,1150 21151 ));1152 assert_eq!(TemplateModule::white_list(collection_id).len(), 0);1153 });1154}11551156// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1157#[test]1158fn white_list_test_1() {1159 new_test_ext().execute_with(|| {1160 default_limits();1161 1162 let collection_id = create_test_collection(&CollectionMode::NFT, 1);11631164 let origin1 = Origin::signed(1);1165 1166 let data = default_nft_data();1167 create_test_item(collection_id, &data.into());11681169 assert_ok!(TemplateModule::set_public_access_mode(1170 origin1.clone(),1171 collection_id,1172 AccessMode::WhiteList1173 ));1174 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));11751176 assert_noop!(1177 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1178 Error::<Test>::AddresNotInWhiteList1179 );1180 });1181}11821183#[test]1184fn white_list_test_2() {1185 new_test_ext().execute_with(|| {1186 default_limits();1187 1188 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1189 let origin1 = Origin::signed(1);1190 1191 let data = default_nft_data();1192 create_test_item(collection_id, &data.into());11931194 assert_ok!(TemplateModule::set_public_access_mode(1195 origin1.clone(),1196 collection_id,1197 AccessMode::WhiteList1198 ));1199 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1200 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));12011202 // do approve1203 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1204 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);12051206 assert_ok!(TemplateModule::remove_from_white_list(1207 origin1.clone(),1208 1,1209 11210 ));12111212 assert_noop!(1213 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1214 Error::<Test>::AddresNotInWhiteList1215 );1216 });1217}12181219// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1220#[test]1221fn white_list_test_3() {1222 new_test_ext().execute_with(|| {1223 default_limits();1224 1225 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12261227 let origin1 = Origin::signed(1);1228 1229 let data = default_nft_data();1230 create_test_item(collection_id, &data.into());12311232 assert_ok!(TemplateModule::set_public_access_mode(1233 origin1.clone(),1234 collection_id,1235 AccessMode::WhiteList1236 ));1237 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));12381239 assert_noop!(1240 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1241 Error::<Test>::AddresNotInWhiteList1242 );1243 });1244}12451246#[test]1247fn white_list_test_4() {1248 new_test_ext().execute_with(|| {1249 default_limits();1250 1251 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12521253 let origin1 = Origin::signed(1);12541255 let data = default_nft_data();1256 create_test_item(collection_id, &data.into());12571258 assert_ok!(TemplateModule::set_public_access_mode(1259 origin1.clone(),1260 collection_id,1261 AccessMode::WhiteList1262 ));1263 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1264 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));12651266 // do approve1267 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1268 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);12691270 assert_ok!(TemplateModule::remove_from_white_list(1271 origin1.clone(),1272 collection_id,1273 21274 ));12751276 assert_noop!(1277 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1278 Error::<Test>::AddresNotInWhiteList1279 );1280 });1281}12821283// If Public Access mode is set to WhiteList, tokens can’t be destroyed by a non-whitelisted address (even if it owned them before enabling WhiteList mode)1284#[test]1285fn white_list_test_5() {1286 new_test_ext().execute_with(|| {1287 default_limits();1288 1289 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12901291 let origin1 = Origin::signed(1);12921293 let data = default_nft_data();1294 create_test_item(collection_id, &data.into());12951296 assert_ok!(TemplateModule::set_public_access_mode(1297 origin1.clone(),1298 collection_id,1299 AccessMode::WhiteList1300 ));1301 assert_noop!(1302 TemplateModule::burn_item(origin1.clone(), 1, 1),1303 Error::<Test>::AddresNotInWhiteList1304 );1305 });1306}13071308// If Public Access mode is set to WhiteList, oken transfers can’t be Approved by a non-whitelisted address (see Approve method).1309#[test]1310fn white_list_test_6() {1311 new_test_ext().execute_with(|| {1312 default_limits();1313 1314 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13151316 let origin1 = Origin::signed(1);1317 assert_ok!(TemplateModule::set_public_access_mode(1318 origin1.clone(),1319 collection_id,1320 AccessMode::WhiteList1321 ));13221323 // do approve1324 assert_noop!(1325 TemplateModule::approve(origin1.clone(), 1, 1, 1),1326 Error::<Test>::AddresNotInWhiteList1327 );1328 });1329}13301331// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1332// tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1333#[test]1334fn white_list_test_7() {1335 new_test_ext().execute_with(|| {1336 default_limits();1337 1338 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13391340 let data = default_nft_data();1341 create_test_item(collection_id, &data.into());1342 1343 let origin1 = Origin::signed(1);13441345 assert_ok!(TemplateModule::set_public_access_mode(1346 origin1.clone(),1347 collection_id,1348 AccessMode::WhiteList1349 ));1350 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1351 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13521353 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1));1354 });1355}13561357#[test]1358fn white_list_test_8() {1359 new_test_ext().execute_with(|| {1360 default_limits();1361 1362 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13631364 let data = default_nft_data();1365 create_test_item(collection_id, &data.into());1366 1367 let origin1 = Origin::signed(1);13681369 assert_ok!(TemplateModule::set_public_access_mode(1370 origin1.clone(),1371 collection_id,1372 AccessMode::WhiteList1373 ));1374 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1375 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13761377 // do approve1378 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1379 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);13801381 assert_ok!(TemplateModule::transfer_from(1382 origin1.clone(),1383 1,1384 2,1385 1,1386 1,1387 11388 ));1389 });1390}13911392// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1393#[test]1394fn white_list_test_9() {1395 new_test_ext().execute_with(|| {1396 default_limits();1397 1398 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1399 let origin1 = Origin::signed(1);14001401 assert_ok!(TemplateModule::set_public_access_mode(1402 origin1.clone(),1403 collection_id,1404 AccessMode::WhiteList1405 ));1406 assert_ok!(TemplateModule::set_mint_permission(1407 origin1.clone(),1408 collection_id,1409 false1410 ));14111412 let data = default_nft_data();1413 create_test_item(collection_id, &data.into());1414 });1415}14161417// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1418#[test]1419fn white_list_test_10() {1420 new_test_ext().execute_with(|| {1421 default_limits();1422 1423 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14241425 let origin1 = Origin::signed(1);1426 let origin2 = Origin::signed(2);14271428 assert_ok!(TemplateModule::set_public_access_mode(1429 origin1.clone(),1430 collection_id,1431 AccessMode::WhiteList1432 ));1433 assert_ok!(TemplateModule::set_mint_permission(1434 origin1.clone(),1435 collection_id,1436 false1437 ));14381439 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));14401441 assert_ok!(TemplateModule::create_item(1442 origin2.clone(),1443 collection_id,1444 2,1445 default_nft_data().into()1446 ));1447 });1448}14491450// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and white listed address.1451#[test]1452fn white_list_test_11() {1453 new_test_ext().execute_with(|| {1454 default_limits();1455 1456 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14571458 let origin1 = Origin::signed(1);1459 let origin2 = Origin::signed(2);14601461 assert_ok!(TemplateModule::set_public_access_mode(1462 origin1.clone(),1463 collection_id,1464 AccessMode::WhiteList1465 ));1466 assert_ok!(TemplateModule::set_mint_permission(1467 origin1.clone(),1468 collection_id,1469 false1470 ));1471 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));14721473 assert_noop!(1474 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1475 Error::<Test>::PublicMintingNotAllowed1476 );1477 });1478}14791480// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-white listed address.1481#[test]1482fn white_list_test_12() {1483 new_test_ext().execute_with(|| {1484 default_limits();1485 1486 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14871488 let origin1 = Origin::signed(1);1489 let origin2 = Origin::signed(2);14901491 assert_ok!(TemplateModule::set_public_access_mode(1492 origin1.clone(),1493 collection_id,1494 AccessMode::WhiteList1495 ));1496 assert_ok!(TemplateModule::set_mint_permission(1497 origin1.clone(),1498 collection_id,1499 false1500 ));15011502 assert_noop!(1503 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1504 Error::<Test>::PublicMintingNotAllowed1505 );1506 });1507}15081509// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1510#[test]1511fn white_list_test_13() {1512 new_test_ext().execute_with(|| {1513 default_limits();1514 1515 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15161517 let origin1 = Origin::signed(1);15181519 assert_ok!(TemplateModule::set_public_access_mode(1520 origin1.clone(),1521 collection_id,1522 AccessMode::WhiteList1523 ));1524 assert_ok!(TemplateModule::set_mint_permission(1525 origin1.clone(),1526 collection_id,1527 true1528 ));15291530 let data = default_nft_data();1531 create_test_item(collection_id, &data.into());1532 });1533}15341535// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1536#[test]1537fn white_list_test_14() {1538 new_test_ext().execute_with(|| {1539 default_limits();1540 1541 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15421543 let origin1 = Origin::signed(1);1544 let origin2 = Origin::signed(2);15451546 assert_ok!(TemplateModule::set_public_access_mode(1547 origin1.clone(),1548 collection_id,1549 AccessMode::WhiteList1550 ));1551 assert_ok!(TemplateModule::set_mint_permission(1552 origin1.clone(),1553 collection_id,1554 true1555 ));15561557 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));15581559 assert_ok!(TemplateModule::create_item(1560 origin2.clone(),1561 1,1562 2,1563 default_nft_data().into()1564 ));1565 });1566}15671568// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-white listed address.1569#[test]1570fn white_list_test_15() {1571 new_test_ext().execute_with(|| {1572 default_limits();1573 1574 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15751576 let origin1 = Origin::signed(1);1577 let origin2 = Origin::signed(2);15781579 assert_ok!(TemplateModule::set_public_access_mode(1580 origin1.clone(),1581 collection_id,1582 AccessMode::WhiteList1583 ));1584 assert_ok!(TemplateModule::set_mint_permission(1585 origin1.clone(),1586 collection_id,1587 true1588 ));15891590 assert_noop!(1591 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1592 Error::<Test>::AddresNotInWhiteList1593 );1594 });1595}15961597// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by non-privileged and white listed address.1598#[test]1599fn white_list_test_16() {1600 new_test_ext().execute_with(|| {1601 default_limits();1602 1603 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16041605 let origin1 = Origin::signed(1);1606 let origin2 = Origin::signed(2);16071608 assert_ok!(TemplateModule::set_public_access_mode(1609 origin1.clone(),1610 collection_id,1611 AccessMode::WhiteList1612 ));1613 assert_ok!(TemplateModule::set_mint_permission(1614 origin1.clone(),1615 collection_id,1616 true1617 ));1618 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));16191620 assert_ok!(TemplateModule::create_item(1621 origin2.clone(),1622 1,1623 2,1624 default_nft_data().into()1625 ));1626 });1627}16281629// Total number of collections. Positive test1630#[test]1631fn total_number_collections_bound() {1632 new_test_ext().execute_with(|| {1633 default_limits();1634 1635 create_test_collection(&CollectionMode::NFT, 1);1636 });1637}16381639// Total number of collections. Negotive test1640#[test]1641fn total_number_collections_bound_neg() {1642 new_test_ext().execute_with(|| {1643 default_limits();16441645 let origin1 = Origin::signed(1);16461647 for i in 0..default_collection_numbers_limit() {1648 create_test_collection(&CollectionMode::NFT, i + 1);1649 }16501651 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1652 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1653 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();16541655 // 11-th collection in chain. Expects error1656 assert_noop!(TemplateModule::create_collection(1657 origin1.clone(),1658 col_name1.clone(),1659 col_desc1.clone(),1660 token_prefix1.clone(),1661 CollectionMode::NFT1662 ), Error::<Test>::TotalCollectionsLimitExceeded);1663 });1664}16651666// Owned tokens by a single address. Positive test1667#[test]1668fn owned_tokens_bound() {1669 new_test_ext().execute_with(|| {1670 default_limits();1671 1672 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16731674 let data = default_nft_data();1675 create_test_item(collection_id, &data.clone().into());1676 create_test_item(collection_id, &data.into());1677 });1678}16791680// Owned tokens by a single address. Negotive test1681#[test]1682fn owned_tokens_bound_neg() {1683 new_test_ext().execute_with(|| {1684 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1685 collection_numbers_limit: 10,1686 account_token_ownership_limit: 1,1687 collections_admins_limit: 5,1688 custom_data_limit: 2048,1689 nft_sponsor_transfer_timeout: 15,1690 fungible_sponsor_transfer_timeout: 15,1691 refungible_sponsor_transfer_timeout: 15, 1692 }));1693 1694 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16951696 let origin1 = Origin::signed(1);1697 let data = default_nft_data();1698 create_test_item(collection_id, &data.clone().into());16991700 assert_noop!(TemplateModule::create_item(1701 origin1.clone(),1702 1,1703 1,1704 data.into()1705 ), Error::<Test>::AddressOwnershipLimitExceeded);1706 });1707}17081709// Number of collection admins. Positive test1710#[test]1711fn collection_admins_bound() {1712 new_test_ext().execute_with(|| {1713 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1714 collection_numbers_limit: 10,1715 account_token_ownership_limit: 10,1716 collections_admins_limit: 2,1717 custom_data_limit: 2048,1718 nft_sponsor_transfer_timeout: 15,1719 fungible_sponsor_transfer_timeout: 15,1720 refungible_sponsor_transfer_timeout: 15, 1721 }));1722 1723 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17241725 let origin1 = Origin::signed(1);1726 1727 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1728 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3));1729 });1730}17311732// Number of collection admins. Negotive test1733#[test]1734fn collection_admins_bound_neg() {1735 new_test_ext().execute_with(|| {1736 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1737 collection_numbers_limit: 10,1738 account_token_ownership_limit: 1,1739 collections_admins_limit: 1,1740 custom_data_limit: 2048,1741 nft_sponsor_transfer_timeout: 15,1742 fungible_sponsor_transfer_timeout: 15,1743 refungible_sponsor_transfer_timeout: 15, 1744 }));1745 1746 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17471748 let origin1 = Origin::signed(1);17491750 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1751 assert_noop!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3), Error::<Test>::CollectionAdminsLimitExceeded);1752 });1753}17541755// NFT custom data size. Negative test const_data.1756#[test]1757fn custom_data_size_nft_const_data_bound_neg() {1758 new_test_ext().execute_with(|| {1759 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1760 collection_numbers_limit: 10,1761 account_token_ownership_limit: 10,1762 collections_admins_limit: 5,1763 custom_data_limit: 2,1764 nft_sponsor_transfer_timeout: 15,1765 fungible_sponsor_transfer_timeout: 15,1766 refungible_sponsor_transfer_timeout: 15, 1767 }));1768 1769 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17701771 let origin1 = Origin::signed(1);1772 let too_big_const_data = CreateItemData::NFT(CreateNftData{1773 const_data: vec![1, 2, 3, 4],1774 variable_data: vec![]1775 });17761777 assert_noop!(TemplateModule::create_item(1778 origin1.clone(),1779 collection_id,1780 1,1781 too_big_const_data1782 ), Error::<Test>::TokenConstDataLimitExceeded);1783 });1784}17851786// NFT custom data size. Negative test variable_data.1787#[test]1788fn custom_data_size_nft_variable_data_bound_neg() {1789 new_test_ext().execute_with(|| {1790 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1791 collection_numbers_limit: 10,1792 account_token_ownership_limit: 10,1793 collections_admins_limit: 5,1794 custom_data_limit: 2,1795 nft_sponsor_transfer_timeout: 15,1796 fungible_sponsor_transfer_timeout: 15,1797 refungible_sponsor_transfer_timeout: 15, 1798 }));17991800 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18011802 let origin1 = Origin::signed(1);1803 let too_big_const_data = CreateItemData::NFT(CreateNftData{1804 const_data: vec![],1805 variable_data: vec![1, 2, 3, 4]1806 });18071808 assert_noop!(TemplateModule::create_item(1809 origin1.clone(),1810 collection_id,1811 1,1812 too_big_const_data1813 ), Error::<Test>::TokenVariableDataLimitExceeded);1814 });1815}18161817// Re fungible custom data size. Negative test const_data.1818#[test]1819fn custom_data_size_re_fungible_const_data_bound_neg() {1820 new_test_ext().execute_with(|| {1821 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1822 collection_numbers_limit: 10,1823 account_token_ownership_limit: 10,1824 collections_admins_limit: 5,1825 custom_data_limit: 2,1826 nft_sponsor_transfer_timeout: 15,1827 fungible_sponsor_transfer_timeout: 15,1828 refungible_sponsor_transfer_timeout: 15, 1829 }));18301831 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18321833 let origin1 = Origin::signed(1);1834 let too_big_const_data = CreateItemData::NFT(CreateNftData{1835 const_data: vec![1, 2, 3, 4],1836 variable_data: vec![]1837 });18381839 assert_noop!(TemplateModule::create_item(1840 origin1.clone(),1841 collection_id,1842 1,1843 too_big_const_data1844 ), Error::<Test>::TokenConstDataLimitExceeded);1845 });1846}18471848// Re fungible custom data size. Negative test variable_data.1849#[test]1850fn custom_data_size_re_fungible_variable_data_bound_neg() {1851 new_test_ext().execute_with(|| {1852 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1853 collection_numbers_limit: 10,1854 account_token_ownership_limit: 10,1855 collections_admins_limit: 5,1856 custom_data_limit: 2,1857 nft_sponsor_transfer_timeout: 15,1858 fungible_sponsor_transfer_timeout: 15,1859 refungible_sponsor_transfer_timeout: 15, 1860 }));18611862 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18631864 let origin1 = Origin::signed(1);1865 let too_big_const_data = CreateItemData::NFT(CreateNftData{1866 const_data: vec![],1867 variable_data: vec![1, 2, 3, 4]1868 });18691870 assert_noop!(TemplateModule::create_item(1871 origin1.clone(),1872 collection_id,1873 1,1874 too_big_const_data1875 ), Error::<Test>::TokenVariableDataLimitExceeded);1876 });1877}1878// #endregion18791880#[test]1881fn set_const_on_chain_schema() {1882 new_test_ext().execute_with(|| {1883 default_limits();18841885 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18861887 let origin1 = Origin::signed(1);1888 assert_ok!(TemplateModule::set_const_on_chain_schema(origin1, collection_id, b"test const on chain schema".to_vec()));18891890 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"test const on chain schema".to_vec());1891 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"".to_vec());1892 });1893}18941895#[test]1896fn set_variable_on_chain_schema() {1897 new_test_ext().execute_with(|| {1898 default_limits();1899 1900 let collection_id = create_test_collection(&CollectionMode::NFT, 1);19011902 let origin1 = Origin::signed(1);1903 assert_ok!(TemplateModule::set_variable_on_chain_schema(origin1, collection_id, b"test variable on chain schema".to_vec()));19041905 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"".to_vec());1906 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"test variable on chain schema".to_vec());1907 });1908}19091910#[test]1911fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {1912 new_test_ext().execute_with(|| {1913 default_limits();19141915 let collection_id = create_test_collection(&CollectionMode::NFT, 1);19161917 let origin1 = Origin::signed(1);1918 1919 let data = default_nft_data();1920 create_test_item(1, &data.into());1921 1922 let variable_data = b"test set_variable_meta_data method.".to_vec();1923 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));19241925 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, variable_data);1926 });1927}19281929#[test]1930fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {1931 new_test_ext().execute_with(|| {1932 default_limits();19331934 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);19351936 let origin1 = Origin::signed(1);19371938 let data = default_re_fungible_data();1939 create_test_item(1, &data.into());19401941 let variable_data = b"test set_variable_meta_data method.".to_vec();1942 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));19431944 assert_eq!(TemplateModule::refungible_item_id(collection_id, 1).variable_data, variable_data);1945 });1946}194719481949#[test]1950fn set_variable_meta_data_on_fungible_token_fails() {1951 new_test_ext().execute_with(|| {1952 default_limits();19531954 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);19551956 let origin1 = Origin::signed(1);19571958 let data = default_fungible_data();1959 create_test_item(1, &data.into());19601961 let variable_data = b"test set_variable_meta_data method.".to_vec();1962 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()), Error::<Test>::CantStoreMetadataInFungibleTokens);1963 });1964}19651966#[test]1967fn set_variable_meta_data_on_nft_token_fails_for_big_data() {1968 new_test_ext().execute_with(|| {1969 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1970 collection_numbers_limit: default_collection_numbers_limit(),1971 account_token_ownership_limit: 10,1972 collections_admins_limit: 5,1973 custom_data_limit: 10,1974 nft_sponsor_transfer_timeout: 15,1975 fungible_sponsor_transfer_timeout: 15,1976 refungible_sponsor_transfer_timeout: 15, 1977 }));19781979 let collection_id = create_test_collection(&CollectionMode::NFT, 1);19801981 let origin1 = Origin::signed(1);19821983 let data = default_nft_data();1984 create_test_item(1, &data.into());19851986 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1987 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);1988 });1989}19901991#[test]1992fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {1993 new_test_ext().execute_with(|| {1994 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1995 collection_numbers_limit: default_collection_numbers_limit(),1996 account_token_ownership_limit: 10,1997 collections_admins_limit: 5,1998 custom_data_limit: 10,1999 nft_sponsor_transfer_timeout: 15,2000 fungible_sponsor_transfer_timeout: 15,2001 refungible_sponsor_transfer_timeout: 15, 2002 }));200320042005 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);20062007 let origin1 = Origin::signed(1);20082009 let data = default_re_fungible_data();2010 create_test_item(1, &data.into());20112012 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();2013 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);2014 });2015}1// Tests to be written here2use super::*;3use crate::mock::*;4use crate::{AccessMode, ApprovePermissions, CollectionMode,5 Ownership, ChainLimits, CreateItemData, CreateNftData, CreateFungibleData, CreateReFungibleData,6 CollectionId, TokenId, MAX_DECIMAL_POINTS};7use frame_support::{assert_noop, assert_ok};8use frame_system::{ RawOrigin };910fn default_collection_numbers_limit() -> u32 {11 1012}1314fn default_limits() {15 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 16 collection_numbers_limit: default_collection_numbers_limit(),17 account_token_ownership_limit: 10,18 collections_admins_limit: 5,19 custom_data_limit: 2048,20 nft_sponsor_transfer_timeout: 15,21 fungible_sponsor_transfer_timeout: 15,22 refungible_sponsor_transfer_timeout: 15, 23 }));24}2526fn default_nft_data() -> CreateNftData {27 CreateNftData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] }28}2930fn default_fungible_data () -> CreateFungibleData {31 CreateFungibleData { }32}3334fn default_re_fungible_data () -> CreateReFungibleData {35 CreateReFungibleData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] }36}3738fn create_test_collection_for_owner(mode: &CollectionMode, owner: u64, id: CollectionId) -> CollectionId {39 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();40 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();41 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();4243 let origin1 = Origin::signed(owner);44 assert_ok!(TemplateModule::create_collection(45 origin1.clone(),46 col_name1.clone(),47 col_desc1.clone(),48 token_prefix1.clone(),49 mode.clone()50 ));5152 let saved_col_name: Vec<u16> = "Test1\0\0".encode_utf16().collect::<Vec<u16>>();53 let saved_description: Vec<u16> = "TestDescription1\0\0".encode_utf16().collect::<Vec<u16>>();54 let saved_prefix: Vec<u8> = b"token_prefix1\0\0".to_vec();55 assert_eq!(TemplateModule::collection(id).owner, owner);56 assert_eq!(TemplateModule::collection(id).name, saved_col_name);57 assert_eq!(TemplateModule::collection(id).mode, *mode);58 assert_eq!(TemplateModule::collection(id).description, saved_description);59 assert_eq!(TemplateModule::collection(id).token_prefix, saved_prefix);60 id61}6263fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {64 create_test_collection_for_owner(&mode, 1, id)65}6667fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {68 let origin1 = Origin::signed(1);69 assert_ok!(TemplateModule::create_item(70 origin1.clone(),71 collection_id,72 1,73 data.clone()74 ));7576}7778// Use cases tests region79// #region8081#[test]82fn set_version_schema() {83 new_test_ext().execute_with(|| {84 default_limits();85 let origin1 = Origin::signed(1);86 let collection_id = create_test_collection(&CollectionMode::NFT, 1);87 88 assert_ok!(TemplateModule::set_schema_version(origin1, collection_id, SchemaVersion::Unique));89 assert_eq!(TemplateModule::collection(collection_id).schema_version, SchemaVersion::Unique);90 });91}9293#[test]94fn create_fungible_collection_fails_with_large_decimal_numbers() {95 new_test_ext().execute_with(|| {96 default_limits();9798 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();99 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();100 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();101102 let origin1 = Origin::signed(1);103 assert_noop!(TemplateModule::create_collection(104 origin1,105 col_name1,106 col_desc1,107 token_prefix1,108 CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1)109 ), Error::<Test>::CollectionDecimalPointLimitExceeded);110 }); 111}112113#[test]114fn create_re_fungible_collection_fails_with_large_decimal_numbers() {115 new_test_ext().execute_with(|| {116 default_limits();117118 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();119 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();120 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();121122 let origin1 = Origin::signed(1);123 assert_noop!(TemplateModule::create_collection(124 origin1,125 col_name1,126 col_desc1,127 token_prefix1,128 CollectionMode::ReFungible(MAX_DECIMAL_POINTS + 1)129 ), Error::<Test>::CollectionDecimalPointLimitExceeded);130 });131}132133#[test]134fn create_nft_item() {135 new_test_ext().execute_with(|| {136 default_limits();137 let collection_id = create_test_collection(&CollectionMode::NFT, 1);138 139 let data = default_nft_data();140 create_test_item(collection_id, &data.clone().into());141 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).const_data, data.const_data);142 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, data.variable_data);143 });144}145146// Use cases tests region147// #region148#[test]149fn create_nft_multiple_items() {150 new_test_ext().execute_with(|| {151 default_limits();152 153 create_test_collection(&CollectionMode::NFT, 1);154155 let origin1 = Origin::signed(1);156157 let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];158159 assert_ok!(TemplateModule::create_multiple_items(160 origin1.clone(),161 1,162 1,163 items_data.clone().into_iter().map(|d| { d.into() }).collect()164 ));165 for (index, data) in items_data.iter().enumerate() {166 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).const_data.to_vec(), data.const_data);167 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).variable_data.to_vec(), data.variable_data);168 }169 });170}171172#[test]173fn create_refungible_item() {174 new_test_ext().execute_with(|| {175 default_limits();176 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);177178 let data = default_re_fungible_data();179 create_test_item(collection_id, &data.clone().into());180 assert_eq!(181 TemplateModule::refungible_item_id(collection_id, 1).const_data,182 data.const_data183 );184 assert_eq!(185 TemplateModule::refungible_item_id(collection_id, 1).variable_data,186 data.variable_data187 );188 assert_eq!(189 TemplateModule::refungible_item_id(collection_id, 1).owner[0],190 Ownership {191 owner: 1,192 fraction: 1000193 }194 );195 });196}197198#[test]199fn create_multiple_refungible_items() {200 new_test_ext().execute_with(|| {201 default_limits();202 203 create_test_collection(&CollectionMode::ReFungible(3), 1);204205 let origin1 = Origin::signed(1);206207 let items_data = vec![default_re_fungible_data(), default_re_fungible_data(), default_re_fungible_data()];208209 assert_ok!(TemplateModule::create_multiple_items(210 origin1.clone(),211 1,212 1,213 items_data.clone().into_iter().map(|d| { d.into() }).collect()214 ));215 for (index, data) in items_data.iter().enumerate() {216217 let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId);218 assert_eq!(item.const_data.to_vec(), data.const_data);219 assert_eq!(item.variable_data.to_vec(), data.variable_data);220 assert_eq!(221 item.owner[0],222 Ownership {223 owner: 1,224 fraction: 1000225 }226 );227 }228 });229}230231#[test]232fn create_fungible_item() {233 new_test_ext().execute_with(|| {234 default_limits();235 236 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);237238 let data = default_fungible_data();239 create_test_item(collection_id, &data.into());240241 assert_eq!(TemplateModule::fungible_item_id(collection_id, 1).owner, 1);242 });243}244245#[test]246fn create_multiple_fungible_items() {247 new_test_ext().execute_with(|| {248 default_limits();249250 create_test_collection(&CollectionMode::Fungible(3), 1);251252 let origin1 = Origin::signed(1);253254 let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];255256 assert_ok!(TemplateModule::create_multiple_items(257 origin1.clone(),258 1,259 1,260 items_data.clone().into_iter().map(|d| { d.into() }).collect()261 ));262 263 for (index, _) in items_data.iter().enumerate() {264 assert_eq!(TemplateModule::fungible_item_id(1, (index + 1) as TokenId).owner, 1);265 }266 assert_eq!(TemplateModule::balance_count(1, 1), 3000);267 assert_eq!(TemplateModule::address_tokens(1, 1), [1, 2, 3]);268 });269}270271#[test]272fn transfer_fungible_item() {273 new_test_ext().execute_with(|| {274 default_limits();275 276 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);277278 let origin1 = Origin::signed(1);279 let origin2 = Origin::signed(2);280281 let data = default_fungible_data();282 create_test_item(collection_id, &data.into());283284 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 1);285 assert_eq!(TemplateModule::balance_count(1, 1), 1000);286 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);287288 // change owner scenario289 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));290 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);291 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 1000);292 assert_eq!(TemplateModule::balance_count(1, 1), 0);293 assert_eq!(TemplateModule::balance_count(1, 2), 1000);294 // assert_eq!(TemplateModule::address_tokens(1, 1), []);295 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);296297 // split item scenario298 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));299 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);300 assert_eq!(TemplateModule::fungible_item_id(1, 2).owner, 3);301 assert_eq!(TemplateModule::balance_count(1, 2), 500);302 assert_eq!(TemplateModule::balance_count(1, 3), 500);303 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);304 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);305306 // split item and new owner has account scenario307 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));308 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 300);309 assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 700);310 assert_eq!(TemplateModule::balance_count(1, 2), 300);311 assert_eq!(TemplateModule::balance_count(1, 3), 700);312 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);313 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);314 });315}316317#[test]318fn transfer_refungible_item() {319 new_test_ext().execute_with(|| {320 default_limits();321 322 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);323324 let data = default_re_fungible_data();325 create_test_item(collection_id, &data.clone().into());326327 let origin1 = Origin::signed(1);328 let origin2 = Origin::signed(2);329 assert_eq!(330 TemplateModule::refungible_item_id(collection_id, 1).const_data,331 data.const_data332 );333 assert_eq!(334 TemplateModule::refungible_item_id(collection_id, 1).variable_data,335 data.variable_data336 );337 assert_eq!(338 TemplateModule::refungible_item_id(collection_id, 1).owner[0],339 Ownership {340 owner: 1,341 fraction: 1000342 }343 );344 assert_eq!(TemplateModule::balance_count(1, 1), 1000);345 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);346347 // change owner scenario348 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));349 assert_eq!(350 TemplateModule::refungible_item_id(1, 1).owner[0],351 Ownership {352 owner: 2,353 fraction: 1000354 }355 );356 assert_eq!(TemplateModule::balance_count(1, 1), 0);357 assert_eq!(TemplateModule::balance_count(1, 2), 1000);358 // assert_eq!(TemplateModule::address_tokens(1, 1), []);359 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);360361 // split item scenario362 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));363 assert_eq!(364 TemplateModule::refungible_item_id(1, 1).owner[0],365 Ownership {366 owner: 2,367 fraction: 500368 }369 );370 assert_eq!(371 TemplateModule::refungible_item_id(1, 1).owner[1],372 Ownership {373 owner: 3,374 fraction: 500375 }376 );377 assert_eq!(TemplateModule::balance_count(1, 2), 500);378 assert_eq!(TemplateModule::balance_count(1, 3), 500);379 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);380 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);381382 // split item and new owner has account scenario383 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));384 assert_eq!(385 TemplateModule::refungible_item_id(1, 1).owner[0],386 Ownership {387 owner: 2,388 fraction: 300389 }390 );391 assert_eq!(392 TemplateModule::refungible_item_id(1, 1).owner[1],393 Ownership {394 owner: 3,395 fraction: 700396 }397 );398 assert_eq!(TemplateModule::balance_count(1, 2), 300);399 assert_eq!(TemplateModule::balance_count(1, 3), 700);400 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);401 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);402 });403}404405#[test]406fn transfer_nft_item() {407 new_test_ext().execute_with(|| {408 default_limits();409 410 let collection_id = create_test_collection(&CollectionMode::NFT, 1);411412 let data = default_nft_data();413 create_test_item(collection_id, &data.into());414 assert_eq!(TemplateModule::balance_count(1, 1), 1);415 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);416417 let origin1 = Origin::signed(1);418 // default scenario419 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));420 assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2);421 assert_eq!(TemplateModule::balance_count(1, 1), 0);422 assert_eq!(TemplateModule::balance_count(1, 2), 1);423 // assert_eq!(TemplateModule::address_tokens(1, 1), []);424 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);425 });426}427428#[test]429fn nft_approve_and_transfer_from() {430 new_test_ext().execute_with(|| {431 default_limits();432 433 let collection_id = create_test_collection(&CollectionMode::NFT, 1);434435 let data = default_nft_data();436 create_test_item(collection_id, &data.into());437438 let origin1 = Origin::signed(1);439 let origin2 = Origin::signed(2);440441 assert_eq!(TemplateModule::balance_count(1, 1), 1);442 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);443444 // neg transfer445 assert_noop!(TemplateModule::transfer_from(446 origin2.clone(),447 1,448 2,449 1,450 1,451 1), Error::<Test>::NoPermission);452453 // do approve454 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));455 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);456 assert_eq!(457 TemplateModule::approved(1, (1, 1))[0],458 ApprovePermissions {459 approved: 2,460 amount: 100000000461 }462 );463464 assert_ok!(TemplateModule::transfer_from(465 origin2.clone(),466 1,467 2,468 1,469 1,470 1471 ));472 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);473 });474}475476#[test]477fn nft_approve_and_transfer_from_white_list() {478 new_test_ext().execute_with(|| {479 default_limits();480 481 let collection_id = create_test_collection(&CollectionMode::NFT, 1);482483 let origin1 = Origin::signed(1);484 let origin2 = Origin::signed(2);485486 let data = default_nft_data();487 create_test_item(collection_id, &data.clone().into());488489 assert_eq!(TemplateModule::nft_item_id(1, 1).const_data, data.const_data);490 assert_eq!(TemplateModule::balance_count(1, 1), 1);491 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);492493 assert_ok!(TemplateModule::set_mint_permission(494 origin1.clone(),495 1,496 true497 ));498 assert_ok!(TemplateModule::set_public_access_mode(499 origin1.clone(),500 1,501 AccessMode::WhiteList502 ));503 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));504 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));505 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));506507 // do approve508 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));509 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);510 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));511 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);512 assert_eq!(513 TemplateModule::approved(1, (1, 1))[0],514 ApprovePermissions {515 approved: 2,516 amount: 100000000517 }518 );519520 assert_ok!(TemplateModule::transfer_from(521 origin2.clone(),522 1,523 3,524 1,525 1,526 1527 ));528 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);529 });530}531532#[test]533fn refungible_approve_and_transfer_from() {534 new_test_ext().execute_with(|| {535 default_limits();536 537 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);538 539 let origin1 = Origin::signed(1);540 let origin2 = Origin::signed(2);541542 let data = default_re_fungible_data();543 create_test_item(collection_id, &data.into());544545 assert_eq!(TemplateModule::balance_count(1, 1), 1000);546 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);547548 assert_ok!(TemplateModule::set_mint_permission(549 origin1.clone(),550 1,551 true552 ));553 assert_ok!(TemplateModule::set_public_access_mode(554 origin1.clone(),555 1,556 AccessMode::WhiteList557 ));558 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));559 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));560 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));561562 // do approve563 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));564 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);565 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));566 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);567 assert_eq!(568 TemplateModule::approved(1, (1, 1))[0],569 ApprovePermissions {570 approved: 2,571 amount: 100000000572 }573 );574575 assert_ok!(TemplateModule::transfer_from(576 origin2.clone(),577 1,578 3,579 1,580 1,581 100582 ));583 assert_eq!(TemplateModule::balance_count(1, 1), 900);584 assert_eq!(TemplateModule::balance_count(1, 3), 100);585 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);586 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);587588 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);589 assert_eq!(590 TemplateModule::approved(1, (1, 1))[0],591 ApprovePermissions {592 approved: 3,593 amount: 100000000594 }595 );596 });597}598599#[test]600fn fungible_approve_and_transfer_from() {601 new_test_ext().execute_with(|| {602 default_limits();603 604 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);605 606 let data = default_fungible_data();607 create_test_item(collection_id, &data.into());608609 let origin1 = Origin::signed(1);610 let origin2 = Origin::signed(2);611612 assert_eq!(TemplateModule::balance_count(1, 1), 1000);613 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);614615 assert_ok!(TemplateModule::set_mint_permission(616 origin1.clone(),617 1,618 true619 ));620 assert_ok!(TemplateModule::set_public_access_mode(621 origin1.clone(),622 1,623 AccessMode::WhiteList624 ));625 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));626 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));627 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));628629 // do approve630 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));631 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);632 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));633 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);634 assert_eq!(635 TemplateModule::approved(1, (1, 1))[0],636 ApprovePermissions {637 approved: 2,638 amount: 100000000639 }640 );641642 assert_ok!(TemplateModule::transfer_from(643 origin2.clone(),644 1,645 3,646 1,647 1,648 100649 ));650 assert_eq!(TemplateModule::balance_count(1, 1), 900);651 assert_eq!(TemplateModule::balance_count(1, 3), 100);652 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);653 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);654655 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);656 assert_eq!(657 TemplateModule::approved(1, (1, 1))[0],658 ApprovePermissions {659 approved: 3,660 amount: 100000000661 }662 );663664 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));665 assert_ok!(TemplateModule::transfer_from(666 origin2.clone(),667 1,668 3,669 1,670 1,671 900672 ));673 assert_eq!(TemplateModule::balance_count(1, 1), 0);674 assert_eq!(TemplateModule::balance_count(1, 3), 1000);675 // assert_eq!(TemplateModule::address_tokens(1, 1), []);676 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);677678 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);679 });680}681682#[test]683fn change_collection_owner() {684 new_test_ext().execute_with(|| {685 default_limits();686 687 let collection_id = create_test_collection(&CollectionMode::NFT, 1);688 689 let origin1 = Origin::signed(1);690 assert_ok!(TemplateModule::change_collection_owner(691 origin1.clone(),692 collection_id,693 2694 ));695 assert_eq!(TemplateModule::collection(collection_id).owner, 2);696 });697}698699#[test]700fn destroy_collection() {701 new_test_ext().execute_with(|| {702 default_limits();703 704 let collection_id = create_test_collection(&CollectionMode::NFT, 1);705 706 let origin1 = Origin::signed(1);707 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));708 });709}710711#[test]712fn burn_nft_item() {713 new_test_ext().execute_with(|| {714 default_limits();715 716 let collection_id = create_test_collection(&CollectionMode::NFT, 1);717718 let origin1 = Origin::signed(1);719 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));720 721 let data = default_nft_data();722 create_test_item(collection_id, &data.into());723724 // check balance (collection with id = 1, user id = 1)725 assert_eq!(TemplateModule::balance_count(1, 1), 1);726727 // burn item728 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));729 assert_noop!(730 TemplateModule::burn_item(origin1.clone(), 1, 1),731 Error::<Test>::TokenNotFound732 );733734 assert_eq!(TemplateModule::balance_count(1, 1), 0);735 });736}737738#[test]739fn burn_fungible_item() {740 new_test_ext().execute_with(|| {741 default_limits();742 743 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);744 745 let origin1 = Origin::signed(1);746 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));747 748 let data = default_fungible_data();749 create_test_item(collection_id, &data.into());750751 // check balance (collection with id = 1, user id = 1)752 assert_eq!(TemplateModule::balance_count(1, 1), 1000);753754 // burn item755 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));756 assert_noop!(757 TemplateModule::burn_item(origin1.clone(), 1, 1),758 Error::<Test>::TokenNotFound759 );760761 assert_eq!(TemplateModule::balance_count(1, 1), 0);762 });763}764765#[test]766fn burn_refungible_item() {767 new_test_ext().execute_with(|| {768 default_limits();769 770 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);771 let origin1 = Origin::signed(1);772773 assert_ok!(TemplateModule::set_mint_permission(774 origin1.clone(),775 collection_id,776 true777 ));778 assert_ok!(TemplateModule::set_public_access_mode(779 origin1.clone(),780 collection_id,781 AccessMode::WhiteList782 ));783 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));784785 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));786 787 let data = default_re_fungible_data();788 create_test_item(collection_id, &data.into());789790 // check balance (collection with id = 1, user id = 2)791 assert_eq!(TemplateModule::balance_count(1, 1), 1000);792793 // burn item794 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));795 assert_noop!(796 TemplateModule::burn_item(origin1.clone(), 1, 1),797 Error::<Test>::TokenNotFound798 );799800 assert_eq!(TemplateModule::balance_count(1, 1), 0);801 });802}803804#[test]805fn add_collection_admin() {806 new_test_ext().execute_with(|| {807 default_limits();808 809 let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);810 create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);811 create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);812 813 let origin1 = Origin::signed(1);814815 // collection admin816 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));817 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));818819 assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&2), true);820 assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&3), true);821 });822}823824#[test]825fn remove_collection_admin() {826 new_test_ext().execute_with(|| {827 default_limits();828 829 let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);830 create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);831 create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);832833 let origin1 = Origin::signed(1);834 let origin2 = Origin::signed(2);835836 // collection admin837 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));838 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));839840 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);841 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);842843 // remove admin844 assert_ok!(TemplateModule::remove_collection_admin(845 origin2.clone(),846 1,847 3848 ));849 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), false);850 });851}852853#[test]854fn balance_of() {855 new_test_ext().execute_with(|| {856 default_limits();857 858 let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);859 let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);860 let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible(3), 3);861 862 // check balance before863 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);864 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);865 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 0);866867 let nft_data = default_nft_data();868 create_test_item(nft_collection_id, &nft_data.into());869 870 let fungible_data = default_fungible_data();871 create_test_item(fungible_collection_id, &fungible_data.into());872 873 let re_fungible_data = default_re_fungible_data();874 create_test_item(re_fungible_collection_id, &re_fungible_data.into());875876 // check balance (collection with id = 1, user id = 1)877 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1);878 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 1000);879 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 1000);880 assert_eq!(TemplateModule::nft_item_id(nft_collection_id, 1).owner, 1);881 assert_eq!(TemplateModule::fungible_item_id(fungible_collection_id, 1).owner, 1);882 assert_eq!(TemplateModule::refungible_item_id(re_fungible_collection_id, 1).owner[0].owner, 1);883 });884}885886#[test]887fn approve() {888 new_test_ext().execute_with(|| {889 default_limits();890 891 let collection_id = create_test_collection(&CollectionMode::NFT, 1);892 893 let data = default_nft_data();894 create_test_item(collection_id, &data.into());895896 let origin1 = Origin::signed(1);897 898 // approve899 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));900 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);901 });902}903904#[test]905fn transfer_from() {906 new_test_ext().execute_with(|| {907 default_limits();908 909 let collection_id = create_test_collection(&CollectionMode::NFT, 1);910 let origin1 = Origin::signed(1);911 let origin2 = Origin::signed(2);912913 let data = default_nft_data();914 create_test_item(collection_id, &data.into());915916 // approve917 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));918 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);919920 assert_ok!(TemplateModule::set_mint_permission(921 origin1.clone(),922 1,923 true924 ));925 assert_ok!(TemplateModule::set_public_access_mode(926 origin1.clone(),927 1,928 AccessMode::WhiteList929 ));930 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));931 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));932 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));933934 assert_ok!(TemplateModule::transfer_from(935 origin2.clone(),936 1,937 2,938 1,939 1,940 1941 ));942943 // after transfer944 assert_eq!(TemplateModule::balance_count(1, 1), 0);945 assert_eq!(TemplateModule::balance_count(1, 2), 1);946 });947}948949// #endregion950951// Coverage tests region952// #region953954#[test]955fn owner_can_add_address_to_white_list() {956 new_test_ext().execute_with(|| {957 default_limits();958 959 let collection_id = create_test_collection(&CollectionMode::NFT, 1);960961 let origin1 = Origin::signed(1);962 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));963 assert_eq!(TemplateModule::white_list(collection_id, 2), true);964 });965}966967#[test]968fn admin_can_add_address_to_white_list() {969 new_test_ext().execute_with(|| {970 default_limits();971 972 let collection_id = create_test_collection(&CollectionMode::NFT, 1);973 let origin1 = Origin::signed(1);974 let origin2 = Origin::signed(2);975976 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));977 assert_ok!(TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3));978 assert_eq!(TemplateModule::white_list(collection_id, 3), true);979 });980}981982#[test]983fn nonprivileged_user_cannot_add_address_to_white_list() {984 new_test_ext().execute_with(|| {985 default_limits();986 987 let collection_id = create_test_collection(&CollectionMode::NFT, 1);988989 let origin2 = Origin::signed(2);990 assert_noop!(991 TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3),992 Error::<Test>::NoPermission993 );994 });995}996997#[test]998fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {999 new_test_ext().execute_with(|| {1000 default_limits();10011002 let origin1 = Origin::signed(1);10031004 assert_noop!(1005 TemplateModule::add_to_white_list(origin1.clone(), 1, 2),1006 Error::<Test>::CollectionNotFound1007 );1008 });1009}10101011#[test]1012fn nobody_can_add_address_to_white_list_of_deleted_collection() {1013 new_test_ext().execute_with(|| {1014 default_limits();1015 1016 let collection_id = create_test_collection(&CollectionMode::NFT, 1);10171018 let origin1 = Origin::signed(1);1019 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1020 assert_noop!(1021 TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2),1022 Error::<Test>::CollectionNotFound1023 );1024 });1025}10261027// If address is already added to white list, nothing happens1028#[test]1029fn address_is_already_added_to_white_list() {1030 new_test_ext().execute_with(|| {1031 default_limits();1032 1033 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1034 let origin1 = Origin::signed(1);1035 1036 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1037 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1038 assert_eq!(TemplateModule::white_list(collection_id, 2), true);1039 });1040}10411042#[test]1043fn owner_can_remove_address_from_white_list() {1044 new_test_ext().execute_with(|| {1045 default_limits();1046 1047 let collection_id = create_test_collection(&CollectionMode::NFT, 1);10481049 let origin1 = Origin::signed(1);1050 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1051 assert_ok!(TemplateModule::remove_from_white_list(1052 origin1.clone(),1053 collection_id,1054 21055 ));1056 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1057 });1058}10591060#[test]1061fn admin_can_remove_address_from_white_list() {1062 new_test_ext().execute_with(|| {1063 default_limits();1064 1065 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1066 let origin1 = Origin::signed(1);1067 let origin2 = Origin::signed(2);10681069 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));10701071 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 3));1072 assert_ok!(TemplateModule::remove_from_white_list(1073 origin2.clone(),1074 collection_id,1075 31076 ));1077 assert_eq!(TemplateModule::white_list(collection_id, 3), false);1078 });1079}10801081#[test]1082fn nonprivileged_user_cannot_remove_address_from_white_list() {1083 new_test_ext().execute_with(|| {1084 default_limits();1085 1086 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1087 let origin1 = Origin::signed(1);1088 let origin2 = Origin::signed(2);10891090 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1091 assert_noop!(1092 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1093 Error::<Test>::NoPermission1094 );1095 assert_eq!(TemplateModule::white_list(collection_id, 2), true);1096 });1097}10981099#[test]1100fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1101 new_test_ext().execute_with(|| {1102 default_limits();1103 let origin1 = Origin::signed(1);11041105 assert_noop!(1106 TemplateModule::remove_from_white_list(origin1.clone(), 1, 2),1107 Error::<Test>::CollectionNotFound1108 );1109 });1110}11111112#[test]1113fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1114 new_test_ext().execute_with(|| {1115 default_limits();1116 1117 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1118 let origin1 = Origin::signed(1);1119 let origin2 = Origin::signed(2);11201121 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1122 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1123 assert_noop!(1124 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1125 Error::<Test>::CollectionNotFound1126 );1127 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1128 });1129}11301131// If address is already removed from white list, nothing happens1132#[test]1133fn address_is_already_removed_from_white_list() {1134 new_test_ext().execute_with(|| {1135 default_limits();1136 1137 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1138 let origin1 = Origin::signed(1);11391140 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1141 assert_ok!(TemplateModule::remove_from_white_list(1142 origin1.clone(),1143 collection_id,1144 21145 ));1146 assert_ok!(TemplateModule::remove_from_white_list(1147 origin1.clone(),1148 collection_id,1149 21150 ));1151 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1152 });1153}11541155// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1156#[test]1157fn white_list_test_1() {1158 new_test_ext().execute_with(|| {1159 default_limits();1160 1161 let collection_id = create_test_collection(&CollectionMode::NFT, 1);11621163 let origin1 = Origin::signed(1);1164 1165 let data = default_nft_data();1166 create_test_item(collection_id, &data.into());11671168 assert_ok!(TemplateModule::set_public_access_mode(1169 origin1.clone(),1170 collection_id,1171 AccessMode::WhiteList1172 ));1173 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));11741175 assert_noop!(1176 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1177 Error::<Test>::AddresNotInWhiteList1178 );1179 });1180}11811182#[test]1183fn white_list_test_2() {1184 new_test_ext().execute_with(|| {1185 default_limits();1186 1187 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1188 let origin1 = Origin::signed(1);1189 1190 let data = default_nft_data();1191 create_test_item(collection_id, &data.into());11921193 assert_ok!(TemplateModule::set_public_access_mode(1194 origin1.clone(),1195 collection_id,1196 AccessMode::WhiteList1197 ));1198 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1199 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));12001201 // do approve1202 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1203 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);12041205 assert_ok!(TemplateModule::remove_from_white_list(1206 origin1.clone(),1207 1,1208 11209 ));12101211 assert_noop!(1212 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1213 Error::<Test>::AddresNotInWhiteList1214 );1215 });1216}12171218// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1219#[test]1220fn white_list_test_3() {1221 new_test_ext().execute_with(|| {1222 default_limits();1223 1224 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12251226 let origin1 = Origin::signed(1);1227 1228 let data = default_nft_data();1229 create_test_item(collection_id, &data.into());12301231 assert_ok!(TemplateModule::set_public_access_mode(1232 origin1.clone(),1233 collection_id,1234 AccessMode::WhiteList1235 ));1236 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));12371238 assert_noop!(1239 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1240 Error::<Test>::AddresNotInWhiteList1241 );1242 });1243}12441245#[test]1246fn white_list_test_4() {1247 new_test_ext().execute_with(|| {1248 default_limits();1249 1250 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12511252 let origin1 = Origin::signed(1);12531254 let data = default_nft_data();1255 create_test_item(collection_id, &data.into());12561257 assert_ok!(TemplateModule::set_public_access_mode(1258 origin1.clone(),1259 collection_id,1260 AccessMode::WhiteList1261 ));1262 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1263 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));12641265 // do approve1266 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1267 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);12681269 assert_ok!(TemplateModule::remove_from_white_list(1270 origin1.clone(),1271 collection_id,1272 21273 ));12741275 assert_noop!(1276 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1277 Error::<Test>::AddresNotInWhiteList1278 );1279 });1280}12811282// If Public Access mode is set to WhiteList, tokens can’t be destroyed by a non-whitelisted address (even if it owned them before enabling WhiteList mode)1283#[test]1284fn white_list_test_5() {1285 new_test_ext().execute_with(|| {1286 default_limits();1287 1288 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12891290 let origin1 = Origin::signed(1);12911292 let data = default_nft_data();1293 create_test_item(collection_id, &data.into());12941295 assert_ok!(TemplateModule::set_public_access_mode(1296 origin1.clone(),1297 collection_id,1298 AccessMode::WhiteList1299 ));1300 assert_noop!(1301 TemplateModule::burn_item(origin1.clone(), 1, 1),1302 Error::<Test>::AddresNotInWhiteList1303 );1304 });1305}13061307// If Public Access mode is set to WhiteList, oken transfers can’t be Approved by a non-whitelisted address (see Approve method).1308#[test]1309fn white_list_test_6() {1310 new_test_ext().execute_with(|| {1311 default_limits();1312 1313 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13141315 let origin1 = Origin::signed(1);1316 assert_ok!(TemplateModule::set_public_access_mode(1317 origin1.clone(),1318 collection_id,1319 AccessMode::WhiteList1320 ));13211322 // do approve1323 assert_noop!(1324 TemplateModule::approve(origin1.clone(), 1, 1, 1),1325 Error::<Test>::AddresNotInWhiteList1326 );1327 });1328}13291330// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1331// tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1332#[test]1333fn white_list_test_7() {1334 new_test_ext().execute_with(|| {1335 default_limits();1336 1337 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13381339 let data = default_nft_data();1340 create_test_item(collection_id, &data.into());1341 1342 let origin1 = Origin::signed(1);13431344 assert_ok!(TemplateModule::set_public_access_mode(1345 origin1.clone(),1346 collection_id,1347 AccessMode::WhiteList1348 ));1349 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1350 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13511352 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1));1353 });1354}13551356#[test]1357fn white_list_test_8() {1358 new_test_ext().execute_with(|| {1359 default_limits();1360 1361 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13621363 let data = default_nft_data();1364 create_test_item(collection_id, &data.into());1365 1366 let origin1 = Origin::signed(1);13671368 assert_ok!(TemplateModule::set_public_access_mode(1369 origin1.clone(),1370 collection_id,1371 AccessMode::WhiteList1372 ));1373 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1374 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13751376 // do approve1377 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1378 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);13791380 assert_ok!(TemplateModule::transfer_from(1381 origin1.clone(),1382 1,1383 2,1384 1,1385 1,1386 11387 ));1388 });1389}13901391// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1392#[test]1393fn white_list_test_9() {1394 new_test_ext().execute_with(|| {1395 default_limits();1396 1397 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1398 let origin1 = Origin::signed(1);13991400 assert_ok!(TemplateModule::set_public_access_mode(1401 origin1.clone(),1402 collection_id,1403 AccessMode::WhiteList1404 ));1405 assert_ok!(TemplateModule::set_mint_permission(1406 origin1.clone(),1407 collection_id,1408 false1409 ));14101411 let data = default_nft_data();1412 create_test_item(collection_id, &data.into());1413 });1414}14151416// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1417#[test]1418fn white_list_test_10() {1419 new_test_ext().execute_with(|| {1420 default_limits();1421 1422 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14231424 let origin1 = Origin::signed(1);1425 let origin2 = Origin::signed(2);14261427 assert_ok!(TemplateModule::set_public_access_mode(1428 origin1.clone(),1429 collection_id,1430 AccessMode::WhiteList1431 ));1432 assert_ok!(TemplateModule::set_mint_permission(1433 origin1.clone(),1434 collection_id,1435 false1436 ));14371438 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));14391440 assert_ok!(TemplateModule::create_item(1441 origin2.clone(),1442 collection_id,1443 2,1444 default_nft_data().into()1445 ));1446 });1447}14481449// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and white listed address.1450#[test]1451fn white_list_test_11() {1452 new_test_ext().execute_with(|| {1453 default_limits();1454 1455 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14561457 let origin1 = Origin::signed(1);1458 let origin2 = Origin::signed(2);14591460 assert_ok!(TemplateModule::set_public_access_mode(1461 origin1.clone(),1462 collection_id,1463 AccessMode::WhiteList1464 ));1465 assert_ok!(TemplateModule::set_mint_permission(1466 origin1.clone(),1467 collection_id,1468 false1469 ));1470 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));14711472 assert_noop!(1473 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1474 Error::<Test>::PublicMintingNotAllowed1475 );1476 });1477}14781479// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-white listed address.1480#[test]1481fn white_list_test_12() {1482 new_test_ext().execute_with(|| {1483 default_limits();1484 1485 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14861487 let origin1 = Origin::signed(1);1488 let origin2 = Origin::signed(2);14891490 assert_ok!(TemplateModule::set_public_access_mode(1491 origin1.clone(),1492 collection_id,1493 AccessMode::WhiteList1494 ));1495 assert_ok!(TemplateModule::set_mint_permission(1496 origin1.clone(),1497 collection_id,1498 false1499 ));15001501 assert_noop!(1502 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1503 Error::<Test>::PublicMintingNotAllowed1504 );1505 });1506}15071508// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1509#[test]1510fn white_list_test_13() {1511 new_test_ext().execute_with(|| {1512 default_limits();1513 1514 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15151516 let origin1 = Origin::signed(1);15171518 assert_ok!(TemplateModule::set_public_access_mode(1519 origin1.clone(),1520 collection_id,1521 AccessMode::WhiteList1522 ));1523 assert_ok!(TemplateModule::set_mint_permission(1524 origin1.clone(),1525 collection_id,1526 true1527 ));15281529 let data = default_nft_data();1530 create_test_item(collection_id, &data.into());1531 });1532}15331534// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1535#[test]1536fn white_list_test_14() {1537 new_test_ext().execute_with(|| {1538 default_limits();1539 1540 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15411542 let origin1 = Origin::signed(1);1543 let origin2 = Origin::signed(2);15441545 assert_ok!(TemplateModule::set_public_access_mode(1546 origin1.clone(),1547 collection_id,1548 AccessMode::WhiteList1549 ));1550 assert_ok!(TemplateModule::set_mint_permission(1551 origin1.clone(),1552 collection_id,1553 true1554 ));15551556 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));15571558 assert_ok!(TemplateModule::create_item(1559 origin2.clone(),1560 1,1561 2,1562 default_nft_data().into()1563 ));1564 });1565}15661567// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-white listed address.1568#[test]1569fn white_list_test_15() {1570 new_test_ext().execute_with(|| {1571 default_limits();1572 1573 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15741575 let origin1 = Origin::signed(1);1576 let origin2 = Origin::signed(2);15771578 assert_ok!(TemplateModule::set_public_access_mode(1579 origin1.clone(),1580 collection_id,1581 AccessMode::WhiteList1582 ));1583 assert_ok!(TemplateModule::set_mint_permission(1584 origin1.clone(),1585 collection_id,1586 true1587 ));15881589 assert_noop!(1590 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1591 Error::<Test>::AddresNotInWhiteList1592 );1593 });1594}15951596// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by non-privileged and white listed address.1597#[test]1598fn white_list_test_16() {1599 new_test_ext().execute_with(|| {1600 default_limits();1601 1602 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16031604 let origin1 = Origin::signed(1);1605 let origin2 = Origin::signed(2);16061607 assert_ok!(TemplateModule::set_public_access_mode(1608 origin1.clone(),1609 collection_id,1610 AccessMode::WhiteList1611 ));1612 assert_ok!(TemplateModule::set_mint_permission(1613 origin1.clone(),1614 collection_id,1615 true1616 ));1617 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));16181619 assert_ok!(TemplateModule::create_item(1620 origin2.clone(),1621 1,1622 2,1623 default_nft_data().into()1624 ));1625 });1626}16271628// Total number of collections. Positive test1629#[test]1630fn total_number_collections_bound() {1631 new_test_ext().execute_with(|| {1632 default_limits();1633 1634 create_test_collection(&CollectionMode::NFT, 1);1635 });1636}16371638// Total number of collections. Negotive test1639#[test]1640fn total_number_collections_bound_neg() {1641 new_test_ext().execute_with(|| {1642 default_limits();16431644 let origin1 = Origin::signed(1);16451646 for i in 0..default_collection_numbers_limit() {1647 create_test_collection(&CollectionMode::NFT, i + 1);1648 }16491650 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1651 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1652 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();16531654 // 11-th collection in chain. Expects error1655 assert_noop!(TemplateModule::create_collection(1656 origin1.clone(),1657 col_name1.clone(),1658 col_desc1.clone(),1659 token_prefix1.clone(),1660 CollectionMode::NFT1661 ), Error::<Test>::TotalCollectionsLimitExceeded);1662 });1663}16641665// Owned tokens by a single address. Positive test1666#[test]1667fn owned_tokens_bound() {1668 new_test_ext().execute_with(|| {1669 default_limits();1670 1671 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16721673 let data = default_nft_data();1674 create_test_item(collection_id, &data.clone().into());1675 create_test_item(collection_id, &data.into());1676 });1677}16781679// Owned tokens by a single address. Negotive test1680#[test]1681fn owned_tokens_bound_neg() {1682 new_test_ext().execute_with(|| {1683 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1684 collection_numbers_limit: 10,1685 account_token_ownership_limit: 1,1686 collections_admins_limit: 5,1687 custom_data_limit: 2048,1688 nft_sponsor_transfer_timeout: 15,1689 fungible_sponsor_transfer_timeout: 15,1690 refungible_sponsor_transfer_timeout: 15, 1691 }));1692 1693 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16941695 let origin1 = Origin::signed(1);1696 let data = default_nft_data();1697 create_test_item(collection_id, &data.clone().into());16981699 assert_noop!(TemplateModule::create_item(1700 origin1.clone(),1701 1,1702 1,1703 data.into()1704 ), Error::<Test>::AddressOwnershipLimitExceeded);1705 });1706}17071708// Number of collection admins. Positive test1709#[test]1710fn collection_admins_bound() {1711 new_test_ext().execute_with(|| {1712 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1713 collection_numbers_limit: 10,1714 account_token_ownership_limit: 10,1715 collections_admins_limit: 2,1716 custom_data_limit: 2048,1717 nft_sponsor_transfer_timeout: 15,1718 fungible_sponsor_transfer_timeout: 15,1719 refungible_sponsor_transfer_timeout: 15, 1720 }));1721 1722 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17231724 let origin1 = Origin::signed(1);1725 1726 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1727 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3));1728 });1729}17301731// Number of collection admins. Negotive test1732#[test]1733fn collection_admins_bound_neg() {1734 new_test_ext().execute_with(|| {1735 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1736 collection_numbers_limit: 10,1737 account_token_ownership_limit: 1,1738 collections_admins_limit: 1,1739 custom_data_limit: 2048,1740 nft_sponsor_transfer_timeout: 15,1741 fungible_sponsor_transfer_timeout: 15,1742 refungible_sponsor_transfer_timeout: 15, 1743 }));1744 1745 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17461747 let origin1 = Origin::signed(1);17481749 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1750 assert_noop!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3), Error::<Test>::CollectionAdminsLimitExceeded);1751 });1752}17531754// NFT custom data size. Negative test const_data.1755#[test]1756fn custom_data_size_nft_const_data_bound_neg() {1757 new_test_ext().execute_with(|| {1758 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1759 collection_numbers_limit: 10,1760 account_token_ownership_limit: 10,1761 collections_admins_limit: 5,1762 custom_data_limit: 2,1763 nft_sponsor_transfer_timeout: 15,1764 fungible_sponsor_transfer_timeout: 15,1765 refungible_sponsor_transfer_timeout: 15, 1766 }));1767 1768 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17691770 let origin1 = Origin::signed(1);1771 let too_big_const_data = CreateItemData::NFT(CreateNftData{1772 const_data: vec![1, 2, 3, 4],1773 variable_data: vec![]1774 });17751776 assert_noop!(TemplateModule::create_item(1777 origin1.clone(),1778 collection_id,1779 1,1780 too_big_const_data1781 ), Error::<Test>::TokenConstDataLimitExceeded);1782 });1783}17841785// NFT custom data size. Negative test variable_data.1786#[test]1787fn custom_data_size_nft_variable_data_bound_neg() {1788 new_test_ext().execute_with(|| {1789 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1790 collection_numbers_limit: 10,1791 account_token_ownership_limit: 10,1792 collections_admins_limit: 5,1793 custom_data_limit: 2,1794 nft_sponsor_transfer_timeout: 15,1795 fungible_sponsor_transfer_timeout: 15,1796 refungible_sponsor_transfer_timeout: 15, 1797 }));17981799 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18001801 let origin1 = Origin::signed(1);1802 let too_big_const_data = CreateItemData::NFT(CreateNftData{1803 const_data: vec![],1804 variable_data: vec![1, 2, 3, 4]1805 });18061807 assert_noop!(TemplateModule::create_item(1808 origin1.clone(),1809 collection_id,1810 1,1811 too_big_const_data1812 ), Error::<Test>::TokenVariableDataLimitExceeded);1813 });1814}18151816// Re fungible custom data size. Negative test const_data.1817#[test]1818fn custom_data_size_re_fungible_const_data_bound_neg() {1819 new_test_ext().execute_with(|| {1820 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1821 collection_numbers_limit: 10,1822 account_token_ownership_limit: 10,1823 collections_admins_limit: 5,1824 custom_data_limit: 2,1825 nft_sponsor_transfer_timeout: 15,1826 fungible_sponsor_transfer_timeout: 15,1827 refungible_sponsor_transfer_timeout: 15, 1828 }));18291830 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18311832 let origin1 = Origin::signed(1);1833 let too_big_const_data = CreateItemData::NFT(CreateNftData{1834 const_data: vec![1, 2, 3, 4],1835 variable_data: vec![]1836 });18371838 assert_noop!(TemplateModule::create_item(1839 origin1.clone(),1840 collection_id,1841 1,1842 too_big_const_data1843 ), Error::<Test>::TokenConstDataLimitExceeded);1844 });1845}18461847// Re fungible custom data size. Negative test variable_data.1848#[test]1849fn custom_data_size_re_fungible_variable_data_bound_neg() {1850 new_test_ext().execute_with(|| {1851 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1852 collection_numbers_limit: 10,1853 account_token_ownership_limit: 10,1854 collections_admins_limit: 5,1855 custom_data_limit: 2,1856 nft_sponsor_transfer_timeout: 15,1857 fungible_sponsor_transfer_timeout: 15,1858 refungible_sponsor_transfer_timeout: 15, 1859 }));18601861 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18621863 let origin1 = Origin::signed(1);1864 let too_big_const_data = CreateItemData::NFT(CreateNftData{1865 const_data: vec![],1866 variable_data: vec![1, 2, 3, 4]1867 });18681869 assert_noop!(TemplateModule::create_item(1870 origin1.clone(),1871 collection_id,1872 1,1873 too_big_const_data1874 ), Error::<Test>::TokenVariableDataLimitExceeded);1875 });1876}1877// #endregion18781879#[test]1880fn set_const_on_chain_schema() {1881 new_test_ext().execute_with(|| {1882 default_limits();18831884 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18851886 let origin1 = Origin::signed(1);1887 assert_ok!(TemplateModule::set_const_on_chain_schema(origin1, collection_id, b"test const on chain schema".to_vec()));18881889 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"test const on chain schema".to_vec());1890 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"".to_vec());1891 });1892}18931894#[test]1895fn set_variable_on_chain_schema() {1896 new_test_ext().execute_with(|| {1897 default_limits();1898 1899 let collection_id = create_test_collection(&CollectionMode::NFT, 1);19001901 let origin1 = Origin::signed(1);1902 assert_ok!(TemplateModule::set_variable_on_chain_schema(origin1, collection_id, b"test variable on chain schema".to_vec()));19031904 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"".to_vec());1905 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"test variable on chain schema".to_vec());1906 });1907}19081909#[test]1910fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {1911 new_test_ext().execute_with(|| {1912 default_limits();19131914 let collection_id = create_test_collection(&CollectionMode::NFT, 1);19151916 let origin1 = Origin::signed(1);1917 1918 let data = default_nft_data();1919 create_test_item(1, &data.into());1920 1921 let variable_data = b"test set_variable_meta_data method.".to_vec();1922 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));19231924 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, variable_data);1925 });1926}19271928#[test]1929fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {1930 new_test_ext().execute_with(|| {1931 default_limits();19321933 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);19341935 let origin1 = Origin::signed(1);19361937 let data = default_re_fungible_data();1938 create_test_item(1, &data.into());19391940 let variable_data = b"test set_variable_meta_data method.".to_vec();1941 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));19421943 assert_eq!(TemplateModule::refungible_item_id(collection_id, 1).variable_data, variable_data);1944 });1945}194619471948#[test]1949fn set_variable_meta_data_on_fungible_token_fails() {1950 new_test_ext().execute_with(|| {1951 default_limits();19521953 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);19541955 let origin1 = Origin::signed(1);19561957 let data = default_fungible_data();1958 create_test_item(1, &data.into());19591960 let variable_data = b"test set_variable_meta_data method.".to_vec();1961 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()), Error::<Test>::CantStoreMetadataInFungibleTokens);1962 });1963}19641965#[test]1966fn set_variable_meta_data_on_nft_token_fails_for_big_data() {1967 new_test_ext().execute_with(|| {1968 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1969 collection_numbers_limit: default_collection_numbers_limit(),1970 account_token_ownership_limit: 10,1971 collections_admins_limit: 5,1972 custom_data_limit: 10,1973 nft_sponsor_transfer_timeout: 15,1974 fungible_sponsor_transfer_timeout: 15,1975 refungible_sponsor_transfer_timeout: 15, 1976 }));19771978 let collection_id = create_test_collection(&CollectionMode::NFT, 1);19791980 let origin1 = Origin::signed(1);19811982 let data = default_nft_data();1983 create_test_item(1, &data.into());19841985 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1986 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);1987 });1988}19891990#[test]1991fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {1992 new_test_ext().execute_with(|| {1993 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1994 collection_numbers_limit: default_collection_numbers_limit(),1995 account_token_ownership_limit: 10,1996 collections_admins_limit: 5,1997 custom_data_limit: 10,1998 nft_sponsor_transfer_timeout: 15,1999 fungible_sponsor_transfer_timeout: 15,2000 refungible_sponsor_transfer_timeout: 15, 2001 }));200220032004 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);20052006 let origin1 = Origin::signed(1);20072008 let data = default_re_fungible_data();2009 create_test_item(1, &data.into());20102011 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();2012 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);2013 });2014}runtime/Cargo.tomldiffbeforeafterboth--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -45,6 +45,8 @@
pallet-timestamp = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
pallet-transaction-payment = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
pallet-transaction-payment-rpc-runtime-api = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
+pallet-treasury = { version = "2.0.0", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
+pallet-vesting = { version = "2.0.0", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
sp-api = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
sp-block-builder = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
sp-consensus-aura = { default-features = false, version = '0.8.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
@@ -56,8 +58,6 @@
sp-std = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
sp-transaction-pool = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
sp-version = { default-features = false, version = '2.0.0' , git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
-
-pallet-treasury = { version = "2.0.0", default-features = false, git = 'https://github.com/usetech-llc/substrate.git', branch = 'release_flexi' }
[features]
default = ['std']
@@ -90,6 +90,9 @@
'pallet-timestamp/std',
'pallet-transaction-payment/std',
'pallet-transaction-payment-rpc-runtime-api/std',
+ 'pallet-treasury/std',
+ 'pallet-vesting/std',
+
'pallet-nft/std',
'sp-api/std',
'sp-block-builder/std',
@@ -103,5 +106,4 @@
'sp-transaction-pool/std',
'sp-version/std',
- 'pallet-treasury/std',
]
runtime/src/lib.rsdiffbeforeafterboth--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]
@@ -17,7 +22,7 @@
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{
- Convert, BlakeTwo256, Block as BlockT, IdentifyAccount,
+ Convert, ConvertInto, BlakeTwo256, Block as BlockT, IdentifyAccount,
IdentityLookup, NumberFor, Saturating, Verify,
},
transaction_validity::{TransactionSource, TransactionValidity},
@@ -315,7 +320,7 @@
type Balance = Balance;
/// The ubiquitous event type.
type Event = Event;
- type DustRemoval = ();
+ type DustRemoval = Treasury;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
@@ -357,7 +362,7 @@
impl pallet_transaction_payment::Trait for Runtime {
type Currency = pallet_balances::Module<Runtime>;
- type OnTransactionPayment = ();
+ type OnTransactionPayment = Treasury;
type TransactionByteFee = TransactionByteFee;
type WeightToFee = IdentityFee<Balance>;
type FeeMultiplierUpdate = ();
@@ -412,6 +417,18 @@
type Call = Call;
}
+parameter_types! {
+ pub const MinVestedTransfer: Balance = 100 * DOLLARS;
+}
+
+impl pallet_vesting::Trait for Runtime {
+ type Event = Event;
+ type Currency = Balances;
+ type BlockNumberToBalance = ConvertInto;
+ type MinVestedTransfer = MinVestedTransfer;
+ type WeightInfo = ();
+}
+
/// Used for the module nft in `./nft.rs`
impl pallet_nft::Trait for Runtime {
type Event = Event;
@@ -435,6 +452,7 @@
Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},
Nft: pallet_nft::{Module, Call, Config<T>, Storage, Event<T>},
Treasury: pallet_treasury::{Module, Call, Storage, Config, Event<T>},
+ Vesting: pallet_vesting::{Module, Call, Config<T>, Storage, Event<T>},
}
);
runtime/src/nft_weights.rsdiffbeforeafterboth--- a/runtime/src/nft_weights.rs
+++ b/runtime/src/nft_weights.rs
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight};
pub struct WeightInfo;
@@ -108,19 +113,44 @@
.saturating_add(DbWeight::get().reads(2 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
- // fn set_chain_limits() -> Weight {
- // (0 as Weight)
- // .saturating_add(DbWeight::get().reads(1 as Weight))
- // .saturating_add(DbWeight::get().writes(1 as Weight))
- // }
fn enable_contract_sponsoring() -> Weight {
(13_000_000 as Weight)
.saturating_add(DbWeight::get().reads(1 as Weight))
.saturating_add(DbWeight::get().writes(1 as Weight))
}
- // fn set_contract_sponsoring_rate_limit() -> Weight {
- // (0 as Weight)
- // .saturating_add(DbWeight::get().reads(1 as Weight))
- // .saturating_add(DbWeight::get().writes(1 as Weight))
- // }
+ fn set_schema_version() -> Weight {
+ (8_500_000 as Weight)
+ .saturating_add(DbWeight::get().reads(2 as Weight))
+ .saturating_add(DbWeight::get().writes(1 as Weight))
+ }
+ fn set_chain_limits() -> Weight {
+ (1_300_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(1 as Weight))
+ }
+ fn set_contract_sponsoring_rate_limit() -> Weight {
+ (3_500_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(2 as Weight))
+ }
+ fn toggle_contract_white_list() -> Weight {
+ (3_000_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(2 as Weight))
+ }
+ fn add_to_contract_white_list() -> Weight {
+ (3_000_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(2 as Weight))
+ }
+ fn remove_from_contract_white_list() -> Weight {
+ (3_200_000 as Weight)
+ .saturating_add(DbWeight::get().reads(0 as Weight))
+ .saturating_add(DbWeight::get().writes(2 as Weight))
+ }
+ fn set_collection_limits() -> Weight {
+ (8_900_000 as Weight)
+ .saturating_add(DbWeight::get().reads(2 as Weight))
+ .saturating_add(DbWeight::get().writes(1 as Weight))
+ }
}
runtime_types.jsondiffbeforeafterboth--- a/runtime_types.json
+++ b/runtime_types.json
@@ -42,18 +42,14 @@
"Fraction": "u128"
},
"FungibleItemType": {
- "Collection": "CollectionId",
- "Owner": "AccountId",
"Value": "u128"
},
"NftItemType": {
- "Collection": "CollectionId",
"Owner": "AccountId",
"ConstData": "Vec<u8>",
"VariableData": "Vec<u8>"
},
"ReFungibleItemType": {
- "Collection": "CollectionId",
"Owner": "Vec<Ownership<AccountId>>",
"ConstData": "Vec<u8>",
"VariableData": "Vec<u8>"
@@ -70,14 +66,10 @@
"OffchainSchema": "Vec<u8>",
"SchemaVersion": "SchemaVersion",
"Sponsor": "AccountId",
- "UnconfirmedSponsor": "AccountId",
+ "SponsorConfirmed": "bool",
"Limits": "CollectionLimits",
"VariableOnChainSchema": "Vec<u8>",
"ConstOnChainSchema": "Vec<u8>"
- },
- "ApprovePermissions": {
- "Approved": "AccountId",
- "Amount": "u128"
},
"RawData": "Vec<u8>",
"Address": "AccountId",
@@ -87,7 +79,9 @@
"const_data": "Vec<u8>",
"variable_data": "Vec<u8>"
},
- "CreateFungibleData": {},
+ "CreateFungibleData": {
+ "value": "u128"
+ },
"CreateReFungibleData": {
"const_data": "Vec<u8>",
"variable_data": "Vec<u8>"
@@ -107,10 +101,6 @@
},
"CollectionId": "u32",
"TokenId": "u32",
- "BasketItem": {
- "Address": "AccountId",
- "start_block": "BlockNumber"
- },
"ChainLimits": {
"collection_numbers_limit": "u32",
"account_token_ownership_limit": "u32",
tests/READMEdiffbeforeafterboth--- a/tests/README
+++ /dev/null
@@ -1,12 +0,0 @@
-# Tests
-
-## How to run
-
-1. Run `npm install`.
-2. Setup a test node. You can do it using `docker-compose up -d` in parent directory.
-3. Configure tests with env variables or by editing [configuration file](src/config.ts).
-4. Run `npm run test`.
-
-## Don't run on the same node twice
-
-Some tests fail when ran on the same blockchain node twice. Either always use a new node or purge the existing one with `nft purge-chain --dev`. There is also [a script](../purge-running-node.sh) to purge and restart a node, started with docker-compose.
tests/README.mddiffbeforeafterboth--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,9 @@
+# Tests
+
+## How to run
+
+1. Run `npm install`.
+2. Setup a test node. You can do it using `docker-compose up -d` in parent directory.
+3. Optional step - configure tests with env variables or by editing [configuration file](src/config.ts).
+4. Run `npm test`.
+
tests/loadtester-src/.gitignorediffbeforeafterboth--- /dev/null
+++ b/tests/loadtester-src/.gitignore
@@ -0,0 +1,9 @@
+# Ignore build artifacts from the local tests sub-crate.
+/target/
+
+# Ignore backup files creates by cargo fmt.
+**/*.rs.bk
+
+# Remove Cargo.lock when creating an executable, leave it for libraries
+# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
+Cargo.lock
\ No newline at end of file
tests/loadtester-src/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/tests/loadtester-src/Cargo.toml
@@ -0,0 +1,36 @@
+[package]
+name = "loadtester"
+version = "0.1.0"
+authors = ["[your_name] <[your_email]>"]
+edition = "2018"
+
+[dependencies]
+ink_primitives = { version = "3.0.0-rc2", default-features = false }
+ink_metadata = { version = "3.0.0-rc2", default-features = false, features = ["derive"], optional = true }
+ink_env = { version = "3.0.0-rc2", default-features = false }
+ink_storage = { version = "3.0.0-rc2", default-features = false }
+ink_lang = { version = "3.0.0-rc2", default-features = false }
+ink_prelude = { version = "3.0.0-rc2", default-features = false }
+
+scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] }
+scale-info = { version = "0.4.1", default-features = false, features = ["derive"], optional = true }
+
+[lib]
+name = "loadtester"
+path = "lib.rs"
+crate-type = [
+ # Used for normal contract Wasm blobs.
+ "cdylib",
+]
+
+[features]
+default = ["std"]
+std = [
+ "ink_metadata/std",
+ "ink_env/std",
+ "ink_storage/std",
+ "ink_primitives/std",
+ "scale/std",
+ "scale-info/std",
+]
+ink-as-dependency = []
tests/loadtester-src/lib.rsdiffbeforeafterboth--- /dev/null
+++ b/tests/loadtester-src/lib.rs
@@ -0,0 +1,53 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use ink_lang as ink;
+
+#[ink::contract]
+mod loadtester {
+ use ink_storage::collections::Vec as InkVec;
+
+ #[ink(storage)]
+ pub struct LoadTester {
+ vector: InkVec<u64>,
+ }
+
+ impl LoadTester {
+ #[ink(constructor)]
+ pub fn new() -> Self {
+ Self {
+ vector: InkVec::new(),
+ }
+ }
+
+ #[ink(message)]
+ pub fn bloat(&mut self, count: u64){
+ for i in 1..count+1 {
+ self.vector.push(i);
+ }
+ }
+
+ #[ink(message)]
+ pub fn get(&self) -> u128 {
+ let mut sum: u128 = 0;
+ for num in self.vector.iter() {
+ sum += *num as u128;
+ }
+ sum
+ }
+ }
+
+ #[cfg(test)]
+ mod tests {
+
+ use super::*;
+
+ #[test]
+ fn it_works() {
+ let mut lt = LoadTester::new();
+ lt.bloat(4);
+ assert_eq!(lt.get(), [1,2,3,4]);
+ lt.bloat(3);
+ assert_eq!(lt.get(), [1,2,3,4,1,2,3]);
+ }
+ }
+}
tests/package-lock.jsondiffbeforeafterboth--- a/tests/package-lock.json
+++ b/tests/package-lock.json
@@ -13,13 +13,12 @@
"@polkadot/api-contract": "^2.3.1",
"@polkadot/types": "^2.3.1",
"@polkadot/util": "^3.4.1",
- "@types/bn.js": "^4.11.6",
+ "bignumber.js": "^9.0.0",
"chai-as-promised": "^7.1.1"
},
"devDependencies": {
"@polkadot/dev": "^0.52.11",
"@polkadot/ts": "^0.3.41",
- "@types/bn.js": "^4.11.6",
"@types/chai": "^4.2.12",
"@types/chai-as-promised": "^7.1.3",
"@types/mocha": "^8.0.3",
@@ -7114,6 +7113,14 @@
"node": "*"
}
},
+ "node_modules/bignumber.js": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz",
+ "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/binary-extensions": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
@@ -34960,6 +34967,11 @@
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true
},
+ "bignumber.js": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz",
+ "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA=="
+ },
"binary-extensions": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -6,7 +6,6 @@
"devDependencies": {
"@polkadot/dev": "^0.52.11",
"@polkadot/ts": "^0.3.41",
- "@types/bn.js": "^4.11.6",
"@types/chai": "^4.2.12",
"@types/chai-as-promised": "^7.1.3",
"@types/mocha": "^8.0.3",
@@ -17,7 +16,8 @@
"typescript": "^3.9.7"
},
"scripts": {
- "test": "mocha --timeout 9999999 -r ts-node/register ./**/*.test.ts"
+ "test": "mocha --timeout 9999999 -r ts-node/register ./**/*.test.ts",
+ "load": "mocha --timeout 9999999 -r ts-node/register ./**/*.load.ts"
},
"author": "",
"license": "Apache 2.0",
@@ -27,7 +27,7 @@
"@polkadot/api-contract": "^2.3.1",
"@polkadot/types": "^2.3.1",
"@polkadot/util": "^3.4.1",
- "@types/bn.js": "^4.11.6",
+ "bignumber.js": "^9.0.0",
"chai-as-promised": "^7.1.1"
},
"standard": {
tests/src/accounts.tsdiffbeforeafterboth--- a/tests/src/accounts.ts
+++ b/tests/src/accounts.ts
@@ -1,2 +1,9 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
export const bobsPublicKey = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty';
export const alicesPublicKey = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
+export const ferdiesPublicKey = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL';
+export const nullPublicKey = '5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM';
\ No newline at end of file
tests/src/blocks-production.test.tsdiffbeforeafterboth--- a/tests/src/blocks-production.test.ts
+++ b/tests/src/blocks-production.test.ts
@@ -1,8 +1,13 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import usingApi from "./substrate/substrate-api";
import promisifySubstrate from "./substrate/promisify-substrate";
import { expect } from "chai";
-describe('Blocks Production', () => {
+describe('Blocks Production smoke test', () => {
it('Node produces new blocks', async () => {
await usingApi(async api => {
const blocksPromise = promisifySubstrate(api, () => {
tests/src/config.tsdiffbeforeafterboth--- a/tests/src/config.ts
+++ b/tests/src/config.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import process from 'process';
const config = {
tests/src/confirmSponsorship.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/confirmSponsorship.test.ts
@@ -0,0 +1,350 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api";
+import {
+ createCollectionExpectSuccess,
+ setCollectionSponsorExpectSuccess,
+ destroyCollectionExpectSuccess,
+ setCollectionSponsorExpectFailure,
+ confirmSponsorshipExpectSuccess,
+ confirmSponsorshipExpectFailure,
+ createItemExpectSuccess,
+ findUnusedAddress,
+ getGenericResult,
+ enableWhiteListExpectSuccess,
+ enablePublicMintingExpectSuccess,
+ addToWhiteListExpectSuccess,
+} from "./util/helpers";
+import { Keyring } from "@polkadot/api";
+import { IKeyringPair } from "@polkadot/types/types";
+import type { AccountId } from '@polkadot/types/interfaces';
+import { BigNumber } from 'bignumber.js';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+let alice: IKeyringPair;
+let bob: IKeyringPair;
+let charlie: IKeyringPair;
+
+describe('integration test: ext. confirmSponsorship():', () => {
+
+ before(async () => {
+ await usingApi(async (api) => {
+ const keyring = new Keyring({ type: 'sr25519' });
+ alice = keyring.addFromUri(`//Alice`);
+ bob = keyring.addFromUri(`//Bob`);
+ charlie = keyring.addFromUri(`//Charlie`);
+ });
+ });
+
+ it('Confirm collection sponsorship', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+ });
+ it('Add sponsor to a collection after the same sponsor was already added and confirmed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ });
+ it('Add new sponsor to a collection after another sponsor was already added and confirmed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+ await setCollectionSponsorExpectSuccess(collectionId, charlie.address);
+ });
+
+ it('NFT: Transfer fees are paid by the sponsor after confirmation', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+
+ await usingApi(async (api) => {
+ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ // Find unused address
+ const zeroBalance = await findUnusedAddress(api);
+
+ // Mint token for unused address
+ const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);
+
+ // Transfer this tokens from unused address to Alice
+ const zeroToAlice = api.tx.nft.transfer(zeroBalance.address, collectionId, itemId, 0);
+ const events = await submitTransactionAsync(zeroBalance, zeroToAlice);
+ const result = getGenericResult(events);
+
+ const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ expect(result.success).to.be.true;
+ expect(BsponsorBalance.lt(AsponsorBalance)).to.be.true;
+ });
+
+ });
+
+ it('Fungible: Transfer fees are paid by the sponsor after confirmation', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'Fungible');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+
+ await usingApi(async (api) => {
+ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ // Find unused address
+ const zeroBalance = await findUnusedAddress(api);
+
+ // Mint token for unused address
+ const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);
+
+ // Transfer this tokens from unused address to Alice
+ const zeroToAlice = api.tx.nft.transfer(zeroBalance.address, collectionId, itemId, 1);
+ const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);
+ const result1 = getGenericResult(events1);
+
+ const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ expect(result1.success).to.be.true;
+ expect(BsponsorBalance.lt(AsponsorBalance)).to.be.true;
+ });
+ });
+
+ it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'ReFungible');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+
+ await usingApi(async (api) => {
+ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ // Find unused address
+ const zeroBalance = await findUnusedAddress(api);
+
+ // Mint token for unused address
+ const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', zeroBalance.address);
+
+ // Transfer this tokens from unused address to Alice
+ const zeroToAlice = api.tx.nft.transfer(zeroBalance.address, collectionId, itemId, 1);
+ const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);
+ const result1 = getGenericResult(events1);
+
+ const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ expect(result1.success).to.be.true;
+ expect(BsponsorBalance.lt(AsponsorBalance)).to.be.true;
+ });
+ });
+
+ it('CreateItem fees are paid by the sponsor after confirmation', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+
+ // Enable collection white list
+ await enableWhiteListExpectSuccess(alice, collectionId);
+
+ // Enable public minting
+ await enablePublicMintingExpectSuccess(alice, collectionId);
+
+ // Create Item
+ await usingApi(async (api) => {
+ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ // Find unused address
+ const zeroBalance = await findUnusedAddress(api);
+
+ // Add zeroBalance address to white list
+ await addToWhiteListExpectSuccess(alice, collectionId, zeroBalance.address);
+
+ // Mint token using unused address as signer
+ const tokenId = await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
+
+ const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ expect(BsponsorBalance.lt(AsponsorBalance)).to.be.true;
+ });
+ });
+
+ it('NFT: Sponsoring is rate limited', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+
+ await usingApi(async (api) => {
+ // Find unused address
+ const zeroBalance = await findUnusedAddress(api);
+
+ // Mint token for alice
+ const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
+
+ // Transfer this token from Alice to unused address and back
+ // Alice to Zero gets sponsored
+ const aliceToZero = api.tx.nft.transfer(zeroBalance.address, collectionId, itemId, 0);
+ const events1 = await submitTransactionAsync(alice, aliceToZero);
+ const result1 = getGenericResult(events1);
+
+ // Second transfer should fail
+ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+ const zeroToAlice = api.tx.nft.transfer(alice.address, collectionId, itemId, 0);
+ const badTransaction = async function () {
+ console.log = function () {};
+ console.error = function () {};
+ await submitTransactionAsync(zeroBalance, zeroToAlice);
+ delete console.log;
+ delete console.error;
+ };
+ await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees");
+ const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ // Try again after Zero gets some balance - now it should succeed
+ const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);
+ await submitTransactionAsync(alice, balancetx);
+ const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);
+ const result2 = getGenericResult(events2);
+
+ expect(result1.success).to.be.true;
+ expect(result2.success).to.be.true;
+ expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;
+ });
+ });
+
+ it('Fungible: Sponsoring is rate limited', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'Fungible');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+
+ await usingApi(async (api) => {
+ // Find unused address
+ const zeroBalance = await findUnusedAddress(api);
+
+ // Mint token for unused address
+ const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);
+
+ // Transfer this tokens in parts from unused address to Alice
+ const zeroToAlice = api.tx.nft.transfer(zeroBalance.address, collectionId, itemId, 1);
+ const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);
+ const result1 = getGenericResult(events1);
+
+ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ const badTransaction = async function () {
+ console.log = function () {};
+ console.error = function () {};
+ await submitTransactionAsync(zeroBalance, zeroToAlice);
+ delete console.log;
+ delete console.error;
+ };
+
+ const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ // Try again after Zero gets some balance - now it should succeed
+ const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);
+ await submitTransactionAsync(alice, balancetx);
+ const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);
+ const result2 = getGenericResult(events2);
+
+ expect(result1.success).to.be.true;
+ expect(result2.success).to.be.true;
+ expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;
+ });
+ });
+
+ it('ReFungible: Sponsoring is rate limited', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'ReFungible');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+
+ await usingApi(async (api) => {
+ // Find unused address
+ const zeroBalance = await findUnusedAddress(api);
+
+ // Mint token for alice
+ const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', alice.address);
+
+ // Transfer this token from Alice to unused address and back
+ // Alice to Zero gets sponsored
+ const aliceToZero = api.tx.nft.transfer(zeroBalance.address, collectionId, itemId, 1);
+ const events1 = await submitTransactionAsync(alice, aliceToZero);
+ const result1 = getGenericResult(events1);
+
+ // Second transfer should fail
+ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+ const zeroToAlice = api.tx.nft.transfer(alice.address, collectionId, itemId, 1);
+ const badTransaction = async function () {
+ console.log = function () {};
+ console.error = function () {};
+ await submitTransactionAsync(zeroBalance, zeroToAlice);
+ delete console.log;
+ delete console.error;
+ };
+ await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees");
+ const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ // Try again after Zero gets some balance - now it should succeed
+ const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15);
+ await submitTransactionAsync(alice, balancetx);
+ const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);
+ const result2 = getGenericResult(events2);
+
+ expect(result1.success).to.be.true;
+ expect(result2.success).to.be.true;
+ expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;
+ });
+ });
+
+});
+
+describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {
+ before(async () => {
+ await usingApi(async (api) => {
+ const keyring = new Keyring({ type: 'sr25519' });
+ alice = keyring.addFromUri(`//Alice`);
+ bob = keyring.addFromUri(`//Bob`);
+ charlie = keyring.addFromUri(`//Charlie`);
+ });
+ });
+
+ it('(!negative test!) Confirm sponsorship for a collection that never existed', async () => {
+ // Find the collection that never existed
+ const collectionId = 0;
+ await usingApi(async (api) => {
+ const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;
+ });
+
+ await confirmSponsorshipExpectFailure(collectionId, '//Bob');
+ });
+
+ it('(!negative test!) Confirm sponsorship using a non-sponsor address', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+
+ await usingApi(async (api) => {
+ const transfer = api.tx.balances.transfer(charlie.address, 1e15);
+ await submitTransactionAsync(alice, transfer);
+ });
+
+ await confirmSponsorshipExpectFailure(collectionId, '//Charlie');
+ });
+
+ it('(!negative test!) Confirm sponsorship using owner address', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectFailure(collectionId, '//Alice');
+ });
+
+ it('(!negative test!) Confirm sponsorship without sponsor being set with setCollectionSponsor', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await confirmSponsorshipExpectFailure(collectionId, '//Bob');
+ });
+
+ it('(!negative test!) Confirm sponsorship in a collection that was destroyed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await destroyCollectionExpectSuccess(collectionId);
+ await confirmSponsorshipExpectFailure(collectionId, '//Bob');
+ });
+});
tests/src/connection.test.tsdiffbeforeafterboth--- a/tests/src/connection.test.ts
+++ b/tests/src/connection.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import usingApi from "./substrate/substrate-api";
import { WsProvider } from '@polkadot/api';
import * as chai from 'chai';
@@ -7,7 +12,7 @@
const expect = chai.expect;
-describe('Connection', () => {
+describe('Connection smoke test', () => {
it('Connection can be established', async () => {
await usingApi(async api => {
const health = await api.rpc.system.health();
@@ -16,11 +21,17 @@
});
it('Cannot connect to 255.255.255.255', async () => {
+ console.log = function () {};
+ console.error = function () {};
+
const neverConnectProvider = new WsProvider('ws://255.255.255.255:9944');
await expect((async () => {
await usingApi(async api => {
const health = await api.rpc.system.health();
}, { provider: neverConnectProvider });
})()).to.be.eventually.rejected;
+
+ delete console.log;
+ delete console.error;
});
});
\ No newline at end of file
tests/src/contracts.test.tsdiffbeforeafterboth--- a/tests/src/contracts.test.ts
+++ b/tests/src/contracts.test.ts
@@ -1,17 +1,25 @@
-import { expect } from "chai";
-import usingApi from "./substrate/substrate-api";
+import chai from "chai";
+import chaiAsPromised from 'chai-as-promised';
+import usingApi, { submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api";
import fs from "fs";
-import { Abi, BlueprintPromise, CodePromise, ContractPromise } from "@polkadot/api-contract";
+import { Abi, BlueprintPromise as Blueprint, CodePromise, ContractPromise as Contract } from "@polkadot/api-contract";
import { IKeyringPair } from "@polkadot/types/types";
-import { Keyring } from "@polkadot/api";
+import { ApiPromise, Keyring } from "@polkadot/api";
import { ApiTypes, SubmittableExtrinsic } from "@polkadot/api/types";
+import privateKey from "./substrate/privateKey";
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+import { BigNumber } from 'bignumber.js';
+import { findUnusedAddress } from './util/helpers'
+
const value = 0;
const gasLimit = 3000n * 1000000n;
+const endowment = `1000000000000000`;
const marketContractAddress = '5CYN9j3YvRkqxewoxeSvRbhAym4465C57uMmX5j4yz99L5H6';
-function deployBlueprint(alice: IKeyringPair, code: CodePromise): Promise<BlueprintPromise> {
- return new Promise<BlueprintPromise>(async (resolve, reject) => {
+function deployBlueprint(alice: IKeyringPair, code: CodePromise): Promise<Blueprint> {
+ return new Promise<Blueprint>(async (resolve, reject) => {
const unsub = await code
.createBlueprint()
.signAndSend(alice, (result) => {
@@ -24,7 +32,7 @@
});
}
-function deployContract(alice: IKeyringPair, blueprint: BlueprintPromise) : Promise<any> {
+function deployContract(alice: IKeyringPair, blueprint: Blueprint) : Promise<any> {
return new Promise<any>(async (resolve, reject) => {
const endowment = 1000000000000000n;
const initValue = true;
@@ -40,57 +48,127 @@
});
}
-function runTransaction(privateKey: IKeyringPair, extrinsic: SubmittableExtrinsic<ApiTypes>) {
- return new Promise<void>(async (resolve, reject) => {
- extrinsic.signAndSend(privateKey, async result => {
- if(!result.isInBlock) {
- return;
- }
+async function prepareDeployer(api: ApiPromise) {
+ // Find unused address
+ const deployer = await findUnusedAddress(api);
- if(result.findRecord('system', 'ExtrinsicSuccess')) {
- resolve();
- }
- else {
- reject('Failed to flip value.');
- }
- })
- });
+ // Transfer balance to it
+ const keyring = new Keyring({ type: 'sr25519' });
+ const alice = keyring.addFromUri(`//Alice`);
+ let amount = new BigNumber(endowment);
+ amount = amount.plus(1e15);
+ const tx = api.tx.balances.transfer(deployer.address, amount.toFixed());
+ await submitTransactionAsync(alice, tx);
+
+ return deployer;
}
+async function deployFlipper(api: ApiPromise): Promise<[Contract, IKeyringPair]> {
+ const metadata = JSON.parse(fs.readFileSync('./src/flipper/metadata.json').toString('utf-8'));
+ const abi = new Abi(metadata);
+
+ const deployer = await prepareDeployer(api);
+
+ const wasm = fs.readFileSync('./src/flipper/flipper.wasm');
+
+ const code = new CodePromise(api, abi, wasm);
+
+ const blueprint = await deployBlueprint(deployer, code);
+ const contract = (await deployContract(deployer, blueprint))['contract'] as Contract;
+
+ const initialGetResponse = await getFlipValue(contract, deployer);
+ expect(initialGetResponse).to.be.true;
+
+ return [contract, deployer];
+}
+
+async function getFlipValue(contract: Contract, deployer: IKeyringPair) {
+ const result = await contract.query.get(deployer.address, value, gasLimit);
+
+ if(!result.result.isSuccess) {
+ throw `Failed to get flipper value`;
+ }
+ return (result.result.asSuccess.data[0] == 0x00) ? false : true;
+}
+
describe('Contracts', () => {
it(`Can deploy smart contract Flipper, instantiate it and call it's get and flip messages.`, async () => {
await usingApi(async api => {
- const keyring = new Keyring({ type: 'sr25519' });
- const alice = keyring.addFromUri("//Alice");
-
- const wasm = fs.readFileSync('./src/flipper/flipper.wasm');
-
- const metadata = JSON.parse(fs.readFileSync('./src/flipper/metadata.json').toString('utf-8'));
- const abi = new Abi(metadata);
+ const [contract, deployer] = await deployFlipper(api);
+ const initialGetResponse = await getFlipValue(contract, deployer);
- const code = new CodePromise(api, abi, wasm);
+ const bob = privateKey("//Bob");
+ const flip = contract.exec('flip', value, gasLimit);
+ await submitTransactionAsync(bob, flip);
- const blueprint = await deployBlueprint(alice, code);
- const contract = (await deployContract(alice, blueprint))['contract'];
+ const afterFlipGetResponse = await getFlipValue(contract, deployer);
+ expect(afterFlipGetResponse).not.to.be.eq(initialGetResponse, 'Flipping should change value.');
+ });
+ });
- const getFlipValue = async () => {
- const result = await contract.query.get(alice.address, value, gasLimit);
+ it(`Whitelisted account can call contract.`, async () => {
+ await usingApi(async api => {
+ const bob = privateKey("//Bob");
- if(!result.result.isSuccess) {
- throw `Failed to get flipper value`;
- }
- return (result.result.asSuccess.data[0] == 0x00) ? false : true;
- }
+ const [contract, deployer] = await deployFlipper(api);
+ const consoleError = console.error;
+ console.error = (...data: any[]) => {
+ };
- const initialGetResponse = await getFlipValue();
- expect(initialGetResponse).to.be.true;
+ let expectedFlipValue = await getFlipValue(contract, deployer);
const flip = contract.exec('flip', value, gasLimit);
- await runTransaction(alice, flip);
+ await submitTransactionAsync(bob, flip);
+ expectedFlipValue = !expectedFlipValue;
+ const afterFlip = await getFlipValue(contract,deployer);
+ expect(afterFlip).to.be.eq(expectedFlipValue, `Anyone can call new contract.`);
- const afterFlipGetResponse = await getFlipValue();
+ const deployerCanFlip = async () => {
+ expectedFlipValue = !expectedFlipValue;
+ const deployerFlip = contract.exec('flip', value, gasLimit);
+ await submitTransactionAsync(deployer, deployerFlip);
+ const aliceFlip1Response = await getFlipValue(contract, deployer);
+ expect(aliceFlip1Response).to.be.eq(expectedFlipValue, `Deployer always can flip.`);
+ };
+ await deployerCanFlip();
- expect(afterFlipGetResponse).to.be.false;
+ const enableWhiteListTx = api.tx.nft.toggleContractWhiteList(contract.address, true);
+ const enableResult = await submitTransactionAsync(deployer, enableWhiteListTx);
+ const flipWithEnabledWhiteList = contract.exec('flip', value, gasLimit);
+ await expect(submitTransactionExpectFailAsync(bob, flipWithEnabledWhiteList)).to.be.rejected;
+ const flipValueAfterEnableWhiteList = await getFlipValue(contract, deployer);
+ expect(flipValueAfterEnableWhiteList).to.be.eq(expectedFlipValue, `Enabling whitelist doesn't make it possible to call contract for everyone.`);
+
+ await deployerCanFlip();
+
+ const addBobToWhiteListTx = api.tx.nft.addToContractWhiteList(contract.address, bob.address);
+ const addBobResult = await submitTransactionAsync(deployer, addBobToWhiteListTx);
+ const flipWithWhitelistedBob = contract.exec('flip', value, gasLimit);
+ await submitTransactionAsync(bob, flipWithWhitelistedBob);
+ expectedFlipValue = !expectedFlipValue;
+ const flipAfterWhiteListed = await getFlipValue(contract,deployer);
+ expect(flipAfterWhiteListed).to.be.eq(expectedFlipValue, `Bob was whitelisted, now he can flip.`);
+
+ await deployerCanFlip();
+
+ const removeBobFromWhiteListTx = api.tx.nft.removeFromContractWhiteList(contract.address, bob.address);
+ const removeBobResult = await submitTransactionAsync(deployer, removeBobFromWhiteListTx);
+ const bobRemoved = contract.exec('flip', value, gasLimit);
+ await expect(submitTransactionExpectFailAsync(bob, bobRemoved)).to.be.rejected;
+ const afterBobRemoved = await getFlipValue(contract, deployer);
+ expect(afterBobRemoved).to.be.eq(expectedFlipValue, `Bob can't call contract, now when he is removeed from white list.`);
+
+ await deployerCanFlip();
+
+ const disableWhiteListTx = api.tx.nft.toggleContractWhiteList(contract.address, false);
+ const disableWhiteListResult = await submitTransactionAsync(deployer, disableWhiteListTx);
+ const whiteListDisabledFlip = contract.exec('flip', value, gasLimit);
+ await submitTransactionAsync(bob, whiteListDisabledFlip);
+ expectedFlipValue = !expectedFlipValue;
+ const afterWhiteListDisabled = await getFlipValue(contract,deployer);
+ expect(afterWhiteListDisabled).to.be.eq(expectedFlipValue, `Anyone can call contract with disabled whitelist.`);
+
+ console.error = consoleError;
});
});
@@ -123,7 +201,7 @@
// const bob = new GenericAccountId(api.registry, bobsPublicKey);
// const transfer = contractInstance.exec('balance_transfer', 0, 1000000000000n, [bob, new u128(api.registry, 1000000)]);
- // await runTransaction(alicesPrivateKey, transfer);
+ // await submitTransactionAsync(alicesPrivateKey, transfer);
// const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
tests/src/createCollection.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/createCollection.test.ts
@@ -0,0 +1,72 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import { default as usingApi } from "./substrate/substrate-api";
+import { createCollectionExpectSuccess, createCollectionExpectFailure } from "./util/helpers";
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+describe('integration test: ext. createCollection():', () => {
+ it('Create new NFT collection', async () => {
+ await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ });
+ it('Create new NFT collection whith collection_name of maximum length (64 bytes)', async () => {
+ await createCollectionExpectSuccess(
+ 'ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCD',
+ '1', '1', 'NFT');
+ });
+ it('Create new NFT collection whith collection_description of maximum length (256 bytes)', async () => {
+ await createCollectionExpectSuccess(
+ 'A',
+ 'ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJabcdef',
+ '1', 'NFT');
+ });
+ it('Create new NFT collection whith token_prefix of maximum length (16 bytes)', async () => {
+ await createCollectionExpectSuccess(
+ '1',
+ '1',
+ 'ABCDEFGHIJABCDEF', 'NFT');
+ });
+ it('Create new Fungible collection', async () => {
+ await createCollectionExpectSuccess('1', '1', '1', 'Fungible');
+ });
+ it('Create new ReFungible collection', async () => {
+ await createCollectionExpectSuccess('1', '1', '1', 'ReFungible');
+ });
+});
+
+describe('(!negative test!) integration test: ext. createCollection():', () => {
+ it('(!negative test!) create new NFT collection whith incorrect data (mode)', async () => {
+ await usingApi(async (api) => {
+ const AcollectionCount = parseInt((await api.query.nft.collectionCount()).toString());
+
+ const badTransaction = async function () {
+ await createCollectionExpectSuccess('1', '1', '1', 'BadMode');
+ };
+ expect(badTransaction()).to.be.rejected;
+
+ const BcollectionCount = parseInt((await api.query.nft.collectionCount()).toString());
+ expect(BcollectionCount).to.be.equal(AcollectionCount, 'Error: Incorrect collection created.');
+ });
+ });
+ it('(!negative test!) create new NFT collection whith incorrect data (collection_name)', async () => {
+ await createCollectionExpectFailure(
+ 'ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDE',
+ '1', '1', 'NFT');
+ });
+ it('(!negative test!) create new NFT collection whith incorrect data (collection_description)', async () => {
+ await createCollectionExpectFailure('1',
+ 'ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJabcdefg',
+ '1', 'NFT');
+ });
+ it('(!negative test!) create new NFT collection whith incorrect data (token_prefix)', async () => {
+ await createCollectionExpectFailure('1', '1',
+ 'ABCDEFGHIJABCDEFG',
+ 'NFT');
+ });
+});
tests/src/createItem.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/createItem.test.ts
@@ -0,0 +1,34 @@
+import { default as usingApi } from './substrate/substrate-api';
+import { Keyring } from "@polkadot/api";
+import { IKeyringPair } from "@polkadot/types/types";
+import {
+ createCollectionExpectSuccess,
+ createItemExpectSuccess
+} from './util/helpers';
+
+let alice: IKeyringPair;
+
+describe('integration test: ext. createItem():', () => {
+ before(async () => {
+ await usingApi(async (api) => {
+ const keyring = new Keyring({ type: 'sr25519' });
+ alice = keyring.addFromUri(`//Alice`);
+ });
+ });
+
+ it('Create new item in NFT collection', async () => {
+ const createMode = 'NFT';
+ const newCollectionID = await createCollectionExpectSuccess('0', '0', '0', createMode);
+ await createItemExpectSuccess(alice, newCollectionID, createMode);
+ });
+ it('Create new item in Fungible collection', async () => {
+ const createMode = 'Fungible';
+ const newCollectionID = await createCollectionExpectSuccess('0', '0', '0', createMode);
+ await createItemExpectSuccess(alice, newCollectionID, createMode);
+ });
+ it('Create new item in ReFungible collection', async () => {
+ const createMode = 'ReFungible';
+ const newCollectionID = await createCollectionExpectSuccess('0', '0', '0', createMode);
+ await createItemExpectSuccess(alice, newCollectionID, createMode);
+ });
+});
tests/src/createMultipleItems.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/createMultipleItems.test.ts
@@ -0,0 +1,69 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import { assert } from 'chai';
+import { alicesPublicKey } from './accounts';
+import privateKey from './substrate/privateKey';
+import usingApi from './substrate/substrate-api';
+import waitNewBlocks from './substrate/wait-new-blocks';
+
+const idCollection = 12;
+
+describe.skip('integration test: ext. createMultipleItems():', () => {
+ it('Create two NFT tokens in active NFT collection', async () => {
+ await usingApi(async (api) => {
+ const AitemListIndex = await api.query.nft.itemListIndex(idCollection);
+ console.log(`itemListIndex count (before): ${AitemListIndex}`);
+ const args = ['NFT', 'NFT'];
+ const alicePrivateKey = privateKey('//Alice');
+ const createMultipleItems = await api.tx.nft
+ .createMultipleItems(idCollection, alicesPublicKey, args)
+ .signAndSend(alicePrivateKey);
+ // tslint:disable-next-line: no-unused-expression
+ assert.exists(createMultipleItems, 'createMultipleItems is neither `null` or `undefined`');
+ console.log(`Ext. createMultipleItems submitted with hash: ${createMultipleItems}`);
+ await waitNewBlocks(api);
+ const BitemListIndex = await api.query.nft.itemListIndex(idCollection);
+ console.log(`itemListIndex count (after): ${BitemListIndex}`);
+ if (BitemListIndex === AitemListIndex) { assert.fail('Corret token not added in collection!'); }
+ });
+ });
+ it('(!negative test!) Create two Fungible tokens in active NFT collection', async () => {
+ await usingApi(async (api) => {
+ const AitemListIndex = await api.query.nft.itemListIndex(idCollection);
+ console.log(`itemListIndex count (before): ${AitemListIndex}`);
+ const args = ['Fungible', 'Fungible'];
+ const alicePrivateKey = privateKey('//Alice');
+ const createMultipleItems = await api.tx.nft
+ .createMultipleItems(idCollection, alicesPublicKey, args)
+ .signAndSend(alicePrivateKey);
+ // tslint:disable-next-line: no-unused-expression
+ assert.exists(createMultipleItems, 'createMultipleItems is neither `null` or `undefined`');
+ console.log(`Ext. createMultipleItems submitted with hash: ${createMultipleItems}`);
+ await waitNewBlocks(api);
+ const BitemListIndex = await api.query.nft.itemListIndex(idCollection);
+ console.log(`itemListIndex count (after): ${BitemListIndex}`);
+ if (BitemListIndex > AitemListIndex) { assert.fail('Incorrect token added in collection!'); }
+ });
+ });
+ it('(!negative test!) Create two ReFungible tokens in active NFT collection', async () => {
+ await usingApi(async (api) => {
+ const AitemListIndex = await api.query.nft.itemListIndex(idCollection);
+ console.log(`itemListIndex count (before): ${AitemListIndex}`);
+ const args = ['ReFungible', 'ReFungible'];
+ const alicePrivateKey = privateKey('//Alice');
+ const createMultipleItems = await api.tx.nft
+ .createMultipleItems(idCollection, alicesPublicKey, args)
+ .signAndSend(alicePrivateKey);
+ // tslint:disable-next-line: no-unused-expression
+ assert.exists(createMultipleItems, 'createMultipleItems is neither `null` or `undefined`');
+ console.log(`Ext. createMultipleItems submitted with hash: ${createMultipleItems}`);
+ await waitNewBlocks(api);
+ const BitemListIndex = await api.query.nft.itemListIndex(idCollection);
+ console.log(`itemListIndex count (after): ${BitemListIndex}`);
+ if (BitemListIndex > AitemListIndex) { assert.fail('Incorrect token added in collection!'); }
+ });
+ });
+});
tests/src/creditFeesToTreasury.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/creditFeesToTreasury.test.ts
@@ -0,0 +1,112 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api";
+import { alicesPublicKey, bobsPublicKey } from "./accounts";
+import privateKey from "./substrate/privateKey";
+import { BigNumber } from 'bignumber.js';
+import { createCollectionExpectSuccess, getGenericResult } from './util/helpers';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+const Treasury = "5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z";
+const saneMinimumFee = 0.0001;
+const saneMaximumFee = 0.01;
+
+describe('integration test: Fees must be credited to Treasury:', () => {
+ it('Total issuance does not change', async () => {
+ await usingApi(async (api) => {
+ const totalBefore = new BigNumber((await api.query.balances.totalIssuance()).toString());
+
+ const alicePrivateKey = privateKey('//Alice');
+ const amount = new BigNumber(1);
+ const transfer = api.tx.balances.transfer(bobsPublicKey, amount.toFixed());
+
+ const result = getGenericResult(await submitTransactionAsync(alicePrivateKey, transfer));
+
+ const totalAfter = new BigNumber((await api.query.balances.totalIssuance()).toString());
+
+ expect(result.success).to.be.true;
+ expect(totalAfter.toFixed()).to.be.equal(totalBefore.toFixed());
+ });
+ });
+
+ it('Sender balance decreased by fee+sent amount, Treasury balance increased by fee', async () => {
+ await usingApi(async (api) => {
+ const alicePrivateKey = privateKey('//Alice');
+ const treasuryBalanceBefore = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());
+ const aliceBalanceBefore = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());
+
+ const amount = new BigNumber(1);
+ const transfer = api.tx.balances.transfer(bobsPublicKey, amount.toFixed());
+ const result = getGenericResult(await submitTransactionAsync(alicePrivateKey, transfer));
+
+ const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());
+ const aliceBalanceAfter = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());
+ const fee = aliceBalanceBefore.minus(aliceBalanceAfter).minus(amount);
+ const treasuryIncrease = treasuryBalanceAfter.minus(treasuryBalanceBefore);
+
+ expect(result.success).to.be.true;
+ expect(treasuryIncrease.toFixed()).to.be.equal(fee.toFixed());
+ });
+ });
+
+ it('Treasury balance increased by failed tx fee', async () => {
+ await usingApi(async (api) => {
+ const bobPrivateKey = privateKey('//Bob');
+ const treasuryBalanceBefore = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());
+ const bobBalanceBefore = new BigNumber((await api.query.system.account(bobsPublicKey)).data.free.toString());
+
+ const badTx = api.tx.balances.setBalance(alicesPublicKey, 0, 0);
+ const result = getGenericResult(await submitTransactionAsync(bobPrivateKey, badTx));
+
+ const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());
+ const bobBalanceAfter = new BigNumber((await api.query.system.account(bobsPublicKey)).data.free.toString());
+ const fee = bobBalanceBefore.minus(bobBalanceAfter);
+ const treasuryIncrease = treasuryBalanceAfter.minus(treasuryBalanceBefore);
+
+ expect(result.success).to.be.false;
+ expect(treasuryIncrease.toFixed()).to.be.equal(fee.toFixed());
+ });
+ });
+
+ it('NFT Transactions also send fees to Treasury', async () => {
+ await usingApi(async (api) => {
+ const treasuryBalanceBefore = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());
+ const aliceBalanceBefore = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());
+
+ await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+
+ const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());
+ const aliceBalanceAfter = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());
+ const fee = aliceBalanceBefore.minus(aliceBalanceAfter);
+ const treasuryIncrease = treasuryBalanceAfter.minus(treasuryBalanceBefore);
+
+ expect(treasuryIncrease.toFixed()).to.be.equal(fee.toFixed());
+ });
+ });
+
+ it('Fees are sane', async () => {
+ await usingApi(async (api) => {
+ const treasuryBalanceBefore = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());
+ const aliceBalanceBefore = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());
+
+ await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+
+ const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString());
+ const aliceBalanceAfter = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString());
+ const fee = aliceBalanceBefore.minus(aliceBalanceAfter);
+ const treasuryIncrease = treasuryBalanceAfter.minus(treasuryBalanceBefore);
+
+ expect(fee.dividedBy(1e15).toNumber()).to.be.lessThan(0.01);
+ expect(fee.dividedBy(1e15).toNumber()).to.be.greaterThan(0.0001);
+ });
+ });
+
+});
+
tests/src/destroyCollection.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/destroyCollection.test.ts
@@ -0,0 +1,44 @@
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api";
+import { createCollectionExpectSuccess, createCollectionExpectFailure, destroyCollectionExpectSuccess, destroyCollectionExpectFailure } from "./util/helpers";
+import type { AccountId, EventRecord } from '@polkadot/types/interfaces';
+import privateKey from './substrate/privateKey';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+describe('integration test: ext. destroyCollection():', () => {
+ it('NFT collection can be destroyed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await destroyCollectionExpectSuccess(collectionId);
+ });
+ it('Fungible collection can be destroyed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'Fungible');
+ await destroyCollectionExpectSuccess(collectionId);
+ });
+ it('ReFungible collection can be destroyed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'ReFungible');
+ await destroyCollectionExpectSuccess(collectionId);
+ });
+});
+
+describe('(!negative test!) integration test: ext. destroyCollection():', () => {
+ it('(!negative test!) Destroy a collection that never existed', async () => {
+ await usingApi(async (api) => {
+ // Find the collection that never existed
+ const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;
+ await destroyCollectionExpectFailure(collectionId);
+ });
+ });
+ it('(!negative test!) Destroy a collection that has already been destroyed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await destroyCollectionExpectSuccess(collectionId);
+ await destroyCollectionExpectFailure(collectionId);
+ });
+ it('(!negative test!) Destroy a collection using non-owner account', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await destroyCollectionExpectFailure(collectionId, '//Bob');
+ await destroyCollectionExpectSuccess(collectionId, '//Alice');
+ });
+});
tests/src/load_test_sc/loadtester.wasmdiffbeforeafterbothbinary blob — no preview
tests/src/load_test_sc/metadata.jsondiffbeforeafterboth--- /dev/null
+++ b/tests/src/load_test_sc/metadata.json
@@ -0,0 +1,125 @@
+{
+ "metadataVersion": "0.1.0",
+ "source": {
+ "hash": "0x168cc3cba9657ad3950fb506e568751f99b90fb097685107f6101675662a8303",
+ "language": "ink! 3.0.0-rc2",
+ "compiler": "rustc 1.49.0-nightly"
+ },
+ "contract": {
+ "name": "loadtester",
+ "version": "0.1.0",
+ "authors": [
+ "[your_name] <[your_email]>"
+ ]
+ },
+ "spec": {
+ "constructors": [
+ {
+ "args": [],
+ "docs": [],
+ "name": [
+ "new"
+ ],
+ "selector": "0xd183512b"
+ }
+ ],
+ "docs": [],
+ "events": [],
+ "messages": [
+ {
+ "args": [
+ {
+ "name": "count",
+ "type": {
+ "displayName": [
+ "u64"
+ ],
+ "type": 2
+ }
+ }
+ ],
+ "docs": [],
+ "mutates": true,
+ "name": [
+ "bloat"
+ ],
+ "payable": false,
+ "returnType": null,
+ "selector": "0x49891c2a"
+ },
+ {
+ "args": [],
+ "docs": [],
+ "mutates": false,
+ "name": [
+ "get"
+ ],
+ "payable": false,
+ "returnType": {
+ "displayName": [
+ "u128"
+ ],
+ "type": 3
+ },
+ "selector": "0x1e5ca456"
+ }
+ ]
+ },
+ "storage": {
+ "struct": {
+ "fields": [
+ {
+ "layout": {
+ "struct": {
+ "fields": [
+ {
+ "layout": {
+ "cell": {
+ "key": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "ty": 1
+ }
+ },
+ "name": "len"
+ },
+ {
+ "layout": {
+ "array": {
+ "cellsPerElem": 1,
+ "layout": {
+ "cell": {
+ "key": "0x0000000001000000000000000000000000000000000000000000000000000000",
+ "ty": 2
+ }
+ },
+ "len": 4294967295,
+ "offset": "0x0100000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ "name": "elems"
+ }
+ ]
+ }
+ },
+ "name": "vector"
+ }
+ ]
+ }
+ },
+ "types": [
+ {
+ "def": {
+ "primitive": "u32"
+ }
+ },
+ {
+ "def": {
+ "primitive": "u64"
+ }
+ },
+ {
+ "def": {
+ "primitive": "u128"
+ }
+ }
+ ]
+}
\ No newline at end of file
tests/src/pallet-presence.test.tsdiffbeforeafterboth--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { ApiPromise } from "@polkadot/api";
import { expect } from "chai";
import usingApi from "./substrate/substrate-api";
@@ -6,20 +11,34 @@
return api.runtimeMetadata.asLatest.modules.map(m => m.name.toString().toLowerCase());
}
-describe('Pallet presence.', () => {
- it('NFT pallet is present.', async () => {
+// Pallets that must always be present
+const requiredPallets = [
+ 'nft', 'balances', 'contracts', 'randomnesscollectiveflip', 'system', 'timestamp', 'transactionpayment', 'treasury', 'vesting'
+];
+
+// Pallets that depend on consensus and governance configuration
+const consensusPallets = [
+ 'sudo', 'grandpa', 'aura'
+];
+
+describe('Pallet presence', () => {
+ it('Required pallets are present', async () => {
await usingApi(async api => {
- expect(getModuleNames(api)).to.include('nft');
+ for (let i=0; i<requiredPallets.length; i++) {
+ expect(getModuleNames(api)).to.include(requiredPallets[i]);
+ }
});
});
- it('Balances pallet is present.', async () => {
+ it('Governance and consensus pallets are present', async () => {
await usingApi(async api => {
- expect(getModuleNames(api)).to.include('balances');
+ for (let i=0; i<consensusPallets.length; i++) {
+ expect(getModuleNames(api)).to.include(consensusPallets[i]);
+ }
});
});
- it('Contracts pallet is present.', async () => {
+ it('No extra pallets are included', async () => {
await usingApi(async api => {
- expect(getModuleNames(api)).to.include('contracts');
+ expect(getModuleNames(api).length).to.be.equal(requiredPallets.length + consensusPallets.length);
});
});
});
tests/src/removeCollectionSponsor.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/removeCollectionSponsor.test.ts
@@ -0,0 +1,141 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api";
+import {
+ createCollectionExpectSuccess,
+ setCollectionSponsorExpectSuccess,
+ destroyCollectionExpectSuccess,
+ setCollectionSponsorExpectFailure,
+ confirmSponsorshipExpectSuccess,
+ confirmSponsorshipExpectFailure,
+ createItemExpectSuccess,
+ findUnusedAddress,
+ getGenericResult,
+ enableWhiteListExpectSuccess,
+ enablePublicMintingExpectSuccess,
+ addToWhiteListExpectSuccess,
+ removeCollectionSponsorExpectSuccess,
+ removeCollectionSponsorExpectFailure,
+} from "./util/helpers";
+import { Keyring } from "@polkadot/api";
+import { IKeyringPair } from "@polkadot/types/types";
+import type { AccountId } from '@polkadot/types/interfaces';
+import { BigNumber } from 'bignumber.js';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+let alice: IKeyringPair;
+let bob: IKeyringPair;
+let charlie: IKeyringPair;
+
+describe('integration test: ext. removeCollectionSponsor():', () => {
+
+ before(async () => {
+ await usingApi(async (api) => {
+ const keyring = new Keyring({ type: 'sr25519' });
+ alice = keyring.addFromUri(`//Alice`);
+ bob = keyring.addFromUri(`//Bob`);
+ charlie = keyring.addFromUri(`//Charlie`);
+ });
+ });
+
+ it('Remove NFT collection sponsor stops sponsorship', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+ await removeCollectionSponsorExpectSuccess(collectionId);
+
+ await usingApi(async (api) => {
+ // Find unused address
+ const zeroBalance = await findUnusedAddress(api);
+
+ // Mint token for unused address
+ const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);
+
+ // Transfer this tokens from unused address to Alice - should fail
+ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+ const zeroToAlice = api.tx.nft.transfer(alice.address, collectionId, itemId, 0);
+ const badTransaction = async function () {
+ console.log = function () {};
+ console.error = function () {};
+ await submitTransactionAsync(zeroBalance, zeroToAlice);
+ delete console.log;
+ delete console.error;
+ };
+ await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees");
+ const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString());
+
+ expect(BsponsorBalance.isEqualTo(AsponsorBalance)).to.be.true;
+ });
+ });
+
+ it('Remove a sponsor after it was already removed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+ await removeCollectionSponsorExpectSuccess(collectionId);
+ await removeCollectionSponsorExpectSuccess(collectionId);
+ });
+
+ it('Remove sponsor in a collection that never had the sponsor set', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await removeCollectionSponsorExpectSuccess(collectionId);
+ });
+
+ it('Remove sponsor for a collection that had the sponsor set, but not confirmed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await removeCollectionSponsorExpectSuccess(collectionId);
+ });
+
+});
+
+describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {
+ before(async () => {
+ await usingApi(async (api) => {
+ const keyring = new Keyring({ type: 'sr25519' });
+ alice = keyring.addFromUri(`//Alice`);
+ bob = keyring.addFromUri(`//Bob`);
+ charlie = keyring.addFromUri(`//Charlie`);
+ });
+ });
+
+ it('(!negative test!) Remove sponsor for a collection that never existed', async () => {
+ // Find the collection that never existed
+ const collectionId = 0;
+ await usingApi(async (api) => {
+ const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;
+ });
+
+ await removeCollectionSponsorExpectFailure(collectionId);
+ });
+
+ it('(!negative test!) Remove sponsor in a destroyed collection', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await destroyCollectionExpectSuccess(collectionId);
+ await removeCollectionSponsorExpectFailure(collectionId);
+ });
+
+ it('Set - remove - confirm: fails', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await removeCollectionSponsorExpectSuccess(collectionId);
+ await confirmSponsorshipExpectFailure(collectionId, '//Bob');
+ });
+
+ it('Set - confirm - remove - confirm: Sponsor cannot come back', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+ await removeCollectionSponsorExpectSuccess(collectionId);
+ await confirmSponsorshipExpectFailure(collectionId, '//Bob');
+ });
+
+});
tests/src/rpc.load.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/rpc.load.ts
@@ -0,0 +1,145 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import { expect, assert } from "chai";
+import usingApi, { submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api";
+import { IKeyringPair } from "@polkadot/types/types";
+import { Abi, BlueprintPromise as Blueprint, CodePromise, ContractPromise as Contract } from "@polkadot/api-contract";
+import { ApiPromise, Keyring } from "@polkadot/api";
+import { ApiTypes, SubmittableExtrinsic } from "@polkadot/api/types";
+import { BigNumber } from 'bignumber.js';
+import { findUnusedAddress } from './util/helpers'
+import fs from "fs";
+import privateKey from "./substrate/privateKey";
+
+const value = 0;
+const gasLimit = 500000n * 1000000n;
+const endowment = `1000000000000000`;
+
+
+function deployBlueprint(alice: IKeyringPair, code: CodePromise): Promise<Blueprint> {
+ return new Promise<Blueprint>(async (resolve, reject) => {
+ const unsub = await code
+ .createBlueprint()
+ .signAndSend(alice, (result) => {
+ if (result.status.isInBlock || result.status.isFinalized) {
+ // here we have an additional field in the result, containing the blueprint
+ resolve(result.blueprint);
+ unsub();
+ }
+ })
+ });
+}
+
+function deployContract(alice: IKeyringPair, blueprint: Blueprint) : Promise<any> {
+ return new Promise<any>(async (resolve, reject) => {
+ const unsub = await blueprint.tx
+ .new(endowment, gasLimit)
+ .signAndSend(alice, (result) => {
+ if (result.status.isInBlock || result.status.isFinalized) {
+ unsub();
+ resolve(result);
+ }
+ });
+ });
+}
+
+async function prepareDeployer(api: ApiPromise) {
+ // Find unused address
+ const deployer = await findUnusedAddress(api);
+
+ // Transfer balance to it
+ const keyring = new Keyring({ type: 'sr25519' });
+ const alice = keyring.addFromUri(`//Alice`);
+ let amount = new BigNumber(endowment);
+ amount = amount.plus(1e15);
+ const tx = api.tx.balances.transfer(deployer.address, amount.toFixed());
+ await submitTransactionAsync(alice, tx);
+
+ return deployer;
+}
+
+async function deployLoadTester(api: ApiPromise): Promise<[Contract, IKeyringPair]> {
+ const metadata = JSON.parse(fs.readFileSync('./src/load_test_sc/metadata.json').toString('utf-8'));
+ const abi = new Abi(metadata);
+
+ const deployer = await prepareDeployer(api);
+
+ const wasm = fs.readFileSync('./src/load_test_sc/loadtester.wasm');
+
+ const code = new CodePromise(api, abi, wasm);
+
+ const blueprint = await deployBlueprint(deployer, code);
+ const contract = (await deployContract(deployer, blueprint))['contract'] as Contract;
+
+ return [contract, deployer];
+}
+
+async function getScData(contract: Contract, deployer: IKeyringPair) {
+ const result = await contract.query.get(deployer.address, value, gasLimit);
+
+ if(!result.result.isSuccess) {
+ throw `Failed to get value`;
+ }
+ return result.result.asSuccess.data;
+}
+
+
+describe('RPC Tests', () => {
+ it('Simple RPC Load Test', async () => {
+ await usingApi(async api => {
+ let count = 0;
+ let hrTime = process.hrtime();
+ let microsec1 = hrTime[0] * 1000000 + hrTime[1] / 1000;
+ let rate = 0;
+ const checkPoint = 1000;
+ while (true) {
+ await api.rpc.system.chain();
+ count++;
+ process.stdout.write(`RPC reads: ${count} times at rate ${rate} r/s \r`);
+
+ if (count % checkPoint == 0) {
+ hrTime = process.hrtime();
+ let microsec2 = hrTime[0] * 1000000 + hrTime[1] / 1000;
+ rate = 1000000*checkPoint/(microsec2 - microsec1);
+ microsec1 = microsec2;
+ }
+ }
+ });
+ });
+
+ it.only('Smart Contract RPC Load Test', async () => {
+ await usingApi(async api => {
+
+ // Deploy smart contract
+ const [contract, deployer] = await deployLoadTester(api);
+
+ // Fill smart contract up with data
+ const bob = privateKey("//Bob");
+ const tx = contract.tx.bloat(value, gasLimit, 200);
+ await submitTransactionAsync(bob, tx);
+
+ // Run load test
+ let count = 0;
+ let hrTime = process.hrtime();
+ let microsec1 = hrTime[0] * 1000000 + hrTime[1] / 1000;
+ let rate = 0;
+ const checkPoint = 10;
+ while (true) {
+ await getScData(contract, deployer);
+ count++;
+ process.stdout.write(`SC reads: ${count} times at rate ${rate} r/s \r`);
+
+ if (count % checkPoint == 0) {
+ hrTime = process.hrtime();
+ let microsec2 = hrTime[0] * 1000000 + hrTime[1] / 1000;
+ rate = 1000000*checkPoint/(microsec2 - microsec1);
+ microsec1 = microsec2;
+ }
+ }
+ });
+ });
+
+});
tests/src/setCollectionSponsor.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -0,0 +1,82 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import { default as usingApi } from "./substrate/substrate-api";
+import { createCollectionExpectSuccess, setCollectionSponsorExpectSuccess, destroyCollectionExpectSuccess, setCollectionSponsorExpectFailure } from "./util/helpers";
+import { Keyring } from "@polkadot/api";
+import { IKeyringPair } from "@polkadot/types/types";
+import type { AccountId } from '@polkadot/types/interfaces';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+let bob: IKeyringPair;
+
+describe('integration test: ext. setCollectionSponsor():', () => {
+
+ before(async () => {
+ await usingApi(async (api) => {
+ const keyring = new Keyring({ type: 'sr25519' });
+ bob = keyring.addFromUri(`//Bob`);
+ });
+ });
+
+ it('Set NFT collection sponsor', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ });
+ it('Set Fungible collection sponsor', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'Fungible');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ });
+ it('Set ReFungible collection sponsor', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'ReFungible');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ });
+
+ it('Set the same sponsor repeatedly', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ });
+ it('Replace collection sponsor', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+
+ const keyring = new Keyring({ type: 'sr25519' });
+ const charlie = keyring.addFromUri(`//Charlie`);
+ await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+ await setCollectionSponsorExpectSuccess(collectionId, charlie.address);
+ });
+});
+
+describe('(!negative test!) integration test: ext. setCollectionSponsor():', () => {
+ before(async () => {
+ await usingApi(async (api) => {
+ const keyring = new Keyring({ type: 'sr25519' });
+ bob = keyring.addFromUri(`//Bob`);
+ });
+ });
+
+ it('(!negative test!) Add sponsor with a non-owner', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await setCollectionSponsorExpectFailure(collectionId, bob.address, '//Bob');
+ });
+ it('(!negative test!) Add sponsor to a collection that never existed', async () => {
+ // Find the collection that never existed
+ const collectionId = 0;
+ await usingApi(async (api) => {
+ const collectionId = parseInt((await api.query.nft.createdCollectionCount()).toString()) + 1;
+ });
+
+ await setCollectionSponsorExpectFailure(collectionId, bob.address);
+ });
+ it('(!negative test!) Add sponsor to a collection that was destroyed', async () => {
+ const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT');
+ await destroyCollectionExpectSuccess(collectionId);
+ await setCollectionSponsorExpectFailure(collectionId, bob.address);
+ });
+});
tests/src/substrate/get-balance.tsdiffbeforeafterboth--- a/tests/src/substrate/get-balance.ts
+++ b/tests/src/substrate/get-balance.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { ApiPromise } from "@polkadot/api";
import promisifySubstrate from "./promisify-substrate";
import {AccountInfo} from "@polkadot/types/interfaces/system";
tests/src/substrate/privateKey.tsdiffbeforeafterboth--- a/tests/src/substrate/privateKey.ts
+++ b/tests/src/substrate/privateKey.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { Keyring } from "@polkadot/api";
import { IKeyringPair } from "@polkadot/types/types";
tests/src/substrate/promisify-substrate.tsdiffbeforeafterboth--- a/tests/src/substrate/promisify-substrate.ts
+++ b/tests/src/substrate/promisify-substrate.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import ApiPromise from "@polkadot/api/promise/Api";
type PromiseType<T> = T extends PromiseLike<infer TInner> ? TInner : T;
tests/src/substrate/substrate-api.tsdiffbeforeafterboth--- a/tests/src/substrate/substrate-api.ts
+++ b/tests/src/substrate/substrate-api.ts
@@ -1,7 +1,15 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { WsProvider, ApiPromise } from "@polkadot/api";
+import type { AccountId, Address, ApplyExtrinsicResult, DispatchError, DispatchInfo, EventRecord, Extrinsic, ExtrinsicStatus, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
+import { IKeyringPair } from "@polkadot/types/types";
+
import config from "../config";
import promisifySubstrate from "./promisify-substrate";
-import { ApiOptions } from "@polkadot/api/types";
+import { ApiOptions, SubmittableExtrinsic, ApiTypes } from "@polkadot/api/types";
import rtt from "../../../runtime_types.json";
function defaultApiOptions(): ApiOptions {
@@ -23,4 +31,50 @@
} finally {
await api.disconnect();
}
+}
+
+export function submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {
+ return new Promise(async function(resolve, reject) {
+ try {
+ await transaction.signAndSend(sender, ({ events = [], status }) => {
+ if (status.isReady) {
+ // nothing to do
+ // console.log(`Current tx status is Ready`);
+ } else if (status.isBroadcast) {
+ // nothing to do
+ // console.log(`Current tx status is Broadcast`);
+ } else if (status.isInBlock || status.isFinalized) {
+ resolve(events);
+ } else {
+ console.log(`Something went wrong with transaction. Status: ${status}`);
+ reject("Transaction failed");
+ }
+ });
+ } catch (e) {
+ console.log("Error: ", e);
+ reject(e);
+ }
+ });
+}
+
+export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {
+ return new Promise(async function(resolve, reject) {
+ try {
+ await transaction.signAndSend(sender, ({ events = [], status }) => {
+ if (status.isReady) {
+ // nothing to do
+ // console.log(`Current tx status is Ready`);
+ } else if (status.isBroadcast) {
+ // nothing to do
+ // console.log(`Current tx status is Broadcast`);
+ } else if (status.isInBlock || status.isFinalized) {
+ resolve(events);
+ } else {
+ reject("Transaction failed");
+ }
+ });
+ } catch (e) {
+ reject(e);
+ }
+ });
}
\ No newline at end of file
tests/src/substrate/wait-new-blocks.tsdiffbeforeafterboth--- a/tests/src/substrate/wait-new-blocks.ts
+++ b/tests/src/substrate/wait-new-blocks.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { ApiPromise } from "@polkadot/api";
export default function waitNewBlocks(api: ApiPromise, blocksCount: number = 1): Promise<void> {
tests/src/transfer.test.tsdiffbeforeafterboth--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -1,10 +1,15 @@
-import { expect } from "chai";
-import usingApi from "./substrate/substrate-api";
-import promisifySubstrate from "./substrate/promisify-substrate";
-import waitNewBlocks from "./substrate/wait-new-blocks";
-import { alicesPublicKey, bobsPublicKey } from "./accounts";
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import { expect, assert } from "chai";
+import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api";
+import { alicesPublicKey, bobsPublicKey, ferdiesPublicKey } from "./accounts";
import privateKey from "./substrate/privateKey";
import getBalance from "./substrate/get-balance";
+import { BigNumber } from 'bignumber.js';
+import { findUnusedAddress } from './util/helpers'
describe('Transfer', () => {
it('Balance transfers', async () => {
@@ -14,15 +19,31 @@
const alicePrivateKey = privateKey('//Alice');
const transfer = api.tx.balances.transfer(bobsPublicKey, 1n);
-
- await promisifySubstrate(api, () => transfer.signAndSend(alicePrivateKey))();
+ const result = await submitTransactionAsync(alicePrivateKey, transfer);
- await waitNewBlocks(api);
-
const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
});
});
+
+ it('Inability to pay fees error message is correct', async () => {
+ await usingApi(async api => {
+ // Find unused address
+ const pk = await findUnusedAddress(api);
+
+ console.log = function () {};
+ console.error = function () {};
+
+ const badTransfer = api.tx.balances.transfer(bobsPublicKey, 1n);
+ const badTransaction = async function () {
+ const result = await submitTransactionAsync(pk, badTransfer);
+ };
+ await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees");
+
+ delete console.log;
+ delete console.error;
+ });
+ });
});
tests/src/util/helpers.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/util/helpers.ts
@@ -0,0 +1,398 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import type { AccountId, EventRecord } from '@polkadot/types/interfaces';
+import { ApiPromise, Keyring } from "@polkadot/api";
+import { default as usingApi, submitTransactionAsync } from "../substrate/substrate-api";
+import privateKey from '../substrate/privateKey';
+import { alicesPublicKey, nullPublicKey } from "../accounts";
+import { strToUTF16, utf16ToStr, hexToStr } from '../util/util';
+import { IKeyringPair } from "@polkadot/types/types";
+import { BigNumber } from 'bignumber.js';
+import { Struct, Enum } from '@polkadot/types/codec';
+import { u128 } from '@polkadot/types/primitive';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+type GenericResult = {
+ success: boolean,
+};
+
+type CreateCollectionResult = {
+ success: boolean,
+ collectionId: number
+};
+
+type CreateItemResult = {
+ success: boolean,
+ collectionId: number,
+ itemId: number
+};
+
+export function getGenericResult(events: EventRecord[]): GenericResult {
+ let result: GenericResult = {
+ success: false
+ }
+ events.forEach(({ phase, event: { data, method, section } }) => {
+ // console.log(` ${phase}: ${section}.${method}:: ${data}`);
+ if (method == 'ExtrinsicSuccess') {
+ result.success = true;
+ }
+ });
+ return result;
+}
+
+function getCreateCollectionResult(events: EventRecord[]): CreateCollectionResult {
+ let success = false;
+ let collectionId: number = 0;
+ events.forEach(({ phase, event: { data, method, section } }) => {
+ // console.log(` ${phase}: ${section}.${method}:: ${data}`);
+ if (method == 'ExtrinsicSuccess') {
+ success = true;
+ } else if ((section == 'nft') && (method == 'Created')) {
+ collectionId = parseInt(data[0].toString());
+ }
+ });
+ let result: CreateCollectionResult = {
+ success,
+ collectionId
+ }
+ return result;
+}
+
+function getCreateItemResult(events: EventRecord[]): CreateItemResult {
+ let success = false;
+ let collectionId: number = 0;
+ let itemId: number = 0;
+ events.forEach(({ phase, event: { data, method, section } }) => {
+ // console.log(` ${phase}: ${section}.${method}:: ${data}`);
+ if (method == 'ExtrinsicSuccess') {
+ success = true;
+ } else if ((section == 'nft') && (method == 'ItemCreated')) {
+ collectionId = parseInt(data[0].toString());
+ itemId = parseInt(data[1].toString());
+ }
+ });
+ let result: CreateItemResult = {
+ success,
+ collectionId,
+ itemId
+ }
+ return result;
+}
+
+export async function createCollectionExpectSuccess(name: string, description: string, tokenPrefix: string, mode: string): Promise<number> {
+ let collectionId: number = 0;
+ await usingApi(async (api) => {
+ // Get number of collections before the transaction
+ const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());
+
+ // Run the CreateCollection transaction
+ const alicePrivateKey = privateKey('//Alice');
+ const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), mode);
+ const events = await submitTransactionAsync(alicePrivateKey, tx);
+ const result = getCreateCollectionResult(events);
+
+ // Get number of collections after the transaction
+ const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());
+
+ // Get the collection
+ const collection: any = (await api.query.nft.collection(result.collectionId)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(result.collectionId).to.be.equal(BcollectionCount);
+ expect(collection).to.be.not.null;
+ expect(BcollectionCount).to.be.equal(AcollectionCount+1, 'Error: NFT collection NOT created.');
+ expect(collection.Owner).to.be.equal(alicesPublicKey);
+ expect(utf16ToStr(collection.Name)).to.be.equal(name);
+ expect(utf16ToStr(collection.Description)).to.be.equal(description);
+ expect(hexToStr(collection.TokenPrefix)).to.be.equal(tokenPrefix);
+
+ collectionId = result.collectionId;
+ });
+
+ return collectionId;
+}
+
+export async function createCollectionExpectFailure(name: string, description: string, tokenPrefix: string, mode: string) {
+ await usingApi(async (api) => {
+ // Get number of collections before the transaction
+ const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());
+
+ // Run the CreateCollection transaction
+ const alicePrivateKey = privateKey('//Alice');
+ const tx = api.tx.nft.createCollection(name, description, tokenPrefix, mode);
+ const events = await submitTransactionAsync(alicePrivateKey, tx);
+ const result = getCreateCollectionResult(events);
+
+ // Get number of collections after the transaction
+ const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());
+
+ // What to expect
+ expect(result.success).to.be.false;
+ expect(BcollectionCount).to.be.equal(AcollectionCount, 'Error: Collection with incorrect data created.');
+ });
+}
+
+export async function findUnusedAddress(api: ApiPromise): Promise<IKeyringPair> {
+ let bal = new BigNumber(0);
+ let unused;
+ do {
+ const randomSeed = 'seed' + Math.floor(Math.random() * Math.floor(10000));
+ const keyring = new Keyring({ type: 'sr25519' });
+ unused = keyring.addFromUri(`//${randomSeed}`);
+ bal = new BigNumber((await api.query.system.account(unused.address)).data.free.toString());
+ } while (bal.toFixed() != '0');
+ return unused;
+}
+
+function getDestroyResult(events: EventRecord[]): boolean {
+ let success: boolean = false;
+ events.forEach(({ phase, event: { data, method, section } }) => {
+ // console.log(` ${phase}: ${section}.${method}:: ${data}`);
+ if (method == 'ExtrinsicSuccess') {
+ success = true;
+ }
+ });
+ return success;
+}
+
+export async function destroyCollectionExpectFailure(collectionId: number, senderSeed: string = '//Alice') {
+ await usingApi(async (api) => {
+ // Run the DestroyCollection transaction
+ const alicePrivateKey = privateKey(senderSeed);
+ const tx = api.tx.nft.destroyCollection(collectionId);
+ const events = await submitTransactionAsync(alicePrivateKey, tx);
+ const result = getDestroyResult(events);
+
+ // What to expect
+ expect(result).to.be.false;
+ });
+}
+
+export async function destroyCollectionExpectSuccess(collectionId: number, senderSeed: string = '//Alice') {
+ await usingApi(async (api) => {
+ // Run the DestroyCollection transaction
+ const alicePrivateKey = privateKey(senderSeed);
+ const tx = api.tx.nft.destroyCollection(collectionId);
+ const events = await submitTransactionAsync(alicePrivateKey, tx);
+ const result = getDestroyResult(events);
+
+ // Get the collection
+ const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
+
+ // What to expect
+ expect(result).to.be.true;
+ expect(collection).to.be.not.null;
+ expect(collection.Owner).to.be.equal(nullPublicKey);
+ });
+}
+
+export async function setCollectionSponsorExpectSuccess(collectionId: number, sponsor: string) {
+ await usingApi(async (api) => {
+
+ // Run the transaction
+ const alicePrivateKey = privateKey('//Alice');
+ const tx = api.tx.nft.setCollectionSponsor(collectionId, sponsor);
+ const events = await submitTransactionAsync(alicePrivateKey, tx);
+ const result = getGenericResult(events);
+
+ // Get the collection
+ const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(collection.Sponsor.toString()).to.be.equal(sponsor.toString());
+ expect(collection.SponsorConfirmed).to.be.false;
+ });
+}
+
+export async function removeCollectionSponsorExpectSuccess(collectionId: number) {
+ await usingApi(async (api) => {
+
+ // Run the transaction
+ const alicePrivateKey = privateKey('//Alice');
+ const tx = api.tx.nft.removeCollectionSponsor(collectionId);
+ const events = await submitTransactionAsync(alicePrivateKey, tx);
+ const result = getGenericResult(events);
+
+ // Get the collection
+ const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(collection.Sponsor).to.be.equal(nullPublicKey);
+ expect(collection.SponsorConfirmed).to.be.false;
+ });
+}
+
+export async function removeCollectionSponsorExpectFailure(collectionId: number) {
+ await usingApi(async (api) => {
+
+ // Run the transaction
+ const alicePrivateKey = privateKey('//Alice');
+ const tx = api.tx.nft.removeCollectionSponsor(collectionId);
+ const events = await submitTransactionAsync(alicePrivateKey, tx);
+ const result = getGenericResult(events);
+
+ // What to expect
+ expect(result.success).to.be.false;
+ });
+}
+
+export async function setCollectionSponsorExpectFailure(collectionId: number, sponsor: string, senderSeed: string = '//Alice') {
+ await usingApi(async (api) => {
+
+ // Run the transaction
+ const alicePrivateKey = privateKey(senderSeed);
+ const tx = api.tx.nft.setCollectionSponsor(collectionId, sponsor);
+ const events = await submitTransactionAsync(alicePrivateKey, tx);
+ const result = getGenericResult(events);
+
+ // What to expect
+ expect(result.success).to.be.false;
+ });
+}
+
+export async function confirmSponsorshipExpectSuccess(collectionId: number, senderSeed: string = '//Alice') {
+ await usingApi(async (api) => {
+
+ // Run the transaction
+ const sender = privateKey(senderSeed);
+ const tx = api.tx.nft.confirmSponsorship(collectionId);
+ const events = await submitTransactionAsync(sender, tx);
+ const result = getGenericResult(events);
+
+ // Get the collection
+ const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(collection.Sponsor).to.be.equal(sender.address);
+ expect(collection.SponsorConfirmed).to.be.true;
+ });
+}
+
+export async function confirmSponsorshipExpectFailure(collectionId: number, senderSeed: string = '//Alice') {
+ await usingApi(async (api) => {
+
+ // Run the transaction
+ const sender = privateKey(senderSeed);
+ const tx = api.tx.nft.confirmSponsorship(collectionId);
+ const events = await submitTransactionAsync(sender, tx);
+ const result = getGenericResult(events);
+
+ // What to expect
+ expect(result.success).to.be.false;
+ });
+}
+
+export interface CreateFungibleData extends Struct {
+ readonly value: u128;
+};
+
+export interface CreateReFungibleData extends Struct {};
+export interface CreateNftData extends Struct {};
+
+export interface CreateItemData extends Enum {
+ NFT: CreateNftData,
+ Fungible: CreateFungibleData,
+ ReFungible: CreateReFungibleData
+};
+
+export async function createItemExpectSuccess(sender: IKeyringPair, collectionId: number, createMode: string, owner: string = '') {
+ let newItemId: number = 0;
+ await usingApi(async (api) => {
+ const AItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString());
+ const Aitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON();
+ const AItemBalance = new BigNumber(Aitem.Value);
+
+ if (owner === '') owner = sender.address;
+
+ let tx;
+ if (createMode == 'Fungible') {
+ let createData = {fungible: {value: 10}};
+ tx = api.tx.nft.createItem(collectionId, owner, createData);
+ }
+ else {
+ tx = api.tx.nft.createItem(collectionId, owner, createMode);
+ }
+ const events = await submitTransactionAsync(sender, tx);
+ const result = getCreateItemResult(events);
+
+ const BItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString());
+ const Bitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON();
+ const BItemBalance = new BigNumber(Bitem.Value);
+
+ // What to expect
+ expect(result.success).to.be.true;
+ if (createMode == 'Fungible') {
+ expect(BItemBalance.minus(AItemBalance).toNumber()).to.be.equal(10);
+ }
+ else {
+ expect(BItemCount).to.be.equal(AItemCount+1);
+ }
+ expect(collectionId).to.be.equal(result.collectionId);
+ expect(BItemCount).to.be.equal(result.itemId);
+ newItemId = result.itemId;
+ });
+ return newItemId;
+}
+
+export async function enableWhiteListExpectSuccess(sender: IKeyringPair, collectionId: number) {
+ await usingApi(async (api) => {
+
+ // Run the transaction
+ const tx = api.tx.nft.setPublicAccessMode(collectionId, 'WhiteList');
+ const events = await submitTransactionAsync(sender, tx);
+ const result = getGenericResult(events);
+
+ // Get the collection
+ const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(collection.Access).to.be.equal('WhiteList');
+ });
+}
+
+export async function enablePublicMintingExpectSuccess(sender: IKeyringPair, collectionId: number) {
+ await usingApi(async (api) => {
+
+ // Run the transaction
+ const tx = api.tx.nft.setMintPermission(collectionId, true);
+ const events = await submitTransactionAsync(sender, tx);
+ const result = getGenericResult(events);
+
+ // Get the collection
+ const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(collection.MintMode).to.be.equal(true);
+ });
+}
+
+export async function addToWhiteListExpectSuccess(sender: IKeyringPair, collectionId: number, address: string) {
+ await usingApi(async (api) => {
+
+ // Run the transaction
+ const tx = api.tx.nft.addToWhiteList(collectionId, address);
+ const events = await submitTransactionAsync(sender, tx);
+ const result = getGenericResult(events);
+
+ // Get the collection
+ const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(collection.MintMode).to.be.equal(true);
+ });
+}
+
tests/src/util/util.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/util/util.ts
@@ -0,0 +1,35 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+export function strToUTF16(str: string): any {
+ let buf: number[] = [];
+ for (let i=0, strLen=str.length; i < strLen; i++) {
+ buf.push(str.charCodeAt(i));
+ }
+ return buf;
+}
+
+export function utf16ToStr(buf: number[]): string {
+ let str: string = "";
+ for (let i=0, strLen=buf.length; i < strLen; i++) {
+ if (buf[i] != 0) str += String.fromCharCode(buf[i]);
+ else break;
+ }
+ return str;
+}
+
+export function hexToStr(buf: string): string {
+ let str: string = "";
+ let hexStart = buf.indexOf("0x");
+ if (hexStart < 0) hexStart = 0;
+ else hexStart = 2;
+ for (let i=hexStart, strLen=buf.length; i < strLen; i+=2) {
+ let ch = buf[i] + buf[i+1];
+ let num = parseInt(ch, 16);
+ if (num != 0) str += String.fromCharCode(num);
+ else break;
+ }
+ return str;
+}