Skip to content

Commit

Permalink
NNS1-3497: refactor sort SNS store logic for abandoned projects (#5952)
Browse files Browse the repository at this point in the history
# Motivation

Follow up of #5918. It simplifies the process of locating and renaming
abandoned projects.

# Changes

- Simplifies the process of finding and renaming abandoned projects.
- Replaces the name and token only if the values differ from the
originals.

# Tests

- Adds unit test to cover new logic

# Todos

- [ ] Add entry to changelog (if necessary).
Not necessary

---------

Co-authored-by: pr-automation-bot-public[bot] <189003650+pr-automation-bot-public[bot]@users.noreply.github.com>
Co-authored-by: gix-bot <[email protected]>
Co-authored-by: David de Kloet <[email protected]>
  • Loading branch information
4 people authored Dec 9, 2024
1 parent 153bf86 commit 01faf23
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 43 deletions.
72 changes: 30 additions & 42 deletions frontend/src/lib/stores/sns-aggregator.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ const initSnsAggreagatorStore =
export const snsAggregatorIncludingAbortedProjectsStore =
initSnsAggreagatorStore();

// This project has been abandoned https://dfinity.slack.com/archives/C039M7YS6F6/p1733302975333649
const CYCLES_TRANSFER_STATION_ROOT_CANISTER_ID = "ibahq-taaaa-aaaaq-aadna-cai";

export const snsAggregatorStore: SnsAggregatorStore = derived(
snsAggregatorIncludingAbortedProjectsStore,
(store) => {
Expand All @@ -46,55 +49,52 @@ export const snsAggregatorStore: SnsAggregatorStore = derived(

if (isNullish(data)) return { data: undefined };

// TODO: Find a better way to fix broken SNS metadata. These transformations will be remove once we have a better solution.
const handledAbandonedSnsData = data?.map(fixBrokenSnsMetadataBasedOnId);
const sortedAbandonesSnsData = sortedListBasedOnAbandoned(
handledAbandonedSnsData
const cts = data.find(
(sns) =>
sns.list_sns_canisters.root === CYCLES_TRANSFER_STATION_ROOT_CANISTER_ID
);
const cachedSnsData = sortedAbandonesSnsData.map(
({ isAbandoned: _, ...sns }) => ({ ...sns })
if (isNullish(cts)) return { data };
const dataWithoutCts = data.filter(
(sns) =>
sns.list_sns_canisters.root !== CYCLES_TRANSFER_STATION_ROOT_CANISTER_ID
);

return {
data: cachedSnsData,
data: [...dataWithoutCts, overrideCyclesTransferStation(cts)],
};
}
);

const brokenSnsOverrides: Record<
string,
{ name: string; tokenSymbol: string }
> = {
// Overrided for CYCLES_TRANSFER_STATION as discussed in https://dfinity.slack.com/archives/C039M7YS6F6/p1733302975333649
"ibahq-taaaa-aaaaq-aadna-cai": {
name: "CYCLES-TRANSFER-STATION",
tokenSymbol: "CTS",
},
};

const fixBrokenSnsMetadataBasedOnId = (
const overrideCyclesTransferStation = (
sns: CachedSnsDto
): CachedSnsDto & { isAbandoned?: boolean } => {
const override = brokenSnsOverrides[sns.list_sns_canisters.root];

// Required for the tokens and staking routes as they apply their own sort logic
const hiddenCharacterToPushSnsToEndOfList = "\u200B";
if (!nonNullish(override)) return sns;
const originalName = "CYCLES-TRANSFER-STATION";
const originalSymbol = "CTS";
let name = sns.meta.name;

if (name !== originalName) {
name = `${hiddenCharacterToPushSnsToEndOfList}${name} (formerly ${originalName})`;
}

const newMeta = {
...sns.meta,
name: `${hiddenCharacterToPushSnsToEndOfList}${sns.meta.name} (formerly ${override.name})`,
name,
};

const newIcrc1Metadata = sns.icrc1_metadata.map<
[string, CachedSnsTokenMetadataDto[0][1]]
>(([name, value]) => {
if (name === "icrc1:symbol" && "Text" in value) {
return [
name,
{
Text: `${value.Text} (${override.tokenSymbol})`,
},
];
const symbol = value.Text;
if (symbol !== originalSymbol) {
return [
name,
{
Text: `${symbol} (${originalSymbol})`,
},
];
}
}
return [name, value];
});
Expand All @@ -106,15 +106,3 @@ const fixBrokenSnsMetadataBasedOnId = (
isAbandoned: true,
};
};

// Required for the proposals route as it doesnt apply sort logic
const sortedListBasedOnAbandoned = (
list: (CachedSnsDto & { isAbandoned?: boolean })[]
) => [
...list.sort((a, b) => {
if (a.isAbandoned && !b.isAbandoned) return 1;
if (!a.isAbandoned && b.isAbandoned) return -1;

return 0;
}),
];
41 changes: 40 additions & 1 deletion frontend/src/tests/lib/stores/sns-aggregator.store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,28 @@ describe("sns-aggregator store", () => {
rootCanisterId: "ibahq-taaaa-aaaaq-aadna-cai",
});

const fixedBrokenSns = withBrokenSns({
sns: {
...mockedSns,
meta: {
...mockedSns.meta,
name: "CYCLES-TRANSFER-STATION",
},
icrc1_metadata: [...mockedSns.icrc1_metadata].map(([name, value]) => {
if (name === "icrc1:symbol" && "Text" in value) {
return [
name,
{
Text: "CTS",
},
];
}
return [name, value];
}),
},
rootCanisterId: "ibahq-taaaa-aaaaq-aadna-cai",
});

it("should override information for SNS with rootCanisterId ibahq-taaaa-aaaaq-aadna-cai", () => {
const data = [brokenSns];
snsAggregatorIncludingAbortedProjectsStore.setData(data);
Expand All @@ -194,7 +216,7 @@ describe("sns-aggregator store", () => {
expect(result.icrc1_metadata[3][1]).toEqual({ Text: "--- (CTS)" });
});

it("should sort sns by temporary isAbandoded property", () => {
it("should send the CTS SNS to the bottom of the store", () => {
const data = [brokenSns, ...aggregatorMockSnsesDataDto];
snsAggregatorIncludingAbortedProjectsStore.setData(data);
expect(
Expand All @@ -212,5 +234,22 @@ describe("sns-aggregator store", () => {
);
expect(result.icrc1_metadata[3][1]).toEqual({ Text: "--- (CTS)" });
});

it("should not override CTS SNS if the metadata returns to its original value", () => {
const data = [fixedBrokenSns, ...aggregatorMockSnsesDataDto];
snsAggregatorIncludingAbortedProjectsStore.setData(data);
expect(
get(snsAggregatorIncludingAbortedProjectsStore).data[0].meta.name
).toBe("CYCLES-TRANSFER-STATION");
expect(
get(snsAggregatorIncludingAbortedProjectsStore).data[0]
.icrc1_metadata[3][1]
).toEqual({ Text: "CTS" });

const result =
get(snsAggregatorStore).data[get(snsAggregatorStore).data.length - 1];
expect(result.meta.name).toBe("CYCLES-TRANSFER-STATION");
expect(result.icrc1_metadata[3][1]).toEqual({ Text: "CTS" });
});
});
});

0 comments on commit 01faf23

Please sign in to comment.