--- a/.docker/Dockerfile-try-runtime +++ b/.docker/Dockerfile-try-runtime @@ -46,5 +46,4 @@ echo "Fork from: $REPLICA_FROM\n" && \ cargo build --features=$FEATURE --release - -CMD cargo run --features=try-runtime,$FEATURE --release -- try-runtime on-runtime-upgrade live --uri $REPLICA_FROM +CMD cargo run --features=try-runtime,$FEATURE --release -- try-runtime --no-spec-name-check on-runtime-upgrade live --uri $REPLICA_FROM --- a/.github/workflows/market-test_v2.yml +++ b/.github/workflows/market-test_v2.yml @@ -91,12 +91,20 @@ rm -rf .env cp .env.docker .env +# Temporary disable node readyness check. Have to dig into the script logic. +# - name: Wait for chain up and running +# working-directory: tests +# run: | +# yarn install +# node scripts/readyness.js +# echo "Ready to start tests" +# env: +# RPC_URL: http://127.0.0.1:9933/ + - name: Wait for chain up and running - working-directory: tests run: | - yarn install - node scripts/readyness.js - echo "Ready to start tests" + sleep 1200s + echo "Ready to start Market e2e tests" - name: Show content of .env file and Generate accounts working-directory: qa-tests @@ -184,7 +192,6 @@ - name: Clean Workspace if: always() uses: AutoModality/action-clean@v1.1.0 - --- a/.github/workflows/node-only-update_v2.yml +++ b/.github/workflows/node-only-update_v2.yml @@ -47,8 +47,6 @@ # The type of runner that the job will run on runs-on: [self-hosted-ci,large] - - timeout-minutes: 2880 # 48 hours for execution jobs. name: ${{ matrix.network }} @@ -169,7 +167,7 @@ yarn add mochawesome echo "Ready to start tests" yarn polkadot-types - NOW=$(date +%s) && yarn test --reporter mochawesome --reporter-options reportFilename=test-${NOW} + NOW=$(date +%s) && yarn test --reporter mochawesome --reporter-options reportFilename=test-before-${NOW} env: RPC_URL: http://127.0.0.1:9933/ @@ -179,11 +177,10 @@ if: success() || failure() # run this step even if previous step failed with: name: Tests before node upgrade ${{ matrix.network }} # Name of the check run which will be created - path: ${{ matrix.mainnet_branch }}/tests/mochawesome-report/test-*.json # Path to test results + path: ${{ matrix.mainnet_branch }}/tests/mochawesome-report/test-before-*.json # Path to test results reporter: mochawesome-json fail-on-error: 'false' - # TODO uncomment thease steps after the merge #- name: Run Parallel tests before Node Parachain upgrade # working-directory: ${{ matrix.mainnet_branch }}/tests @@ -229,8 +226,11 @@ #Get PID of polkadot-launch ContainerID=$(docker ps -aqf "name=node-parachain") PID=$(docker exec node-parachain pidof 'polkadot-launch') - echo "Polkadot-launch PID: $PID" - #Send SIGUSR1 signal to $PID + sleep 30s + echo -e "Show logs of node-parachain container.\n" + docker logs ${ContainerID} + echo -e "\n" + echo -e "Restart polkadot-launch process: $PID\n" docker exec node-parachain kill -SIGUSR1 ${PID} echo "SIGUSR1 sent to Polkadot-launch PID: $PID" docker logs ${ContainerID} @@ -243,9 +243,8 @@ docker exec node-parachain cat /polkadot-launch/alice.log docker exec node-parachain cat /polkadot-launch/eve.log docker exec node-parachain cat /polkadot-launch/dave.log - docker exec node-parachain cat /polkadot-launch/charlie.log + docker exec node-parachain cat /polkadot-launch/charlie.log - # 🌗 All parachain collators restarted with the new binaries. - name: Check if docker logs consist messages related to testing of Node Parachain Upgrade. if: success() run: | @@ -297,10 +296,9 @@ run: | yarn install yarn add mochawesome - node scripts/readyness.js echo "Ready to start tests" yarn polkadot-types - NOW=$(date +%s) && yarn test --reporter mochawesome --reporter-options reportFilename=test-${NOW} + NOW=$(date +%s) && yarn test --reporter mochawesome --reporter-options reportFilename=test-after-${NOW} env: RPC_URL: http://127.0.0.1:9933/ @@ -310,7 +308,7 @@ if: success() || failure() # run this step even if previous step failed with: name: Tests after node upgrade ${{ matrix.network }} # Name of the check run which will be created - path: ${{ matrix.mainnet_branch }}/tests/mochawesome-report/test-*.json # Path to test results + path: ${{ matrix.mainnet_branch }}/tests/mochawesome-report/test-after-*.json # Path to test results reporter: mochawesome-json fail-on-error: 'false' --- a/Cargo.lock +++ b/Cargo.lock @@ -6711,6 +6711,24 @@ ] [[package]] +name = "pallet-unique-scheduler-v2" +version = "0.1.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-preimage", + "parity-scale-codec 3.2.1", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "substrate-test-utils", +] + +[[package]] name = "pallet-utility" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.29#cc370aa61e15c18d23a2f686b812fd576a630afe" @@ -8576,7 +8594,7 @@ [[package]] name = "quartz-runtime" -version = "0.9.27" +version = "0.9.29" dependencies = [ "app-promotion-rpc", "cumulus-pallet-aura-ext", @@ -12568,7 +12586,7 @@ [[package]] name = "unique-runtime" -version = "0.9.27" +version = "0.9.29" dependencies = [ "app-promotion-rpc", "cumulus-pallet-aura-ext", --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ ``` git clone https://github.com/paritytech/polkadot.git cd polkadot -git checkout release-v0.9.27 +git checkout release-v0.9.29 cargo build --release ``` --- a/runtime/common/construct_runtime/mod.rs +++ b/runtime/common/construct_runtime/mod.rs @@ -57,8 +57,8 @@ Inflation: pallet_inflation::{Pallet, Call, Storage} = 60, Unique: pallet_unique::{Pallet, Call, Storage, Event} = 61, - #[runtimes(opal)] - Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event} = 62, + // #[runtimes(opal)] + // Scheduler: pallet_unique_scheduler::{Pallet, Call, Storage, Event} = 62, Configuration: pallet_configuration::{Pallet, Call, Storage} = 63, --- a/runtime/common/mod.rs +++ b/runtime/common/mod.rs @@ -20,7 +20,10 @@ pub mod ethereum; pub mod instance; pub mod runtime_apis; + +#[cfg(feature = "scheduler")] pub mod scheduler; + pub mod sponsoring; pub mod weights; --- a/runtime/opal/Cargo.toml +++ b/runtime/opal/Cargo.toml @@ -168,7 +168,7 @@ "pallet-foreign-assets/std" ] limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing'] -opal-runtime = ['refungible', 'scheduler', 'rmrk', 'app-promotion', 'foreign-assets'] +opal-runtime = ['refungible', 'rmrk', 'app-promotion', 'foreign-assets'] refungible = [] scheduler = [] --- a/runtime/opal/src/lib.rs +++ b/runtime/opal/src/lib.rs @@ -50,7 +50,7 @@ spec_name: create_runtime_str!(RUNTIME_NAME), impl_name: create_runtime_str!(RUNTIME_NAME), authoring_version: 1, - spec_version: 927030, + spec_version: 929030, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, --- a/runtime/quartz/Cargo.toml +++ b/runtime/quartz/Cargo.toml @@ -10,7 +10,7 @@ license = 'GPLv3' name = 'quartz-runtime' repository = 'https://github.com/UniqueNetwork/unique-chain' -version = '0.9.27' +version = '0.9.29' [package.metadata.docs.rs] targets = ['x86_64-unknown-linux-gnu'] --- a/runtime/quartz/src/lib.rs +++ b/runtime/quartz/src/lib.rs @@ -50,7 +50,7 @@ spec_name: create_runtime_str!(RUNTIME_NAME), impl_name: create_runtime_str!(RUNTIME_NAME), authoring_version: 1, - spec_version: 927030, + spec_version: 929030, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, --- a/runtime/unique/Cargo.toml +++ b/runtime/unique/Cargo.toml @@ -10,7 +10,7 @@ license = 'GPLv3' name = 'unique-runtime' repository = 'https://github.com/UniqueNetwork/unique-chain' -version = '0.9.27' +version = '0.9.29' [package.metadata.docs.rs] targets = ['x86_64-unknown-linux-gnu'] --- a/runtime/unique/src/lib.rs +++ b/runtime/unique/src/lib.rs @@ -50,7 +50,7 @@ spec_name: create_runtime_str!(RUNTIME_NAME), impl_name: create_runtime_str!(RUNTIME_NAME), authoring_version: 1, - spec_version: 927030, + spec_version: 929030, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, --- a/tests/scripts/readyness.js +++ b/tests/scripts/readyness.js @@ -25,6 +25,7 @@ } catch(e) { await sleep(10000); + console.log(e); } } } --- /dev/null +++ b/tests/src/eth/proxyContract.test.ts @@ -0,0 +1,152 @@ +// 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 . + +import {IKeyringPair} from '@polkadot/types/types'; + +import {itEth, expect, usingEthPlaygrounds, EthUniqueHelper} from './util'; + +describe('EVM payable contracts', () => { + let donor: IKeyringPair; + + before(async function() { + await usingEthPlaygrounds(async (_, privateKey) => { + donor = await privateKey({filename: __filename}); + }); + }); + + itEth('Update proxy contract', async({helper}) => { + const deployer = await helper.eth.createAccountWithBalance(donor); + const caller = await helper.eth.createAccountWithBalance(donor); + const proxyContract = await deployProxyContract(helper, deployer); + + const realContractV1 = await deployRealContractV1(helper, deployer); + const realContractV1proxy = new helper.web3!.eth.Contract(realContractV1.options.jsonInterface, proxyContract.options.address, {from: caller, gas: helper.eth.DEFAULT_GAS}); + await proxyContract.methods.updateVersion(realContractV1.options.address).send(); + + await realContractV1proxy.methods.flip().send(); + await realContractV1proxy.methods.flip().send(); + await realContractV1proxy.methods.flip().send(); + const value1 = await realContractV1proxy.methods.getValue().call(); + const flipCount1 = await realContractV1proxy.methods.getFlipCount().call(); + expect(flipCount1).to.be.equal('3'); + expect(value1).to.be.equal(true); + + const realContractV2 = await deployRealContractV2(helper, deployer); + const realContractV2proxy = new helper.web3!.eth.Contract(realContractV2.options.jsonInterface, proxyContract.options.address, {from: caller, gas: helper.eth.DEFAULT_GAS}); + await proxyContract.methods.updateVersion(realContractV2.options.address).send(); + + await realContractV2proxy.methods.flip().send(); + await realContractV2proxy.methods.flip().send(); + await realContractV2proxy.methods.setStep(5).send(); + await realContractV2proxy.methods.increaseFlipCount().send(); + const value2 = await realContractV2proxy.methods.getValue().call(); + const flipCount2 = await realContractV2proxy.methods.getFlipCount().call(); + expect(value2).to.be.equal(true); + expect(flipCount2).to.be.equal('6'); + }); + + async function deployProxyContract(helper: EthUniqueHelper, deployer: string) { + return await helper.ethContract.deployByCode(deployer, 'ProxyContract', ` + // SPDX-License-Identifier: UNLICENSED + pragma solidity ^0.8.6; + + contract ProxyContract { + event NewEvent(uint data); + receive() external payable {} + bytes32 private constant implementationSlot = bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1); + constructor() {} + function updateVersion(address newContractAddress) external { + bytes32 slot = implementationSlot; + assembly { + sstore(slot, newContractAddress) + } + } + fallback() external { + bytes32 slot = implementationSlot; + assembly { + let ptr := mload(0x40) + let contractAddress := sload(slot) + + calldatacopy(ptr, 0, calldatasize()) + + let result := delegatecall(gas(), contractAddress, ptr, calldatasize(), 0, 0) + let size := returndatasize() + + returndatacopy(ptr, 0, size) + + switch result + case 0 { revert(ptr, size) } + default { return(ptr, size) } + } + } + } + + interface RealContract { + function flip() external; + function getValue() external view returns (bool); + function getFlipCount() external view returns (uint); + }`); + } + + async function deployRealContractV1(helper: EthUniqueHelper, deployer: string) { + return await helper.ethContract.deployByCode(deployer, 'RealContractV1', ` + // SPDX-License-Identifier: UNLICENSED + pragma solidity ^0.8.6; + + contract RealContractV1 { + bool value = false; + uint flipCount = 0; + function flip() external { + value = !value; + flipCount++; + } + function getValue() external view returns (bool) { + return value; + } + function getFlipCount() external view returns (uint) { + return flipCount; + } + }`); + } + + async function deployRealContractV2(helper: EthUniqueHelper, deployer: string) { + return await helper.ethContract.deployByCode(deployer, 'RealContractV2', ` + // SPDX-License-Identifier: UNLICENSED + pragma solidity ^0.8.6; + + contract RealContractV2 { + bool value = false; + uint flipCount = 10; + uint step = 1; + function flip() external { + value = !value; + flipCount--; + } + function setStep(uint value) external { + step = value; + } + function increaseFlipCount() external { + flipCount = flipCount + step; + } + function getValue() external view returns (bool) { + return value; + } + function getFlipCount() external view returns (uint) { + return flipCount; + } + }`); + } +}); \ No newline at end of file