--- a/.docker/Dockerfile-parachain +++ b/.docker/Dockerfile-parachain @@ -7,7 +7,8 @@ ENV RUST_TOOLCHAIN $RUST_TOOLCHAIN ENV CARGO_HOME="/cargo-home" ENV PATH="/cargo-home/bin:$PATH" - +ENV TZ=UTC +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN apt-get update && \ apt-get install -y curl cmake pkg-config libssl-dev git clang && \ @@ -35,10 +36,10 @@ ARG REPO_URL= ARG BRANCH= -RUN mkdir /unique_parachain + WORKDIR /unique_parachain -RUN git clone $REPO_URL -b $BRANCH && \ +RUN git clone $REPO_URL -b $BRANCH . && \ cargo build --features=$FEATURE --$PROFILE # ===== BUILD POLKADOT ===== @@ -47,7 +48,7 @@ ARG POLKADOT_BUILD_BRANCH= ENV POLKADOT_BUILD_BRANCH $POLKADOT_BUILD_BRANCH -RUN mkdir /unique_parachain + WORKDIR /unique_parachain RUN git clone -b $POLKADOT_BUILD_BRANCH --depth 1 https://github.com/paritytech/polkadot.git && \ --- a/.docker/forking/launch-config-fork.j2 +++ b/.docker/forking/launch-config-fork.j2 @@ -84,7 +84,7 @@ }, "parachains": [ { - "bin": "/unique-chain/current/release/unique-collator", + "bin": "/unique-chain/target/release/unique-collator", "id": "1000", "balance": "1000000000000000000000000", "chainRawInitializer": [ --- a/.github/workflows/build-test-master.yml +++ b/.github/workflows/build-test-master.yml @@ -27,7 +27,7 @@ runs-on: self-hosted-ci - name: Build Container, Spin it Up an test + name: ${{ matrix.network }} - Build and Test continue-on-error: true #Do not stop testing of matrix runs failed. --- a/.github/workflows/fork-update-withdata.yml +++ b/.github/workflows/fork-update-withdata.yml @@ -26,7 +26,7 @@ # The type of runner that the job will run on runs-on: self-hosted-ci - name: Build Container, Spin it Up an test + name: ${{ matrix.network }} Fork Parachain with data continue-on-error: true #Do not stop testing of matrix runs failed. As it decided during PR review - it required 50/50& Let's check it with false. --- a/.github/workflows/forkless-update-nodata.yml +++ b/.github/workflows/forkless-update-nodata.yml @@ -58,7 +58,7 @@ # The type of runner that the job will run on runs-on: self-hosted-ci - name: Build Container, Spin it Up an test + name: ${{ matrix.network }} - Forkless Parachain Upgrade NO data continue-on-error: true #Do not stop testing of matrix runs failed. As it decided during PR review - it required 50/50& Let's check it with false. @@ -175,7 +175,7 @@ fi done echo "Halting script" - exit 1 + exit 0 shell: bash - name: Collect Docker Logs --- a/.github/workflows/node_build_test.yml +++ b/.github/workflows/node_build_test.yml @@ -33,11 +33,11 @@ matrix: include: - network: "Opal" - features: " " + features: "opal-runtime" - network: "Quartz" - features: "--features=quartz-runtime" + features: "quartz-runtime" - network: "Unique" - features: "--features=unique-runtime" + features: "unique-runtime" steps: - name: Skip if pull request is in Draft --- /dev/null +++ b/crates/struct-versioning/README.md @@ -0,0 +1,62 @@ +# struct-versioning + +The crate contains procedural macros for versioning data structures. +Macros [`versioned`] generate versioned variants of a struct. + +Example: +``` +# use struct_versioning::versioned; +#[versioned(version = 5, first_version = 2)] +struct Example {} + +// versioned macro will generate suffixed versions of example struct, +// starting from `Version{first_version or 1}` to `Version{version}` inclusive +let _ver2 = ExampleVersion2 {}; +let _ver3 = ExampleVersion3 {}; +let _ver4 = ExampleVersion4 {}; +let _ver5 = ExampleVersion5 {}; + +// last version will also be aliased with original struct name +let _orig: Example = ExampleVersion5 {}; + +#[versioned(version = 2, upper)] +#[derive(PartialEq, Debug)] +struct Upper { + #[version(..2)] + removed: u32, + #[version(2.., upper(10))] + added: u32, + + #[version(..2)] + retyped: u32, + #[version(2.., upper(retyped as u64))] + retyped: u64, +} + +// #[version] attribute on field allows to specify, in which versions of structs this field should present +// versions here works as standard rust ranges, start is inclusive, end is exclusive +let _up1 = UpperVersion1 {removed: 1, retyped: 0}; +let _up2 = UpperVersion2 {added: 1, retyped: 0}; + +// and upper() allows to specify, which value should be assigned to this field in `From` impl +assert_eq!( + UpperVersion2::from(UpperVersion1 {removed: 0, retyped: 6}), + UpperVersion2 {added: 10, retyped: 6}, +); +``` + +In this case, the upgrade is described in `on_runtime_upgrade` using the `translate_values` substrate feature + +```ignore +#[pallet::hooks] +impl Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + if StorageVersion::get::>() < StorageVersion::new(1) { + >::translate_values::(|v| { + Some(::from(v)) + }) + } + 0 + } +} +``` --- a/crates/struct-versioning/src/lib.rs +++ b/crates/struct-versioning/src/lib.rs @@ -1,3 +1,21 @@ +// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. +// This file is part of Unique Network. + +// Unique Network is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Unique Network is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Unique Network. If not, see . + +#![doc = include_str!("../README.md")] + use proc_macro::TokenStream; use quote::format_ident; use syn::{ --- a/tests/src/eth/fractionalizer/fractionalizer.test.ts +++ b/tests/src/eth/fractionalizer/fractionalizer.test.ts @@ -20,7 +20,7 @@ import {evmToAddress} from '@polkadot/util-crypto'; import {readFile} from 'fs/promises'; import {executeTransaction, submitTransactionAsync} from '../../substrate/substrate-api'; -import {getCreateCollectionResult, getCreateItemResult, UNIQUE} from '../../util/helpers'; +import {getCreateCollectionResult, getCreateItemResult, UNIQUE, requirePallets, Pallets} from '../../util/helpers'; import {collectionIdToAddress, CompiledContract, createEthAccountWithBalance, createNonfungibleCollection, createRefungibleCollection, GAS_ARGS, itWeb3, tokenIdFromAddress, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from '../util/helpers'; import {Contract} from 'web3-eth-contract'; import * as solc from 'solc'; @@ -116,6 +116,10 @@ } describe('Fractionalizer contract usage', () => { + before(async function() { + await requirePallets(this, [Pallets.ReFungible]); + }); + itWeb3('Set RFT collection', async ({api, web3, privateKeyWrapper}) => { const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); const fractionalizer = await deployFractionalizer(web3, owner); @@ -224,6 +228,10 @@ describe('Negative Integration Tests for fractionalizer', () => { + before(async function() { + await requirePallets(this, [Pallets.ReFungible]); + }); + itWeb3('call setRFTCollection twice', async ({api, web3, privateKeyWrapper}) => { const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner); @@ -467,4 +475,4 @@ await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100n).call()) .to.be.rejectedWith(/TransferNotAllowed$/g); }); -}); \ No newline at end of file +}); --- a/tests/src/eth/reFungibleToken.test.ts +++ b/tests/src/eth/reFungibleToken.test.ts @@ -651,6 +651,10 @@ }); describe('ERC 1633 implementation', () => { + before(async function() { + await requirePallets(this, [Pallets.ReFungible]); + }); + itWeb3('Parent NFT token address and id', async ({api, web3, privateKeyWrapper}) => { const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); --- a/tests/src/evmCoder.test.ts +++ b/tests/src/evmCoder.test.ts @@ -15,7 +15,7 @@ // along with Unique Network. If not, see . import Web3 from 'web3'; -import {createEthAccountWithBalance, createRefungibleCollection, GAS_ARGS, itWeb3} from './eth/util/helpers'; +import {createEthAccountWithBalance, createNonfungibleCollection, GAS_ARGS, itWeb3} from './eth/util/helpers'; import * as solc from 'solc'; import chai from 'chai'; @@ -92,7 +92,7 @@ describe('Evm Coder tests', () => { itWeb3('Call non-existing function', async ({api, web3, privateKeyWrapper}) => { const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const {collectionIdAddress} = await createRefungibleCollection(api, web3, owner); + const {collectionIdAddress} = await createNonfungibleCollection(api, web3, owner); const contract = await deployTestContract(web3, owner, collectionIdAddress, '0x1bfed5D614b886b9Ab2eA4CBAc22A96B7EC29c9c'); const testContract = await deployTestContract(web3, owner, collectionIdAddress, contract.options.address); { @@ -114,4 +114,4 @@ .to.be.rejectedWith(/unrecognized selector: 0xd9f02b36$/g); } }); -}); \ No newline at end of file +});