in src/ccf/ccf-provider-common/constitution/actions.js [438:490]
function (args) {
const rawMemberId = ccf.strToBuf(args.member_id);
const rawMemberInfo =
ccf.kv["public:ccf.gov.members.info"].get(rawMemberId);
if (rawMemberInfo === undefined) {
return; // Idempotent
}
const memberInfo = ccf.bufToJsonCompatible(rawMemberInfo);
const isActiveMember = memberInfo.status == "Active";
const isRecoveryMember = ccf.kv[
"public:ccf.gov.members.encryption_public_keys"
].has(rawMemberId)
? true
: false;
// If the member is an active recovery member, check that there
// would still be a sufficient number of recovery members left
// to recover the service
if (isActiveMember && isRecoveryMember) {
const rawConfig = ccf.kv["public:ccf.gov.service.config"].get(
getSingletonKvKey()
);
if (rawConfig === undefined) {
throw new Error("Service configuration could not be found");
}
const config = ccf.bufToJsonCompatible(rawConfig);
const activeRecoveryMembersCountAfter =
getActiveRecoveryMembersCount() - 1;
if (activeRecoveryMembersCountAfter < config.recovery_threshold) {
throw new Error(
`Number of active recovery members (${activeRecoveryMembersCountAfter}) would be less than recovery threshold (${config.recovery_threshold})`
);
}
}
ccf.kv["public:ccf.gov.members.info"].delete(rawMemberId);
ccf.kv["public:ccf.gov.members.encryption_public_keys"].delete(
rawMemberId
);
ccf.kv["public:ccf.gov.members.certs"].delete(rawMemberId);
ccf.kv["public:ccf.gov.members.acks"].delete(rawMemberId);
ccf.kv["public:ccf.gov.history"].delete(rawMemberId);
if (isActiveMember && isRecoveryMember) {
// A retired recovery member should not have access to the private
// ledger going forward so rekey the ledger, issuing new shares to
// remaining active recovery members
ccf.node.triggerLedgerRekey();
}
}