Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ changes.
### Fixed

- Fix disappearing proposals in the governance actions list for the same tx hashes [Issue 3918](https://github.com/IntersectMBO/govtool/issues/3918)
- Fix incorrect display of new committee parameters in Governance Action details [Issue 3954](https://github.com/IntersectMBO/govtool/issues/3954)

### Changed

Expand Down
66 changes: 59 additions & 7 deletions govtool/backend/sql/list-proposals.sql
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ CommitteeData AS (
FROM
committee_member cm
JOIN committee_hash ch ON cm.committee_hash_id = ch.id
WHERE EXISTS (
SELECT 1
FROM committee_registration cr
WHERE cr.cold_key_id = ch.id
)
AND NOT EXISTS (
SELECT 1
FROM committee_de_registration cdr
WHERE cdr.cold_key_id = ch.id
AND cdr.tx_id > (
SELECT MAX(cr2.tx_id)
FROM committee_registration cr2
WHERE cr2.cold_key_id = ch.id
)
)
ORDER BY
ch.raw, cm.expiration_epoch DESC
),
Expand All @@ -61,10 +76,31 @@ ParsedDescription AS (
MembersToBeRemoved AS (
SELECT
id,
json_agg(VALUE->>'keyHash') AS members_to_be_removed
json_agg(
json_build_object(
'hash', COALESCE(
VALUE->>'keyHash',
VALUE->>'scriptHash'
),
'type', CASE
WHEN VALUE->>'keyHash' IS NOT NULL THEN 'keyHash'
WHEN VALUE->>'scriptHash' IS NOT NULL THEN 'scriptHash'
ELSE 'unknown'
END,
'hasScript', CASE
WHEN VALUE->>'scriptHash' IS NOT NULL THEN true
ELSE false
END
)
) AS members_to_be_removed
FROM
ParsedDescription pd,
json_array_elements(members_to_be_removed::json) AS value
json_array_elements(
CASE
WHEN pd.members_to_be_removed IS NULL THEN '[]'::json
ELSE pd.members_to_be_removed::json
END
) AS value
GROUP BY
id
),
Expand All @@ -73,7 +109,15 @@ ProcessedCurrentMembers AS (
pd.id,
json_agg(
json_build_object(
'hash', regexp_replace(kv.key, '^keyHash-', ''),
'hash', COALESCE(
regexp_replace(kv.key, '^keyHash-', ''),
regexp_replace(kv.key, '^scriptHash-', '')
),
'type', CASE
WHEN kv.key LIKE 'keyHash-%' THEN 'keyHash'
WHEN kv.key LIKE 'scriptHash-%' THEN 'scriptHash'
ELSE 'unknown'
END,
'newExpirationEpoch', kv.value::int
)
) AS current_members
Expand All @@ -88,9 +132,17 @@ EnrichedCurrentMembers AS (
pcm.id,
json_agg(
json_build_object(
'hash', cm.hash,
'hash', CASE
WHEN (member->>'hash') LIKE 'scriptHash-%' THEN
regexp_replace(member->>'hash', '^scriptHash-', '')
WHEN (member->>'hash') LIKE 'keyHash-%' THEN
regexp_replace(member->>'hash', '^keyHash-', '')
ELSE
member->>'hash'
END,
'type', member->>'type',
'expirationEpoch', cm.expiration_epoch,
'hasScript', cm.has_script,
'hasScript', COALESCE(cm.has_script, member->>'type' = 'scriptHash'),
'newExpirationEpoch', (member->>'newExpirationEpoch')::int
)
) AS enriched_members
Expand Down Expand Up @@ -247,9 +299,9 @@ SELECT
)
FROM
ParsedDescription pd
JOIN
LEFT JOIN
MembersToBeRemoved mtr ON pd.id = mtr.id
JOIN
LEFT JOIN
EnrichedCurrentMembers em ON pd.id = em.id
WHERE
pd.id = gov_action_proposal.id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,51 @@ type CCMember = {
hash: string;
newExpirationEpoch?: number;
};
type CCMemberToBeRemoved = {
hash: string;
hasScript?: boolean;
};

function isArrayOfStrings(value: unknown): value is string[] {
return (
Array.isArray(value) && value.every((item) => typeof item === "string")
);
}
const getCip129Identifier = (hash: string, hasScript?: boolean) =>
encodeCIP129Identifier({
txID: (hasScript ? "13" : "12") + hash,
bech32Prefix: "cc_cold",
});

export const GovernanceActionNewCommitteeDetailsTabContent = ({
details,
}: Pick<ProposalData, "details">) => {
const { t } = useTranslation();
const membersToBeAdded = ((details?.members as CCMember[]) || [])
.filter((member) => member.newExpirationEpoch === undefined)
.filter(
(member) =>
member?.expirationEpoch === undefined ||
member?.expirationEpoch === null,
)
.filter((member) => member?.hash)
.map((member) => ({
cip129Identifier: encodeCIP129Identifier({
txID: (member.hasScript ? "02" : "13") + member.hash,
bech32Prefix: member.hasScript ? "cc_hot" : "cc_cold",
}),
cip129Identifier: getCip129Identifier(member.hash, member.hasScript),
expirationEpoch: member.expirationEpoch,
}));

const membersToBeUpdated = ((details?.members as CCMember[]) || [])
.filter((member) => member.newExpirationEpoch !== undefined)
.filter(
(member) => !!member?.expirationEpoch && !!member?.newExpirationEpoch,
)
.filter((member) => member?.hash)
.map((member) => ({
cip129Identifier: encodeCIP129Identifier({
txID: (member.hasScript ? "02" : "13") + member.hash,
bech32Prefix: member.hasScript ? "cc_hot" : "cc_cold",
}),
cip129Identifier: getCip129Identifier(member.hash, member.hasScript),
expirationEpoch: member.expirationEpoch,
newExpirationEpoch: member.newExpirationEpoch,
}));

const membersToBeRemoved = isArrayOfStrings(details?.membersToBeRemoved)
? details.membersToBeRemoved
: [];
const membersToBeRemoved = (
(details?.membersToBeRemoved as CCMemberToBeRemoved[]) || []
)
.filter((member) => member?.hash && member.hash.trim() !== "")
.map((member) => ({
cip129Identifier: getCip129Identifier(member.hash, member.hasScript),
}));

return (
<Box>
Expand All @@ -63,7 +73,7 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({
whiteSpace: "nowrap",
}}
>
{t("govActions.membersToBeAdded")}
{t("govActions.membersToBeAddedToTheCommittee")}
</Typography>
{membersToBeAdded.map(({ cip129Identifier }) => (
<Box display="flex" flexDirection="row">
Expand Down Expand Up @@ -101,10 +111,10 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({
whiteSpace: "nowrap",
}}
>
{t("govActions.membersToBeRemoved")}
{t("govActions.membersToBeRemovedFromTheCommittee")}
</Typography>
{membersToBeRemoved.map((hash) => (
<Box display="flex" flexDirection="row" key={hash}>
{membersToBeRemoved.map(({ cip129Identifier }) => (
<Box display="flex" flexDirection="row" key={cip129Identifier}>
<Typography
sx={{
fontSize: 16,
Expand All @@ -114,19 +124,10 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({
color: "primaryBlue",
}}
>
{encodeCIP129Identifier({
txID: hash,
bech32Prefix: "cc_cold",
})}
{cip129Identifier}
</Typography>
<Box ml={1}>
<CopyButton
text={encodeCIP129Identifier({
txID: hash,
bech32Prefix: "cc_cold",
})}
variant="blueThin"
/>
<CopyButton text={cip129Identifier} variant="blueThin" />
</Box>
</Box>
))}
Expand Down Expand Up @@ -179,8 +180,8 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({
}}
>
{t("govActions.changeToTermsEpochs", {
epochTo: newExpirationEpoch,
epochFrom: expirationEpoch,
epochTo: newExpirationEpoch ?? "N/A",
epochFrom: expirationEpoch ?? "N/A",
})}
</Typography>
</>
Expand Down
2 changes: 1 addition & 1 deletion govtool/frontend/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@
"membersToBeRemovedFromTheCommittee": "Members to be removed from the Committee",
"membersToBeAddedToTheCommittee": "Members to be added to the Committee",
"changeToTermsOfExistingMembers": "Change to terms of existing members",
"changeToTermsEpochs": "To {{epochTo}} epoch {{epochFrom}} epoch",
"changeToTermsEpochs": "To {{epochTo}} epoch, from {{epochFrom}} epoch",
"newThresholdValue": "New threshold value",
"protocolParamsDetails": {
"existing": "Existing",
Expand Down
Loading