Skip to content

Commit

Permalink
Referenda functional tests (#184)
Browse files Browse the repository at this point in the history
* submit proposal test added

* place decision deposit test added

* more referenda tests added

* fixed wasm-to-evm test and added bond test
  • Loading branch information
maksym-nyrka authored Sep 18, 2023
1 parent 5ef15b0 commit fde40ce
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 89 deletions.
4 changes: 2 additions & 2 deletions functional-tests/src/common/CommonWasm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {cryptoWaitReady, decodeAddress} from "@polkadot/util-crypto";
import {CodePromise} from "@polkadot/api-contract";

class CommonWasm {
nodeUrl = 'wss://testnet.node.sydney.ggxchain.io'
nodeUrl = 'wss://sydney-archive.dev.ggxchain.io:9944'
mnemonic = 'judge decrease owner toddler face album actor diary require junk crater grape'

constructor() {
Expand All @@ -13,7 +13,7 @@ class CommonWasm {
return new Promise( async (resolve, reject) => {
try {
await cryptoWaitReady();
this.keyring = new Keyring({type: 'sr25519'});
this.keyring = new Keyring({ss58Format: 8886, type: 'sr25519'});
this.account = this.keyring.addFromMnemonic(this.mnemonic);

const provider = new WsProvider(this.nodeUrl);
Expand Down
52 changes: 30 additions & 22 deletions functional-tests/src/common/СommonEvm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Web3 from "web3";
import solc from "solc";

class CommonEvm {
nodeUrl = 'https://testnet.node.sydney.ggxchain.io';
nodeUrl = 'https://sydney-archive.dev.ggxchain.io:9944';
mnemonic = 'movie avoid rack lesson rival rice you average caution eternal distance wood';

constructor() {
Expand Down Expand Up @@ -36,25 +36,31 @@ class CommonEvm {

async compile(sourceCode, contractName) {
return new Promise((resolve, reject) => {
// Create the Solidity Compiler Standard Input and Output JSON
const input = {
language: "Solidity",
sources: {main: {content: sourceCode}},
settings: {outputSelection: {"*": {"*": ["abi", "evm.bytecode"]}}},
};

// Parse the compiler output to retrieve the ABI and Bytecode
const output = solc.compile(JSON.stringify(input));
const artifact = JSON.parse(output).contracts.main[contractName];

resolve({
abi: artifact.abi,
bytecode: artifact.evm.bytecode.object,
});
try {
// Create the Solidity Compiler Standard Input and Output JSON
const input = {
language: "Solidity",
sources: {main: {content: sourceCode}},
settings: {outputSelection: {"*": {"*": ["abi", "evm.bytecode"]}}},
};

// Parse the compiler output to retrieve the ABI and Bytecode
const output = solc.compile(JSON.stringify(input));
const artifact = JSON.parse(output).contracts.main[contractName];

resolve({
abi: artifact.abi,
bytecode: artifact.evm.bytecode.object,
});
} catch (e) {
reject(e);
}
})
}

async deployContract(abi, bytecode) {
const web3 = this.getWeb3();

return new Promise(async (resolve, reject) => {
try {
const accounts = await this.getWeb3().eth.getAccounts();
Expand All @@ -63,18 +69,20 @@ class CommonEvm {
const transactionParameters = {
from: accounts[0],
gas: '3000000',
gasLimit: '3000000'
};

const contract = this.getContract(abi);
const result = await contract.deploy({

await contract.deploy({
data: '0x' + bytecode,
arguments: [true]
})
.send(transactionParameters);

console.log('Contract deployed to', result.options.address);
}).send(transactionParameters).on('receipt', function (receipt) {
console.log('deployContract receipt', receipt);

resolve(result);
const checksummedContractAddress = web3.utils.toChecksumAddress(receipt.contractAddress);
resolve(checksummedContractAddress);
});
} catch (e) {
reject(e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {ContractPromise} from '@polkadot/api-contract';
import contract_file from './flipper.contract.json' assert {type: 'json'};
import xvm_abi from "./xvm_abi.js";
import contract_file from './assets/flipper.contract.json' assert {type: 'json'};
import xvm_abi from "./assets/xvm_abi.js";
import CommonWasm from "../../src/common/CommonWasm.js";
import CommonEvm from "../../src/common/СommonEvm.js";
import {expect} from "chai";
Expand Down Expand Up @@ -35,7 +35,7 @@ describe('EVM to WASM communication', async function () {

//call Flipper.flip() from EVM:
const evmAccount = await commonEvm.getAccount();
console.log(evmAccount)
console.log('evmAccount', evmAccount);

const xvmContractAddress = '0x0000000000000000000000000000000000005005';
const xvmContract = commonEvm.getContract(xvm_abi, xvmContractAddress);
Expand Down Expand Up @@ -68,8 +68,7 @@ describe('EVM to WASM communication', async function () {
const gasLimit = await commonWasm.getGasLimit();

let queryResult = await contractPromise.query.get(
commonWasm.getAccount().address,
{
commonWasm.getAccount().address, {
gasLimit,
storageDepositLimit,
}
Expand Down
48 changes: 0 additions & 48 deletions functional-tests/test/cross-vm-communication/flipper_abi.js

This file was deleted.

13 changes: 6 additions & 7 deletions functional-tests/test/cross-vm-communication/wasm-to-evm.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {expect} from 'chai';
import {ContractPromise} from '@polkadot/api-contract';
import wrapperContractFile from './flipper-wrapper.contract.json' assert {type: 'json'};
import flipper_abi from "./flipper_abi.js";
import wrapperContractFile from './assets/flipper-wrapper.contract.json' assert {type: 'json'};
import * as path from "path";
import {fileURLToPath} from 'url';
import * as fs from "fs";
Expand Down Expand Up @@ -33,11 +32,11 @@ describe('WASM to EVM communication', async function () {
const {abi, bytecode} = await commonEvm.compile(sourceCode, "Flipper");
const evmAccount = await commonEvm.getAccount();

const deployResult = await commonEvm.deployContract(abi, bytecode);
const flipperContractAddress = deployResult.options.address;
const flipperContractAddress = await commonEvm.deployContract(abi, bytecode);
console.log('flipperContractAddress:', flipperContractAddress);
console.log('evmAccount:', evmAccount);

let flipperValueBefore = await evmContractCall(flipper_abi, flipperContractAddress, commonEvm.getWeb3(), evmAccount);
let flipperValueBefore = await getFlipperData(abi, flipperContractAddress, commonEvm.getWeb3(), evmAccount);
console.log('flipperValueBefore: ', flipperValueBefore);

//assertion before method call:
Expand All @@ -56,14 +55,14 @@ describe('WASM to EVM communication', async function () {
.flip({storageDepositLimit, gasLimit}, flipperContractAddress);
await commonWasm.signAndSend(tx, commonWasm.getAccount());

let flipperValueAfter = await evmContractCall(flipper_abi, flipperContractAddress, commonEvm.getWeb3(), evmAccount);
let flipperValueAfter = await getFlipperData(abi, flipperContractAddress, commonEvm.getWeb3(), evmAccount);
console.log('flipperValueAfter: ', flipperValueAfter);

//value must be changed after method call:
expect(flipperValueAfter).to.be.false;
});

async function evmContractCall(abi, address, web3, evmAccount) {
async function getFlipperData(abi, address, web3, evmAccount) {
const contract = new web3.eth.Contract(abi, address);

return await contract.methods.data()
Expand Down
151 changes: 151 additions & 0 deletions functional-tests/test/referenda/referenda.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import CommonWasm from "../../src/common/CommonWasm.js";
import {expect} from "chai";

describe('Referenda', async function () {
this.timeout(60000);

const SYSTEM_REMARK_PREIMAGE_HASH = '0xbbf5004add4e25e7a065b96aca30e2ee7cd5e15c3d91203354b685fbfcc8d09c';
let commonWasm;

before( async () => {
commonWasm = await new CommonWasm().init();

await createPreimageForTests();
})

after(async function () {
await commonWasm.disconnect();
});

it('should able to submit proposal', async function () {
const proposalOrigin = 'system';
const proposal = {'Legacy': SYSTEM_REMARK_PREIMAGE_HASH};
const enactmentMoment = 'After';

const referendumCountBefore = await commonWasm.getApi().query.referenda.referendumCount();
console.log('Referendum count before:', referendumCountBefore.toString());

const proposalExtrinsic = commonWasm.getApi().tx.referenda.submit(
proposalOrigin, proposal, enactmentMoment);
await commonWasm.signAndSend(proposalExtrinsic, commonWasm.getAccount());

const referendumCountAfter = await commonWasm.getApi().query.referenda.referendumCount();
console.log('Referendum count after:', referendumCountAfter.toString());

const referendumInfo = await commonWasm.getApi().query.referenda.referendumInfoFor(referendumCountAfter - 1);
console.log('referendumInfo:', referendumInfo.toJSON());

const referendumPreimageHash = referendumInfo.toJSON().ongoing.proposal.legacy.hash;
expect(referendumPreimageHash).to.be.equal(SYSTEM_REMARK_PREIMAGE_HASH);
expect(referendumCountAfter - referendumCountBefore).to.be.equal(1);
});

it('should able to place decision deposit', async function () {
const referendumIndex = await getCurrentReferendumIndex();
console.log('referendumIndex:', referendumIndex);

const proposalExtrinsic = commonWasm.getApi().tx.referenda.placeDecisionDeposit(referendumIndex);
await commonWasm.signAndSend(proposalExtrinsic, commonWasm.getAccount());

const referendumInfo = await commonWasm.getApi().query.referenda.referendumInfoFor(referendumIndex);
console.log('referendumInfo:', referendumInfo.toJSON());

const referendumDepositAccount = referendumInfo.toJSON().ongoing.decisionDeposit.who;
const referendumDepositAmount = commonWasm.hexToDecimal(referendumInfo.toJSON().ongoing.decisionDeposit.amount);

expect(referendumDepositAccount).to.be.equal(commonWasm.getAccount().address);
expect(referendumDepositAmount).to.be.equal(5e20);
});

it('should be able to set metadata', async () => {
const PREIMAGE_HASH = '0x30d961e7469425942c5c06a020b63c68d25ec5c36caf9bed88c6485da238f848';
const referendumIndex = await getCurrentReferendumIndex();
console.log('referendumIndex:', referendumIndex);

const metadataExtrinsic = commonWasm.getApi().tx.referenda.setMetadata(referendumIndex, PREIMAGE_HASH);
await commonWasm.signAndSend(metadataExtrinsic, commonWasm.getAccount());

const metadataOf = (await commonWasm.getApi().query.referenda.metadataOf(referendumIndex)).toJSON();
console.log('metadataOf:', metadataOf);

expect(metadataOf).to.be.equal(PREIMAGE_HASH);
});

it('should be able to get deciding count', async () => {
const referendumIndex = await getCurrentReferendumIndex();
console.log('referendumIndex:', referendumIndex);

const decidingCount = (await commonWasm.getApi().query.referenda.decidingCount(referendumIndex)).toJSON();
console.log('decidingCount:', decidingCount);

expect(decidingCount).to.be.at.least(1);
});

it('should be able to get referenda metadata', async () => {
const referendumIndex = await getCurrentReferendumIndex();
console.log('referendumIndex:', referendumIndex);

const metadataOf = (await commonWasm.getApi().query.referenda.metadataOf(referendumIndex)).toJSON();
console.log('metadataOf:', metadataOf);

expect(metadataOf).to.match(/0x[0-9a-fA-F]+/);
});

it('should be able to get referenda pallet version', async () => {
const palletVersion = (await commonWasm.getApi().query.referenda.palletVersion()).toJSON();
console.log('palletVersion:', palletVersion);

expect(palletVersion).to.match(/^\d+$/);
});

it('should be able to get referendum count', async () => {
const referendumCount = (await commonWasm.getApi().query.referenda.referendumCount()).toJSON();
console.log('referendumCount:', referendumCount);

expect(referendumCount).to.be.at.least(1);
});

it('should be able to get referendum info', async () => {
const referendumIndex = await getCurrentReferendumIndex();
console.log('referendumIndex:', referendumIndex);

const referendumInfo = await commonWasm.getApi().query.referenda.referendumInfoFor(referendumIndex);
console.log('referendumInfo:', referendumInfo.toJSON());

const proposalHash = referendumInfo.toJSON().ongoing.proposal.legacy.hash;
const enactment = referendumInfo.toJSON().ongoing.enactment.after;
const submitted = referendumInfo.toJSON().ongoing.submitted;
const submissionDepositAccount = referendumInfo.toJSON().ongoing.submissionDeposit.who;
const submissionDepositAmount = commonWasm.hexToDecimal(referendumInfo.toJSON().ongoing.submissionDeposit.amount);

expect(proposalHash).to.match(/0x[0-9a-fA-F]+/);
expect(enactment).to.match(/^\d+$/);
expect(submitted).to.match(/^\d+$/);
expect(submissionDepositAccount).to.be.equal(commonWasm.getAccount().address);
expect(submissionDepositAmount).to.be.equal(1_000_000_000_000_000_000);
});

it('should be able to get referendum track queue', async () => {
const referendumIndex = await getCurrentReferendumIndex();
console.log('referendumIndex:', referendumIndex);

const trackQueue = (await commonWasm.getApi().query.referenda.trackQueue(referendumIndex)).toJSON();
console.log('trackQueue:', trackQueue);

expect(trackQueue).to.be.an('array');
});

async function createPreimageForTests() {
const SYSTEM_REMARK_BYTES = '0x000003';
const preimageStatus = await commonWasm.getApi().query.preimage.statusFor(SYSTEM_REMARK_PREIMAGE_HASH);

if (preimageStatus.toJSON() == null) {
const extrinsic = commonWasm.getApi().tx.preimage.notePreimage(SYSTEM_REMARK_BYTES);
await commonWasm.signAndSend(extrinsic, commonWasm.getAccount());
}
}

async function getCurrentReferendumIndex() {
return await commonWasm.getApi().query.referenda.referendumCount() - 1;
}
});
Loading

0 comments on commit fde40ce

Please sign in to comment.