Skip to content

Commit

Permalink
Polkadot: Integration tests use Polkadot v1.0.0 node (hyperledger#1482)
Browse files Browse the repository at this point in the history
Update integration tests to use the latest CI node build containing a substrate node built against `polkadot-v1.0.0`.
  • Loading branch information
xermicus committed Aug 9, 2023
1 parent 0c93f3e commit 586bb3c
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 56 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ jobs:
# We can't run substrate node as a github actions service, since it requires
# command line arguments. See https://github.com/actions/runner/pull/1152
- name: Start substrate contracts node
run: echo id=$(docker run -d -p 9944:9944 ghcr.io/hyperledger/solang-substrate-ci:e41a9c0 substrate-contracts-node --dev --ws-external) >> $GITHUB_OUTPUT
run: echo id=$(docker run -d -p 9944:9944 ghcr.io/hyperledger/solang-substrate-ci:054bef6 substrate-contracts-node --dev --rpc-external) >> $GITHUB_OUTPUT
id: substrate
- uses: actions/setup-node@v3
with:
Expand Down Expand Up @@ -358,7 +358,7 @@ jobs:
# We can't run substrate node as a github actions service, since it requires
# command line arguments. See https://github.com/actions/runner/pull/1152
- name: Start substrate
run: echo id=$(docker run -d -p 9944:9944 ghcr.io/hyperledger/solang-substrate-ci:e41a9c0 substrate-contracts-node --dev --ws-external) >> $GITHUB_OUTPUT
run: echo id=$(docker run -d -p 9944:9944 ghcr.io/hyperledger/solang-substrate-ci:054bef6 substrate-contracts-node --dev --rpc-external) >> $GITHUB_OUTPUT
id: substrate
- uses: actions/download-artifact@master
with:
Expand Down
22 changes: 19 additions & 3 deletions integration/polkadot/UniswapV2ERC20.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('Deploy UniswapV2ERC20 contract and test', () => {
})

it('transfer', async () => {
let gasLimit = await weight(conn, token, "approve", [dave.address, TEST_AMOUNT]);
let gasLimit = await weight(conn, token, "transfer", [dave.address, TEST_AMOUNT]);
let tx = token.tx.transfer({ gasLimit }, dave.address, TEST_AMOUNT);
await transaction(tx, alice);

Expand All @@ -90,7 +90,15 @@ describe('Deploy UniswapV2ERC20 contract and test', () => {
let tx = token.tx.approve({ gasLimit }, dave.address, TEST_AMOUNT);
await transaction(tx, alice);

tx = token.tx.transferFrom({ gasLimit }, alice.address, dave.address, TEST_AMOUNT);
const dryRun = await conn.call.contractsApi.call(
dave.address,
token.address,
0,
null,
null,
token.abi.findMessage("transferFrom").toU8a([alice.address, dave.address, TEST_AMOUNT])
);
tx = token.tx.transferFrom({ gasLimit: dryRun.gasRequired }, alice.address, dave.address, TEST_AMOUNT);
await transaction(tx, dave);

const { output: allowance } = await query(conn, alice, token, "allowance", [alice.address, dave.address]);
Expand All @@ -106,7 +114,15 @@ describe('Deploy UniswapV2ERC20 contract and test', () => {
let tx = token.tx.approve({ gasLimit }, dave.address, MAX_UINT256);
await transaction(tx, alice);

tx = token.tx.transferFrom({ gasLimit }, alice.address, dave.address, TEST_AMOUNT);
const dryRun = await conn.call.contractsApi.call(
dave.address,
token.address,
0,
null,
null,
token.abi.findMessage("transferFrom").toU8a([alice.address, dave.address, TEST_AMOUNT])
);
tx = token.tx.transferFrom({ gasLimit: dryRun.gasRequired }, alice.address, dave.address, TEST_AMOUNT);
await transaction(tx, dave);

const { output: allowance } = await query(conn, alice, token, "allowance", [alice.address, dave.address]);
Expand Down
8 changes: 7 additions & 1 deletion integration/polkadot/array_struct_mapping_storage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,23 @@ describe('Deploy array_struct_mapping_storage contract and test', () => {
await transaction(tx, alice);

// let's add two elements to our array
gasLimit = await weight(conn, contract, "push", []);
tx = contract.tx.push({ gasLimit });

await transaction(tx, alice);

gasLimit = await weight(conn, contract, "push", []);
tx = contract.tx.push({ gasLimit });

await transaction(tx, alice);

// set some values
for (let array_no = 0; array_no < 2; array_no += 1) {
for (let i = 0; i < 10; i += 1) {
tx = contract.tx.set({ gasLimit }, array_no, 102 + i + array_no * 500, 300331 + i);
let index = 102 + i + array_no * 500;
let val = 300331 + i;
gasLimit = await weight(conn, contract, "set", [array_no, index, val]);
tx = contract.tx.set({ gasLimit }, array_no, index, val);

await transaction(tx, alice);
}
Expand All @@ -49,6 +54,7 @@ describe('Deploy array_struct_mapping_storage contract and test', () => {
}

// delete one and try again
gasLimit = await weight(conn, contract, "rm", [0, 104]);
tx = contract.tx.rm({ gasLimit }, 0, 104);

await transaction(tx, alice);
Expand Down
4 changes: 2 additions & 2 deletions integration/polkadot/asserts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ describe('Deploy asserts contract and test', () => {
throw new Error("should not succeed");
}, (res) => res);

// Error 24 is ContractReverted
expect(res2.dispatchError.toHuman()).toEqual({ "Module": { "error": "0x18000000", "index": "8" } });
// Error 25 is ContractReverted
expect(res2.dispatchError.toHuman()).toEqual({ "Module": { "error": "0x19000000", "index": "8" } });

let res3 = await query(conn, alice, contract, "var");

Expand Down
4 changes: 3 additions & 1 deletion integration/polkadot/balances.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('Deploy balances contract and test', () => {

expect(contractRpcBal?.toString()).toBe(contractQueryBalBefore.toString());

let gasLimit = await weight(conn, contract, "payMe");
let gasLimit = await weight(conn, contract, "payMe", undefined, 1000000n);
let tx = contract.tx.payMe({ gasLimit, value: 1000000n });

await transaction(tx, alice);
Expand All @@ -41,6 +41,7 @@ describe('Deploy balances contract and test', () => {

let { data: { free: daveBal1 } } = await conn.query.system.account(dave.address);

gasLimit = await weight(conn, contract, "transfer", [dave.address, 20000]);
let tx1 = contract.tx.transfer({ gasLimit }, dave.address, 20000);

await transaction(tx1, alice);
Expand All @@ -49,6 +50,7 @@ describe('Deploy balances contract and test', () => {

expect(daveBal2.toBigInt()).toEqual(daveBal1.toBigInt() + 20000n);

gasLimit = await weight(conn, contract, "transfer", [dave.address, 10000]);
let tx2 = contract.tx.send({ gasLimit }, dave.address, 10000);

await transaction(tx2, alice);
Expand Down
1 change: 1 addition & 0 deletions integration/polkadot/builtins2.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('Deploy builtins2 contract and test', () => {
// Gas metering is based on execution time:
// Expect each call to burn between 10000..1000000 more gas than the previous iteration.
for (let i = 1; i < 100; i++) {
gasLimit = await weight(conn, contract, "burnGas", [i]);
let { output: gas_left } = await query(conn, alice, contract, "burnGas", [i], undefined, convertWeight(gasLimit).v2Weight);
let gas = BigInt(gas_left!.toString());
expect(gasLimit.toJSON().refTime).toBeGreaterThan(gas);
Expand Down
4 changes: 2 additions & 2 deletions integration/polkadot/call_flags.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ describe('Deploy the CallFlags contract and tests for various call flag combinat
const flags = [CallFlags.TAIL_CALL];
const answer = await query(conn, alice, contract, "echo", [contract.address, foo, voyager, flags]);
const { index, error } = answer.result.asErr.asModule;
// Module 8 error 0x14 is ReentranceDenied in the contracts pallet
// Module 8 error 0x15 is ReentranceDenied in the contracts pallet
expect(index.toJSON()).toStrictEqual(8);
expect(error.toJSON()).toStrictEqual("0x14000000");
expect(error.toJSON()).toStrictEqual("0x15000000");
});

it('fails with the input forwarding flag', async function () {
Expand Down
12 changes: 6 additions & 6 deletions integration/polkadot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"test": "tsc; ts-mocha -t 20000 --exit *.spec.ts",
"build": "./build.sh",
"build-ink": "docker run --rm -v $(pwd)/ink/caller:/opt/contract ghcr.io/hyperledger/solang-substrate-ci:e41a9c0 cargo contract build --release --manifest-path /opt/contract/Cargo.toml"
"build-ink": "docker run --rm -v $(pwd)/ink/caller:/opt/contract ghcr.io/hyperledger/solang-substrate-ci:054bef6 cargo contract build --release --manifest-path /opt/contract/Cargo.toml"
},
"contributors": [
{
Expand All @@ -30,11 +30,11 @@
"typescript": "^4.7"
},
"dependencies": {
"@polkadot/api": "^10.6",
"@polkadot/api-contract": "^10.6",
"@polkadot/keyring": "^12.1",
"@polkadot/types": "^10.6",
"@polkadot/util-crypto": "^12.1",
"@polkadot/api": "^10.9",
"@polkadot/api-contract": "^10.9",
"@polkadot/keyring": "^12.3",
"@polkadot/types": "^10.9",
"@polkadot/util-crypto": "^12.3",
"websnark": "git+https://github.com/tornadocash/websnark.git#4c0af6a8b65aabea3c09f377f63c44e7a58afa6d",
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
"circomlib": "git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc",
Expand Down
12 changes: 6 additions & 6 deletions integration/subxt-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ license = "Apache-2.0"
[dependencies]
anyhow = "1.0.71"
async-trait = "0.1.68"
sp-core = "20.0.0"
sp-runtime = "23.0.0"
sp-weights = "19.0.0"
pallet-contracts-primitives = "23.0.0"
sp-core = "21.0.0"
sp-runtime = "24.0.0"
sp-weights = "20.0.0"
pallet-contracts-primitives = "24.0.0"
hex = "0.4.3"
num-bigint = "0.4.3"
once_cell = "1.17.2"
parity-scale-codec = { version = "3.5.0", features = ["derive"] }
rand = "0.8.5"
serde_json = "1.0.96"
sp-keyring = "23.0.0"
subxt = "0.28.0"
sp-keyring = "24.0.0"
subxt = { version = "0.31.0", features = ["substrate-compat"] }
tokio = {version = "1.28.2", features = ["rt-multi-thread", "macros", "time"]}
contract-metadata = "3.0.1"
contract-transcode = "3.0.1"
Expand Down
Binary file modified integration/subxt-tests/metadata.scale
Binary file not shown.
9 changes: 6 additions & 3 deletions integration/subxt-tests/src/cases/asserts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use contract_transcode::ContractMessageTranscoder;
use hex::FromHex;
use parity_scale_codec::{Decode, Encode};
use sp_core::hexdisplay::AsBytesRef;
use subxt::metadata::ErrorMetadata;
use subxt::error::MetadataError;

use crate::API;

Expand Down Expand Up @@ -55,8 +55,11 @@ async fn case() -> anyhow::Result<()> {
0,
&|t: &ContractMessageTranscoder| t.encode::<_, String>("test_assert_rpc", []).unwrap(),
)
.await;
assert!(res.unwrap_err().to_string().contains("ContractReverted"));
.await
.unwrap_err();
assert!(res
.to_string()
.contains("ModuleError { index: 8, error: [25, 0, 0, 0] }"));

// state should not change after failed operation
let rv = contract
Expand Down
1 change: 0 additions & 1 deletion integration/subxt-tests/src/cases/flipper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,5 @@ async fn case() -> anyhow::Result<()> {
.and_then(|v| <bool>::decode(&mut v.as_bytes_ref()).map_err(Into::into))?;

assert!(!updated);

Ok(())
}
2 changes: 1 addition & 1 deletion integration/subxt-tests/src/cases/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use num_bigint::{BigInt, BigUint, Sign};
use parity_scale_codec::{Decode, Encode, Input};
use sp_core::{crypto::AccountId32, hexdisplay::AsBytesRef, keccak_256, KeccakHasher, H256, U256};
use sp_runtime::{assert_eq_error_rate, scale_info::TypeInfo};
use subxt::ext::sp_runtime::{traits::One, MultiAddress};
use sp_runtime::{traits::One, MultiAddress};

use crate::{Contract, DeployContract, Execution, ReadContract, WriteContract, API};

Expand Down
61 changes: 33 additions & 28 deletions integration/subxt-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@

use contract_transcode::ContractMessageTranscoder;

use node::runtime_types::pallet_contracts::wasm::Determinism;
use node::runtime_types::{
contracts_node_runtime::RuntimeEvent,
frame_system::EventRecord,
pallet_contracts::wasm::Determinism,
sp_weights::weight_v2::{self, Weight},
};
use pallet_contracts_primitives::{
ContractExecResult, ContractResult, ExecReturnValue, GetStorageResult,
};
use parity_scale_codec::{Decode, Encode};

use sp_core::{crypto::AccountId32, hexdisplay::AsBytesRef, Bytes};
use sp_weights::Weight;
use sp_runtime::{DispatchError, ModuleError};
use subxt::{
blocks::ExtrinsicEvents as TxEvents,
ext::sp_runtime::DispatchError,
tx::PairSigner,
utils::{MultiAddress, Static},
utils::{MultiAddress, Static, H256},
Config, OnlineClient, PolkadotConfig,
};

Expand All @@ -30,13 +34,7 @@ use tokio::time::timeout;
mod cases;

// metadata file obtained from the latest substrate-contracts-node
#[subxt::subxt(
runtime_metadata_path = "./metadata.scale",
substitute_type(
type = "sp_weights::weight_v2::Weight",
with = "::subxt::utils::Static<::sp_weights::Weight>"
)
)]
#[subxt::subxt(runtime_metadata_path = "./metadata.scale")]
pub mod node {}

pub type API = OnlineClient<PolkadotConfig>;
Expand Down Expand Up @@ -175,12 +173,6 @@ impl Execution for WriteContract {
.ok()
.flatten()
}) {
if let node::runtime_types::sp_runtime::DispatchError::Module(e) = &e.dispatch_error {
if let Ok(details) = api.metadata().error(e.index, e.error[0]) {
return Err(anyhow::anyhow!("{details:?}"));
}
}

return Err(anyhow::anyhow!("{e:?}"));
}

Expand Down Expand Up @@ -268,7 +260,10 @@ async fn raw_instantiate_and_upload(

let payload = node::tx().contracts().instantiate_with_code(
value,
Static::from(sp_weights::Weight::from(gas_limit)),
Weight {
ref_time: gas_limit,
proof_size: 1000000,
},
storage_deposit_limit.map(Into::into),
code,
data,
Expand Down Expand Up @@ -329,7 +324,10 @@ async fn raw_call(
let payload = node::tx().contracts().call(
MultiAddress::Id(<_ as Decode>::decode(&mut dest.encode().as_bytes_ref())?),
value,
Static::from(sp_weights::Weight::from(gas_limit)),
Weight {
ref_time: gas_limit,
proof_size: 1000000,
},
storage_deposit_limit.map(Into::into),
data,
);
Expand All @@ -355,12 +353,14 @@ async fn query_call(
) -> anyhow::Result<GetStorageResult> {
let rv = api
.rpc()
.state_call(
.state_call::<GetStorageResult>(
"ContractsApi_get_storage",
Some((contract_address, key).encode().as_bytes_ref()),
None,
)
.await?;
.await?
.unwrap()
.unwrap();

<GetStorageResult>::decode(&mut rv.as_bytes_ref()).map_err(|e| anyhow::anyhow!("{e:?}"))
}
Expand All @@ -371,25 +371,30 @@ async fn read_call(
contract_address: AccountId32,
value: u128,
selector: Vec<u8>,
) -> anyhow::Result<ContractExecResult<u128>> {
) -> anyhow::Result<
ContractResult<Result<ExecReturnValue, DispatchError>, u128, EventRecord<RuntimeEvent, H256>>,
> {
let req = CallRequest {
origin: <subxt::utils::AccountId32 as Decode>::decode(&mut caller.encode().as_bytes_ref())?,
dest: <_ as Decode>::decode(&mut contract_address.encode().as_bytes_ref())?,
value,
gas_limit: Some(Weight::from(GAS_LIMIT)),
gas_limit: Some(Weight {
ref_time: GAS_LIMIT,
proof_size: 100000,
}),
storage_deposit_limit: None,
input_data: selector,
};

let rv = api
.rpc()
.state_call("ContractsApi_call", Some(req.encode().as_bytes_ref()), None)
.state_call::<ContractExecResult<u128, EventRecord<RuntimeEvent, H256>>>(
"ContractsApi_call",
Some(req.encode().as_bytes_ref()),
None,
)
.await?;

let rv = ContractResult::<Result<ExecReturnValue, DispatchError>, u128>::decode(
&mut rv.as_bytes_ref(),
)?;

Ok(rv)
}

Expand Down

0 comments on commit 586bb3c

Please sign in to comment.