mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-04-21 23:47:56 +00:00
1295c36241
- Fixed TypeScript type assertion issues - Updated imports from api-augment/substrate to api-augment/bizinikiwi - Fixed imgConvert.mjs header and imports - Added @ts-expect-error for runtime-converted types - Fixed all @polkadot copyright headers to @pezkuwi
179 lines
7.1 KiB
JavaScript
179 lines
7.1 KiB
JavaScript
/**
|
|
* @file: validator-pool.live.test.js
|
|
* @description: Live integration tests for the ValidatorPool pallet.
|
|
*
|
|
* @preconditions:
|
|
* 1. A local Pezkuwi dev node must be running and accessible at `ws://127.0.0.1:8082`.
|
|
* 2. The node must have `validatorPool`, `trust`, `tiki`, and `staking` pallets.
|
|
* 3. The tests require a funded sudo account (`//Alice`).
|
|
*/
|
|
|
|
import { ApiPromise, WsProvider, Keyring } from '@pezkuwi/api';
|
|
import { BN } from '@pezkuwi/util';
|
|
import { jest } from '@jest/globals';
|
|
|
|
// ========================================
|
|
// TEST CONFIGURATION
|
|
// ========================================
|
|
|
|
const WS_ENDPOINT = 'ws://127.0.0.1:8082';
|
|
jest.setTimeout(120000); // 2 minutes
|
|
|
|
const UNITS = new BN('1000000000000'); // 10^12
|
|
|
|
// ========================================
|
|
// TEST SETUP & TEARDOWN
|
|
// ========================================
|
|
|
|
let api;
|
|
let keyring;
|
|
let sudo, userWithHighTrust, userWithLowTrust;
|
|
|
|
// Helper to send a transaction and wait for it to be finalized
|
|
const sendAndFinalize = (tx, signer) => {
|
|
return new Promise((resolve, reject) => {
|
|
tx.signAndSend(signer, ({ status, dispatchError }) => {
|
|
if (status.isFinalized) {
|
|
if (dispatchError) {
|
|
const decoded = api.registry.findMetaError(dispatchError.asModule);
|
|
reject(new Error(`${decoded.section}.${decoded.name}`));
|
|
} else {
|
|
resolve();
|
|
}
|
|
}
|
|
}).catch(reject);
|
|
});
|
|
};
|
|
|
|
beforeAll(async () => {
|
|
const wsProvider = new WsProvider(WS_ENDPOINT);
|
|
api = await ApiPromise.create({ provider: wsProvider });
|
|
keyring = new Keyring({ type: 'sr25519' });
|
|
|
|
sudo = keyring.addFromUri('//Alice');
|
|
userWithHighTrust = keyring.addFromUri('//Charlie');
|
|
userWithLowTrust = keyring.addFromUri('//Dave');
|
|
|
|
console.log('Connected to node and initialized accounts for ValidatorPool tests.');
|
|
|
|
// --- Test Setup: Ensure userWithHighTrust has a high trust score ---
|
|
console.log('Setting up a user with a high trust score...');
|
|
try {
|
|
// 1. Make user a citizen
|
|
await sendAndFinalize(api.tx.tiki.forceMintCitizenNft(userWithHighTrust.address), sudo);
|
|
|
|
// 2. Bond a large stake
|
|
const stakeAmount = UNITS.mul(new BN(10000)); // High stake for high score
|
|
await sendAndFinalize(api.tx.staking.bond(stakeAmount, 'Staked'), userWithHighTrust);
|
|
|
|
// 3. Force recalculate trust score
|
|
await sendAndFinalize(api.tx.trust.forceRecalculateTrustScore(userWithHighTrust.address), sudo);
|
|
|
|
const score = await api.query.trust.trustScoreOf(userWithHighTrust.address);
|
|
console.log(`Setup complete. User trust score is: ${score.toNumber()}.`);
|
|
// This check is important for the test's validity
|
|
expect(score.toNumber()).toBeGreaterThan(api.consts.validatorPool.minTrustScore.toNumber());
|
|
|
|
} catch (e) {
|
|
console.warn(`Setup for userWithHighTrust failed. Tests might not be accurate. Error: ${e.message}`);
|
|
}
|
|
}, 180000); // 3 minutes timeout for this complex setup
|
|
|
|
afterAll(async () => {
|
|
if (api) await api.disconnect();
|
|
});
|
|
|
|
// ========================================
|
|
// LIVE PALLET TESTS
|
|
// ========================================
|
|
|
|
describe('ValidatorPool Pallet Live Workflow', () => {
|
|
|
|
const stakeValidatorCategory = { StakeValidator: null };
|
|
|
|
it('should allow a user with sufficient trust to join and leave the pool', async () => {
|
|
// -----------------------------------------------------------------
|
|
// PHASE 1: JOIN POOL
|
|
// -----------------------------------------------------------------
|
|
console.log('PHASE 1: Joining the validator pool...');
|
|
|
|
await sendAndFinalize(api.tx.validatorPool.joinValidatorPool(stakeValidatorCategory), userWithHighTrust);
|
|
|
|
const poolMember = await api.query.validatorPool.poolMembers(userWithHighTrust.address);
|
|
expect(poolMember.isSome).toBe(true);
|
|
const poolSize = await api.query.validatorPool.poolSize();
|
|
expect(poolSize.toNumber()).toBeGreaterThanOrEqual(1);
|
|
console.log('User successfully joined the pool.');
|
|
|
|
// -----------------------------------------------------------------
|
|
// PHASE 2: LEAVE POOL
|
|
// -----------------------------------------------------------------
|
|
console.log('PHASE 2: Leaving the validator pool...');
|
|
|
|
await sendAndFinalize(api.tx.validatorPool.leaveValidatorPool(), userWithHighTrust);
|
|
|
|
const poolMemberAfterLeave = await api.query.validatorPool.poolMembers(userWithHighTrust.address);
|
|
expect(poolMemberAfterLeave.isNone).toBe(true);
|
|
console.log('User successfully left the pool.');
|
|
});
|
|
|
|
it('should fail for users with insufficient trust or those not in the pool', async () => {
|
|
console.log('Testing failure cases...');
|
|
|
|
// Case 1: Insufficient trust score
|
|
await expect(
|
|
sendAndFinalize(api.tx.validatorPool.joinValidatorPool(stakeValidatorCategory), userWithLowTrust)
|
|
).rejects.toThrow('validatorPool.InsufficientTrustScore');
|
|
console.log('Verified: Cannot join with insufficient trust score.');
|
|
|
|
// Case 2: Already in pool (re-join)
|
|
await sendAndFinalize(api.tx.validatorPool.joinValidatorPool(stakeValidatorCategory), userWithHighTrust);
|
|
await expect(
|
|
sendAndFinalize(api.tx.validatorPool.joinValidatorPool(stakeValidatorCategory), userWithHighTrust)
|
|
).rejects.toThrow('validatorPool.AlreadyInPool');
|
|
console.log('Verified: Cannot join when already in the pool.');
|
|
// Cleanup
|
|
await sendAndFinalize(api.tx.validatorPool.leaveValidatorPool(), userWithHighTrust);
|
|
|
|
// Case 3: Not in pool (leave)
|
|
await expect(
|
|
sendAndFinalize(api.tx.validatorPool.leaveValidatorPool(), userWithLowTrust)
|
|
).rejects.toThrow('validatorPool.NotInPool');
|
|
console.log('Verified: Cannot leave when not in the pool.');
|
|
});
|
|
|
|
it('should allow root to force a new era', async () => {
|
|
console.log('Testing force_new_era...');
|
|
|
|
const minValidators = api.consts.validatorPool.minValidators.toNumber();
|
|
console.log(`Minimum validators required for new era: ${minValidators}`);
|
|
|
|
// Add enough members to meet the minimum requirement
|
|
const members = ['//Charlie', '//Dave', '//Eve', '//Ferdie', '//Gerard'].slice(0, minValidators);
|
|
for (const memberSeed of members) {
|
|
const member = keyring.addFromUri(memberSeed);
|
|
// We assume these test accounts also meet the trust requirements.
|
|
// For a robust test, each should be set up like userWithHighTrust.
|
|
try {
|
|
await sendAndFinalize(api.tx.validatorPool.joinValidatorPool(stakeValidatorCategory), member);
|
|
} catch (e) {
|
|
// Ignore if already in pool from a previous failed run
|
|
if (!e.message.includes('validatorPool.AlreadyInPool')) throw e;
|
|
}
|
|
}
|
|
console.log(`Joined ${minValidators} members to the pool.`);
|
|
|
|
const initialEra = await api.query.validatorPool.currentEra();
|
|
|
|
await sendAndFinalize(api.tx.validatorPool.forceNewEra(), sudo);
|
|
|
|
const newEra = await api.query.validatorPool.currentEra();
|
|
expect(newEra.toNumber()).toBe(initialEra.toNumber() + 1);
|
|
console.log(`Successfully forced new era. Moved from era ${initialEra} to ${newEra}.`);
|
|
|
|
const validatorSet = await api.query.validatorPool.currentValidatorSet();
|
|
expect(validatorSet.isSome).toBe(true);
|
|
console.log('Verified that a new validator set has been created.');
|
|
});
|
|
});
|