From 52962a46254f343dba609f65f49bc26b93b85d0a Mon Sep 17 00:00:00 2001 From: Matthew Orris <--help> Date: Mon, 12 Feb 2024 15:52:56 -0700 Subject: [PATCH 1/3] feat: Add tests for overlapping holds and frozen --- e2e/scaffolding/extrinsicHelpers.ts | 16 +++++++ e2e/sudo/sudo.test.ts | 66 ++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/e2e/scaffolding/extrinsicHelpers.ts b/e2e/scaffolding/extrinsicHelpers.ts index b3b4797aa4..aec6818640 100644 --- a/e2e/scaffolding/extrinsicHelpers.ts +++ b/e2e/scaffolding/extrinsicHelpers.ts @@ -795,4 +795,20 @@ export class ExtrinsicHelper { currentBlock = await getBlockNumber(); } } + + public static submitProposal(keys: KeyringPair, spendAmount: AnyNumber | Compact) { + return new Extrinsic( + () => ExtrinsicHelper.api.tx.treasury.proposeSpend(spendAmount, keys.address), + keys, + ExtrinsicHelper.api.events.treasury.Proposed + ); + } + + public static rejectProposal(keys: KeyringPair, proposalId: any) { + return new Extrinsic( + () => ExtrinsicHelper.api.tx.treasury.rejectProposal(proposalId), + keys, + ExtrinsicHelper.api.events.treasury.Rejected + ); + } } diff --git a/e2e/sudo/sudo.test.ts b/e2e/sudo/sudo.test.ts index f5aa4fdbd8..abb5cce6c8 100644 --- a/e2e/sudo/sudo.test.ts +++ b/e2e/sudo/sudo.test.ts @@ -8,15 +8,18 @@ import { Extrinsic, ExtrinsicHelper } from '../scaffolding/extrinsicHelpers'; import { isTestnet } from '../scaffolding/env'; import { getSudo, getFundingSource } from '../scaffolding/funding'; import { AVRO_GRAPH_CHANGE } from '../schemas/fixtures/avroGraphChangeSchemaType'; -import { Bytes, u16 } from '@polkadot/types'; +import { Bytes, u16, u64 } from '@polkadot/types'; import { DOLLARS, createDelegatorAndDelegation, createProviderKeysAndId, getCurrentItemizedHash, generateSchemaPartialName, + createKeys, + createMsaAndProvider, } from '../scaffolding/helpers'; import { AVRO_CHAT_MESSAGE } from '../stateful-pallet-storage/fixtures/itemizedSchemaType'; +import { stakeToProvider } from '../scaffolding/helpers'; describe('Sudo required', function () { let sudoKey: KeyringPair; @@ -179,6 +182,67 @@ describe('Sudo required', function () { }); }); }); + + describe('Capacity should not be affected by a hold being slashed', function () { + it('stake should fail when overlapping tokens are on hold', async function () { + const accountBalance: bigint = 122n * DOLLARS; + const stakeBalance: bigint = 100n * DOLLARS; + const spendBalance: bigint = 20n * DOLLARS; + const proposalBond: bigint = 100n * DOLLARS; + + // Setup some keys and a provider for capacity staking + const stakeKeys: KeyringPair = createKeys('StakeKeys'); + const stakeProviderId: u64 = await createMsaAndProvider(fundingSource, stakeKeys, 'StakeProvider', accountBalance); + + // Create a treasury proposal which will result in a hold with minimum bond = 100 DOLLARS + const proposalExt = ExtrinsicHelper.submitProposal(stakeKeys, spendBalance); + const { target: proposalEvent } = await proposalExt.signAndSend(); + assert.notEqual(proposalEvent, undefined, 'should return a Proposal event') + + // Confirm that the tokens were reserved/hold in the stakeKeys account using the query API + let stakedAcctInfo = await ExtrinsicHelper.getAccountInfo(stakeKeys.address); + assert.equal( + stakedAcctInfo.data.reserved, + proposalBond, + `expected ${proposalBond} reserved balance, got ${stakedAcctInfo.data.reserved}` + ); + + // Create a stake that will result in overlapping tokens being frozen + // stake will allow only the balance not on hold to be staked + await assert.rejects(stakeToProvider(fundingSource, stakeKeys, stakeProviderId, stakeBalance)); + + // Slash the provider + const slashExt = ExtrinsicHelper.rejectProposal(sudoKey, proposalEvent?.data.proposalIndex); + const { target: slashEvent } = await slashExt.sudoSignAndSend(); + assert.notEqual(slashEvent, undefined, 'should return a Treasury event') + + // Confirm that the tokens were slashed from the stakeKeys account using the query API + stakedAcctInfo = await ExtrinsicHelper.getAccountInfo(stakeKeys.address); + assert.equal( + stakedAcctInfo.data.reserved, + 0n, + `expected 0 reserved balance, got ${stakedAcctInfo.data.reserved}` + ); + }); + + it('proposal should fail when overlapping tokens are on hold', async function () { + const accountBalance: bigint = 122n * DOLLARS; + const stakeBalance: bigint = 100n * DOLLARS; + const spendBalance: bigint = 20n * DOLLARS; + + // Setup some keys and a provider for capacity staking + const stakeKeys: KeyringPair = createKeys('StakeKeys'); + const stakeProviderId: u64 = await createMsaAndProvider(fundingSource, stakeKeys, 'StakeProvider', accountBalance); + + // Create a stake that will result in overlapping tokens being frozen + await assert.doesNotReject(stakeToProvider(fundingSource, stakeKeys, stakeProviderId, stakeBalance)); + + // Create a treasury proposal which will result in a hold with minimum bond = 100 DOLLARS + // The proposal should fail because the stakeKeys account has overlapping tokens frozen + const proposalExt = ExtrinsicHelper.submitProposal(stakeKeys, spendBalance); + await assert.rejects(proposalExt.signAndSend()); + }) + }) }); }); }); From 31b51d498c31e558d503680754f353138f40009a Mon Sep 17 00:00:00 2001 From: Matthew Orris <--help> Date: Tue, 13 Feb 2024 07:10:19 -0700 Subject: [PATCH 2/3] fix: lint errors --- e2e/sudo/sudo.test.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/e2e/sudo/sudo.test.ts b/e2e/sudo/sudo.test.ts index abb5cce6c8..689907e659 100644 --- a/e2e/sudo/sudo.test.ts +++ b/e2e/sudo/sudo.test.ts @@ -192,12 +192,17 @@ describe('Sudo required', function () { // Setup some keys and a provider for capacity staking const stakeKeys: KeyringPair = createKeys('StakeKeys'); - const stakeProviderId: u64 = await createMsaAndProvider(fundingSource, stakeKeys, 'StakeProvider', accountBalance); + const stakeProviderId: u64 = await createMsaAndProvider( + fundingSource, + stakeKeys, + 'StakeProvider', + accountBalance + ); // Create a treasury proposal which will result in a hold with minimum bond = 100 DOLLARS const proposalExt = ExtrinsicHelper.submitProposal(stakeKeys, spendBalance); const { target: proposalEvent } = await proposalExt.signAndSend(); - assert.notEqual(proposalEvent, undefined, 'should return a Proposal event') + assert.notEqual(proposalEvent, undefined, 'should return a Proposal event'); // Confirm that the tokens were reserved/hold in the stakeKeys account using the query API let stakedAcctInfo = await ExtrinsicHelper.getAccountInfo(stakeKeys.address); @@ -214,7 +219,7 @@ describe('Sudo required', function () { // Slash the provider const slashExt = ExtrinsicHelper.rejectProposal(sudoKey, proposalEvent?.data.proposalIndex); const { target: slashEvent } = await slashExt.sudoSignAndSend(); - assert.notEqual(slashEvent, undefined, 'should return a Treasury event') + assert.notEqual(slashEvent, undefined, 'should return a Treasury event'); // Confirm that the tokens were slashed from the stakeKeys account using the query API stakedAcctInfo = await ExtrinsicHelper.getAccountInfo(stakeKeys.address); @@ -232,7 +237,12 @@ describe('Sudo required', function () { // Setup some keys and a provider for capacity staking const stakeKeys: KeyringPair = createKeys('StakeKeys'); - const stakeProviderId: u64 = await createMsaAndProvider(fundingSource, stakeKeys, 'StakeProvider', accountBalance); + const stakeProviderId: u64 = await createMsaAndProvider( + fundingSource, + stakeKeys, + 'StakeProvider', + accountBalance + ); // Create a stake that will result in overlapping tokens being frozen await assert.doesNotReject(stakeToProvider(fundingSource, stakeKeys, stakeProviderId, stakeBalance)); @@ -241,8 +251,8 @@ describe('Sudo required', function () { // The proposal should fail because the stakeKeys account has overlapping tokens frozen const proposalExt = ExtrinsicHelper.submitProposal(stakeKeys, spendBalance); await assert.rejects(proposalExt.signAndSend()); - }) - }) + }); + }); }); }); }); From e2da387cacee4ab6f0772ea32f7dfc2f1fe90956 Mon Sep 17 00:00:00 2001 From: Matthew Orris <--help> Date: Wed, 14 Feb 2024 08:29:59 -0700 Subject: [PATCH 3/3] fix: Update grcov installation command --- .github/workflows/common/codecov/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/common/codecov/action.yml b/.github/workflows/common/codecov/action.yml index 264e144f7d..2db479d8cc 100644 --- a/.github/workflows/common/codecov/action.yml +++ b/.github/workflows/common/codecov/action.yml @@ -9,7 +9,7 @@ runs: steps: - name: Install grcov shell: bash - run: cargo +nightly-2023-07-13 install grcov + run: cargo +nightly-2023-07-13 install --locked grcov - name: Build shell: bash # Limited to 10 threads max run: cargo +nightly-2023-07-13 build -j 10 --features frequency-lint-check