diff --git a/contracts/src/utils/nonces/mod.rs b/contracts/src/utils/nonces/mod.rs index 6c486bfee..456b96f46 100644 --- a/contracts/src/utils/nonces/mod.rs +++ b/contracts/src/utils/nonces/mod.rs @@ -57,4 +57,4 @@ pub trait NoncesImpl: Storage { .insert(account, &(nonce.checked_add(1).ok_or(NoncesError::NonceOverflow)?)); Ok(nonce) } -} +} \ No newline at end of file diff --git a/examples/nonces/.gitignore b/examples/nonces/.gitignore new file mode 100755 index 000000000..8de8f877e --- /dev/null +++ b/examples/nonces/.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 diff --git a/examples/nonces/Cargo.toml b/examples/nonces/Cargo.toml new file mode 100755 index 000000000..60b8fca39 --- /dev/null +++ b/examples/nonces/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "nonces" +version= "4.0.0-beta" +authors = ["Brushfam "] +edition = "2021" + +[dependencies] +ink = { version = "4.2.1", default-features = false} + +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } + +# These dependencies +openbrush = { path = "../..", default-features = false, features = ["utils"] } + +[dev-dependencies] +ink_e2e = "4.2.1" +test_helpers = { path = "../test_helpers", default-features = false } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", + "scale/std", + "scale-info/std", + # These dependencies + "openbrush/std", +] +ink-as-dependency = [] +e2e-tests = [] + +[profile.dev] +codegen-units = 16 diff --git a/examples/nonces/lib.rs b/examples/nonces/lib.rs new file mode 100755 index 000000000..000f6cd58 --- /dev/null +++ b/examples/nonces/lib.rs @@ -0,0 +1,55 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +#[openbrush::contract] +pub mod my_timelock_controller { + use ink::prelude::vec::Vec; + use openbrush::{ + contracts::{ + nonces, + nonces::{ + NoncesError, + NoncesImpl, + }, + traits::{ + utils::nonces::*, + }, + }, + traits::{ + Storage, + String, + }, + }; + + #[ink(storage)] + #[derive(Default, Storage)] + pub struct Contract { + #[storage_field] + nonces: nonces::Data, + } + + impl Contract { + #[ink(constructor)] + pub fn new() -> Self { + Self::default() + } + + #[ink(message)] + pub fn use_nonce(&mut self, account: AccountId) -> Result { + NoncesImpl::_use_nonce(self, &account) + } + + #[ink(message)] + pub fn use_checked_nonce(&mut self, account: AccountId, nonce: u128) -> Result { + NoncesImpl::_use_checked_nonce(self, &account, nonce) + } + } + + impl NoncesImpl for Contract {} + + impl Nonces for Contract { + #[ink(message)] + fn nonces(&self, account: AccountId) -> u128 { + NoncesImpl::nonces(self, &account) + } + } +} diff --git a/package.json b/package.json index 68bf333c8..8c4193186 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "typechain": "npx @727-ventures/typechain-polkadot --in artifacts --out ./typechain-generated", "test:mocha": "mocha --require @babel/register --require ts-node/register --recursive ./tests --extension \".ts\" --exit --timeout 20000", "test:mocha-single": "mocha --require @babel/register --require ts-node/register --extension \".ts\" --exit --timeout 20000", - "test": "yarn build:release && yarn test:mocha" + "test": "yarn build:release && yarn test:mocha", + "raw-mocha": "mocha --require @babel/register --require ts-node/register --extension \".ts\" --exit --timeout 20000" } } diff --git a/tests/e2e/governance/nonces.tests.ts b/tests/e2e/governance/nonces.tests.ts index 7f0f28c38..a2ac7bd61 100644 --- a/tests/e2e/governance/nonces.tests.ts +++ b/tests/e2e/governance/nonces.tests.ts @@ -1,33 +1,92 @@ +import { expect, getSigners } from '../helpers' +import { ApiPromise } from '@polkadot/api' + +import Constructor from '../../../typechain-generated/constructors/nonces' +import Contract from '../../../typechain-generated/contracts/nonces' +import BN from "bn.js"; +import {Result} from "@727-ventures/typechain-types"; + describe('Nonces', function () { + async function setup() { + const api = await ApiPromise.create() + + const signers = getSigners() + const deployer = signers[0] + const bob = signers[1] + + const contractFactory = new Constructor(api, deployer) + const contractAddress = (await contractFactory.new()).address + const contract = new Contract(contractAddress, deployer, api) + + return { + api, + bob, + deployer, + contract, + } + } + beforeEach(async function () { // }) it('gets a nonce', async function () { - // + const { + api, + bob, + deployer, + contract, + } = await setup() + const nonce = await contract.query.nonces(bob.address) + expect(await contract.query.nonces(bob.address)).to.have.output(new BN(0)) + await api.disconnect() }) describe('_useNonce', function () { it('increments a nonce', async function () { - // + const { + api, + bob, + deployer, + contract, + } = await setup() + expect(await contract.query.nonces(bob.address)).to.have.output(new BN(0)) + expect(await contract.query.useNonce(bob.address)).to.have.output(new BN(0)) + expect(await contract.query.useNonce(bob.address)).to.have.output(new BN(1)) + expect(await contract.query.nonces(bob.address)).to.have.output(new BN(2)) + await api.disconnect() }) - it('increments only sender\'s nonce', async function () { - // - }) + // it('increments only sender\'s nonce', async function () { + // // + // }) }) describe('_useCheckedNonce', function () { it('increments a nonce', async function () { - // + const { + api, + bob, + deployer, + contract, + } = await setup() + expect(await contract.query.nonces(bob.address)).to.have.output(new BN(0)) + expect(await contract.query.useCheckedNonce(bob.address, new BN(0))).to.have.output(new BN(0)) + expect(await contract.query.useCheckedNonce(bob.address, new BN(1))).to.have.output(new BN(1)) }) - it('increments only sender\'s nonce', async function () { - // - }) + // it('increments only sender\'s nonce', async function () { + // // + // }) it('reverts when nonce is not the expected', async function () { - // + const { + api, + bob, + deployer, + contract, + } = await setup() + //todo }) }) }) \ No newline at end of file diff --git a/typechain-compiler-config.json b/typechain-compiler-config.json index a541a2cc0..e65db2f84 100644 --- a/typechain-compiler-config.json +++ b/typechain-compiler-config.json @@ -4,7 +4,8 @@ "examples/upgradeable/**", "examples/diamond/**", "examples/proxy/**", - "examples/governance/governor/Cargo.toml" + "examples/governance/governor/Cargo.toml", + "examples/nonces/Cargo.toml" ], "artifactsPath": "./artifacts", "typechainGeneratedPath": "./typechain-generated"