Skip to content

Commit

Permalink
feat: adapt recovery, check balance delta of LLO's.
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitdevos committed Apr 18, 2024
1 parent b2542fd commit fafdc4f
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 34 deletions.
55 changes: 38 additions & 17 deletions packages/client-node/integration/Balance.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Numbers, CoinBalance, Lgnt } from "@logion/node-api";
import { BalanceState, waitFor } from "@logion/client";
import { Duration } from "luxon";

import { State } from "./Utils.js";

Expand All @@ -11,21 +10,24 @@ export async function transfers(state: State) {
const aliceClient = client.withCurrentAccount(alice.account)
let aliceState = await aliceClient.balanceState();

checkBalance(aliceState, "99.99k", "100.00k");
let aliceSnapshot = takeSnapshot(aliceState);
expect(aliceState.transactions.length).toBe(0);
aliceState = await aliceState.transfer({
signer,
amount: Lgnt.from(5000n),
destination: requesterAccount,
});
checkBalance(aliceState, "94.99k", "95.00k");
checkBalanceDelta(aliceState, "-4.99k", aliceSnapshot);
aliceState = await waitFor({
pollingParameters: {
period: Duration.fromMillis(1000),
maxRetries: 50,
},
producer: async state => state ? await state.refresh() : aliceState,
predicate: state => state.transactions.length === 2,
predicate: state => {
if (state.transactions.length > 0) {
const transaction = state.transactions[0];
return transaction.pallet === "balances" && transaction.method === "transferKeepAlive"
} else {
return false;
}
}
});
expect(aliceState.transactions[0].fees.inclusion).toBeGreaterThan(0);
expect(aliceState.transactions[0].fees.storage).toBeUndefined();
Expand All @@ -35,6 +37,8 @@ export async function transfers(state: State) {
const userClient = client.withCurrentAccount(requesterAccount)
let userState = await userClient.balanceState();

aliceSnapshot = takeSnapshot(await aliceState.refresh());

checkBalance(userState, "5.00k");
userState = await userState.transfer({
signer,
Expand All @@ -43,22 +47,39 @@ export async function transfers(state: State) {
});
checkBalance(userState, "2.99k");

// TODO: the balance of a LO is not stable as it increases with block rewards
// this integration test should be rewritten with regular users.
//
// Alice checks her balance.
// aliceState = await aliceState.refresh();
// checkBalance(aliceState, "97.00k"); // is sometimes 96.99k depending on block reward.
aliceState = await aliceState.refresh();
checkBalanceDelta(aliceState, "2.00k", aliceSnapshot);
}

export function checkBalance(balanceState: BalanceState, ...expectedValues: string[]) {
export function checkBalance(balanceState: BalanceState, expectedValue: string) {
const balance = balanceState.balances[0];
checkCoinBalance(balance, ...expectedValues);
checkCoinBalance(balance, expectedValue);
}

export function takeSnapshot(balanceState: BalanceState): CoinBalance {
return balanceState.balances[0];
}

export function checkBalanceDelta(current: BalanceState, expectedDelta: string, previous: CoinBalance) {
checkCoinBalanceDelta(takeSnapshot(current), expectedDelta, previous);
}

export function checkCoinBalanceDelta(current: CoinBalance, expectedDelta: string, previous: CoinBalance) {
expect(current.coin).toEqual(previous.coin);
const delta: CoinBalance = {
coin: current.coin,
available: current.available.subtract(previous.available),
reserved: current.reserved.subtract(previous.reserved),
total: current.total.subtract(previous.total),
level: current.level - previous.level,
}
checkCoinBalance(delta, expectedDelta);
}

export function checkCoinBalance(balance: CoinBalance, ...expectedValues: string[]) {
export function checkCoinBalance(balance: CoinBalance, expectedValue: string) {
const formatted = formatBalance(balance);
expect(expectedValues).toContain(formatted)
expect(expectedValue).toEqual(formatted)
}

export function formatBalance(balance: CoinBalance): string {
Expand Down
4 changes: 2 additions & 2 deletions packages/client-node/integration/Main.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { setupInitialState, State, tearDown, ALICE, BOB } from "./Utils.js";
import { setupInitialState, State, tearDown } from "./Utils.js";
import { enablesProtection, requestValidIdentity } from "./Protection.js";
import { transferAndCannotPayFees, transfers, transferWithInsufficientFunds } from "./Balance.js";
import { providesVault } from "./Vault.js";
Expand All @@ -23,7 +23,7 @@ import { invitedContributors } from "./InvitedContributors.js";

describe("Logion SDK", () => {

jasmine.DEFAULT_TIMEOUT_INTERVAL = 600000;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1200000;

let state: State;

Expand Down
5 changes: 3 additions & 2 deletions packages/client-node/integration/Protection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { initAccountBalance, State } from "./Utils.js";
import { ClosedLoc } from "@logion/client/dist/Loc";
import { LegalOfficerClass } from "@logion/client/dist/Types";
import debugLog = jasmine.debugLog;

export interface IdentityLocs {
alice: UUID,
Expand All @@ -36,7 +37,7 @@ async function activateProtection(state: State, identityLocs: IdentityLocs): Pro

const authenticatedClient = client.withCurrentAccount(requesterAccount);

console.log("Requesting protection")
debugLog("Requesting protection")
const current = await authenticatedClient.protectionState();
expect(current).toBeInstanceOf(NoProtection);

Expand All @@ -57,7 +58,7 @@ async function activateProtection(state: State, identityLocs: IdentityLocs): Pro

async function createsIdentityLoc(state: State, account: ValidAccountId, legalOfficer: LegalOfficerClass): Promise<ClosedLoc> {
const { client, signer } = state;
console.log("Setting balance of %s", account.address)
debugLog(`Setting balance of ${ account.address }`)
await initAccountBalance(state, account);

const authenticatedClient = client.withCurrentAccount(account);
Expand Down
25 changes: 13 additions & 12 deletions packages/client-node/integration/Recovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ import {
import { IdentityLocs } from "./Protection.js";
import { aliceAcceptsTransfer } from "./Vault.js";
import { initAccountBalance, NEW_ADDRESS, REQUESTER_ADDRESS, State } from "./Utils.js";
import debugLog = jasmine.debugLog;

export async function requestRecoveryAndCancel(state: State, identityLocs: IdentityLocs) {
const { client, signer, alice, charlie, newAccount } = state;

const pending = await requestRecovery(state, identityLocs) as PendingProtection;

console.log("LO's - Alice and Charlie Rejecting")
debugLog("LO's - Alice and Charlie Rejecting")
await rejectRequest(client, signer, charlie, newAccount, "Your protection request is not complete");
await rejectRequest(client, signer, alice, newAccount, "Some info is missing");

Expand All @@ -45,7 +46,7 @@ export async function rejectRequest(
const response = await axios.put("/api/protection-request", {
legalOfficerAddress: legalOfficer.account.address,
statuses: [ "PENDING" ],
requester: requester.address,
requesterAddress: requester.address,
});
const request: ProtectionRequest = response.data.requests[0];

Expand All @@ -66,7 +67,7 @@ export async function acceptRequest(
const response = await axios.put("/api/protection-request", {
legalOfficerAddress: legalOfficer.account.address,
statuses: [ "PENDING" ],
requesterAddress: requester
requesterAddress: requester.address,
});
const request: ProtectionRequest = response.data.requests[0];

Expand Down Expand Up @@ -127,23 +128,23 @@ export async function requestRecoveryWithResubmit(state: State, identityLocs: Id

const requested = await requestRecovery(state, identityLocs);

console.log("LO's - Alice Rejecting")
debugLog("LO's - Alice Rejecting")
await rejectRequest(client, signer, alice, newAccount, "for some reason");

console.log("User resubmitting to Alice");
debugLog("User resubmitting to Alice");
const rejected = await requested.refresh() as RejectedRecovery;
const pending = await rejected.resubmit(alice);

console.log("LO's - Accepting and vouching")
debugLog("LO's - Accepting and vouching")
await acceptRequestAndVouch(client.config, client, signer, alice, REQUESTER_ADDRESS, newAccount);
await acceptRequestAndVouch(client.config, client, signer, charlie, REQUESTER_ADDRESS, newAccount);

console.log("Activating")
debugLog("Activating")
const accepted = await pending.refresh() as AcceptedProtection;
let pendingRecovery = await accepted.activate({ signer }) as PendingRecovery;
pendingRecovery = await pendingRecovery.waitForFullyReady();

console.log("Claiming")
debugLog("Claiming")
await pendingRecovery.claimRecovery({ signer });
}

Expand All @@ -152,7 +153,7 @@ export async function recoverLostVault(state: State) {

const claimed = await getClaimedRecovery(state);

console.log("Transfer from recovered vault")
debugLog("Transfer from recovered vault")
const newVault = await claimed.vaultState();
let recoveredVault = await claimed.recoveredVaultState();
recoveredVault = await recoveredVault.createVaultTransferRequest({
Expand All @@ -163,7 +164,7 @@ export async function recoverLostVault(state: State) {
});
const pendingRequest = recoveredVault.pendingVaultTransferRequests[0];

console.log("Alice accepts transfer from recovered vault")
debugLog("Alice accepts transfer from recovered vault")
await aliceAcceptsTransfer(state, pendingRequest, claimed);
}

Expand All @@ -180,7 +181,7 @@ export async function recoverLostAccount(state: State) {

const claimed = await getClaimedRecovery(state);

console.log("Transfer from recovered account")
debugLog("Transfer from recovered account")
const recoveredBalance = await claimed.recoveredBalanceState();
await recoveredBalance.transferAll({
signer,
Expand All @@ -199,7 +200,7 @@ async function requestRecovery(state: State, identityLocs: IdentityLocs): Promis
const current = await authenticatedClient.protectionState();
expect(current).toBeInstanceOf(NoProtection);
if(current instanceof NoProtection) {
console.log("Requesting recovery")
debugLog("Requesting recovery")
return await current.requestRecovery({
payload: {
recoveredAccount: requesterAccount,
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/Polling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface WaitForParameters<T> {

export const DEFAULT_POLLING_PARAMETERS: PollingParameters = {
period: Duration.fromMillis(1000),
maxRetries: 20,
maxRetries: 40,
};

export function waitFor<T>(params: WaitForParameters<T>): Promise<T> {
Expand Down

0 comments on commit fafdc4f

Please sign in to comment.