Skip to content
This repository has been archived by the owner on Jul 15, 2022. It is now read-only.

Commit

Permalink
LL-4373 Discard existing ops on sync if blacklist has changed
Browse files Browse the repository at this point in the history
Add testing for blacklisted feature
  • Loading branch information
juan-cortes committed Jan 13, 2021
1 parent f805b4f commit 3c34f4a
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/account/serialization.js
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ export function fromAccountRaw(rawAccount: AccountRaw): Account {
bitcoinResources,
swapHistory,
algorandResources,
blacklistedTokensCache,
} = rawAccount;

const subAccounts =
Expand Down Expand Up @@ -626,6 +627,7 @@ export function fromAccountRaw(rawAccount: AccountRaw): Account {
currency,
lastSyncDate: new Date(lastSyncDate || 0),
swapHistory: [],
blacklistedTokensCache,
};

if (xpub) {
Expand Down Expand Up @@ -691,6 +693,7 @@ export function toAccountRaw({
bitcoinResources,
swapHistory,
algorandResources,
blacklistedTokensCache,
}: Account): AccountRaw {
const res: $Exact<AccountRaw> = {
id,
Expand All @@ -703,6 +706,7 @@ export function toAccountRaw({
freshAddressPath,
freshAddresses,
blockHeight,
blacklistedTokensCache,
creationDate: creationDate.toISOString(),
operationsCount,
operations: (operations || []).map((o) => toOperationRaw(o)),
Expand Down
9 changes: 8 additions & 1 deletion src/families/ethereum/synchronisation.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,16 @@ export const getAccountShape: GetAccountShape = async (

// fetch transactions, incrementally if possible
const mostRecentStableOperation = initialStableOperations[0];

const newBlacklistedTokensCache = JSON.stringify(blacklistedTokenIds || []);
const outdatedBlacklist =
initialAccount?.blacklistedTokensCache !== newBlacklistedTokensCache;

let pullFromBlockHash =
initialAccount &&
areAllOperationsLoaded(initialAccount) &&
mostRecentStableOperation
mostRecentStableOperation &&
!outdatedBlacklist
? mostRecentStableOperation.blockHash
: undefined;

Expand Down Expand Up @@ -159,6 +165,7 @@ export const getAccountShape: GetAccountShape = async (
blockHeight,
lastSyncDate: new Date(),
balanceHistory: undefined,
blacklistedTokensCache: newBlacklistedTokensCache,
};

return accountShape;
Expand Down
97 changes: 97 additions & 0 deletions src/families/ethereum/synchronisation.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// @flow
import { reduce } from "rxjs/operators";
import { setSupportedCurrencies } from "../../currencies";
import { fromAccountRaw } from "../../account";
import { getAccountCurrency } from "../../account/helpers";
import type { Account } from "../../types";
import { getAccountBridge } from "../../bridge";
import { makeBridgeCacheSystem } from "../../bridge/cache";
import { ethereum1 } from "./test-dataset";

setSupportedCurrencies(["ethereum"]);

describe("blacklistedTokenIds functionality", () => {
const account = fromAccountRaw(ethereum1);
let localCache = {};
const cache = makeBridgeCacheSystem({
saveData(c, d) {
localCache[c.id] = d;
return Promise.resolve();
},
getData(c) {
return Promise.resolve(localCache[c.id]);
},
});

test("initial raw account contains no token accounts", async () => {
await cache.prepareCurrency(account.currency);
expect(ethereum1.subAccounts?.length).toBeFalsy();
});

test("sync finds tokens, but not blacklisted ones", async () => {
const bridge = getAccountBridge(account);
const blacklistedTokenIds = ["ethereum/erc20/weth"];
const synced = await bridge
.sync(account, {
paginationConfig: {},
blacklistedTokenIds,
})
.pipe(reduce((a, f: (Account) => Account) => f(a), account))
.toPromise();

// Contains token accounts
expect(synced.subAccounts?.length).toBeTruthy();

// Contains a known token
expect(
synced.subAccounts.find(
(a) => getAccountCurrency(a)?.id === "ethereum/erc20/0x_project"
)
).toBeTruthy();

// Does not contain a blacklisted token
expect(
synced.subAccounts.find((a) =>
blacklistedTokenIds.includes(getAccountCurrency(a)?.id)
)
).toBe(undefined);
});

test("account resyncs tokens if no longer blacklisted", async () => {
const bridge = getAccountBridge(account);
const blacklistedTokenIds = ["ethereum/erc20/weth"];
const syncedWithoutWeth = await bridge
.sync(account, {
paginationConfig: {},
blacklistedTokenIds,
})
.pipe(reduce((a, f: (Account) => Account) => f(a), account))
.toPromise();

// Contains token accounts
expect(syncedWithoutWeth.subAccounts?.length).toBeTruthy();

// Does not contain a blacklisted token
expect(
syncedWithoutWeth.subAccounts.find((a) =>
blacklistedTokenIds.includes(getAccountCurrency(a)?.id)
)
).toBe(undefined);

//Sync again with `syncedWithoutWeth` as a base but without it being blacklisted
const synced = await bridge
.sync(account, {
paginationConfig: {},
blacklistedTokenIds: ["ethereum/erc20/somethingElse"],
})
.pipe(reduce((a, f: (Account) => Account) => f(a), account))
.toPromise();

// Does not contain a blacklisted token
expect(
synced.subAccounts.find(
(a) => getAccountCurrency(a)?.id === "ethereum/erc20/weth"
)
).toBeTruthy();
});
});
5 changes: 5 additions & 0 deletions src/reconciliation.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,11 @@ export function patchAccount(
changed = true;
}

if (account.blacklistedTokensCache !== updatedRaw.blacklistedTokensCache) {
next.blacklistedTokensCache = updatedRaw.blacklistedTokensCache;
changed = true;
}

if (
updatedRaw.tronResources &&
account.tronResources !== updatedRaw.tronResources
Expand Down
4 changes: 4 additions & 0 deletions src/types/account.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ export type Account = {

// Swap operations linked to this account
swapHistory: SwapOperation[],

// Hash used to discard tx history on sync if blacklisted token ids change
blacklistedTokensCache?: string,
};

export type SubAccount = TokenAccount | ChildAccount;
Expand Down Expand Up @@ -273,6 +276,7 @@ export type AccountRaw = {
algorandResources?: AlgorandResourcesRaw,
// Swap operations linked to this account
swapHistory?: SwapOperationRaw[],
blacklistedTokensCache?: string,
};

export type SubAccountRaw = TokenAccountRaw | ChildAccountRaw;
Expand Down

0 comments on commit 3c34f4a

Please sign in to comment.