Example #1
0
    def __init__(
        self,
        common_dir,
        key_generator,
        share_script,
        consensus,
        members_info=None,
        curve=None,
        public_state=None,
        authenticate_session=True,
        reconfiguration_type=None,
    ):
        self.common_dir = common_dir
        self.members = []
        self.key_generator = key_generator
        self.share_script = share_script
        self.consensus = consensus
        self.recovery_threshold = None
        self.authenticate_session = authenticate_session
        self.reconfiguration_type = reconfiguration_type
        # If a list of member IDs is passed in, generate fresh member identities.
        # Otherwise, recover the state of the consortium from the common directory
        # and the state of the service
        if members_info is not None:
            self.recovery_threshold = 0
            for m_local_id, has_share, m_data in members_info:
                new_member = infra.member.Member(
                    f"member{m_local_id}",
                    curve,
                    common_dir,
                    share_script,
                    has_share,
                    key_generator,
                    m_data,
                    authenticate_session=authenticate_session,
                )
                if has_share:
                    self.recovery_threshold += 1
                self.members.append(new_member)
        else:
            for f in os.listdir(self.common_dir):
                if re.search("member(.*)_cert.pem", f) is not None:
                    local_id = f.split("_")[0]
                    new_member = infra.member.Member(
                        local_id,
                        curve,
                        self.common_dir,
                        share_script,
                        is_recovery_member=os.path.isfile(
                            os.path.join(self.common_dir,
                                         f"{local_id}_enc_privk.pem")),
                        authenticate_session=authenticate_session,
                    )
                    self.members.append(new_member)
                    LOG.info(
                        f"Successfully recovered member {local_id}: {new_member.service_id}"
                    )

            self.recovery_threshold = json.loads(
                public_state["public:ccf.gov.service.config"][
                    ccf.ledger.WELL_KNOWN_SINGLETON_TABLE_KEY]
            )["recovery_threshold"]

            if not self.members:
                LOG.warning("No consortium member to recover")
                return

            for id_bytes, info_bytes in public_state[
                    "public:ccf.gov.members.info"].items():
                member_id = id_bytes.decode()
                member_info = json.loads(info_bytes)

                status = member_info["status"]
                member = self.get_member_by_service_id(member_id)
                if member:
                    if (infra.member.MemberStatus(status) ==
                            infra.member.MemberStatus.ACTIVE):
                        member.set_active()
                else:
                    LOG.warning(
                        f"Keys and certificates for consortium member {member_id} do not exist locally"
                    )
Example #2
0
    def __init__(
        self,
        common_dir,
        key_generator,
        share_script,
        members_info=None,
        curve=None,
        remote_node=None,
        authenticate_session=True,
    ):
        self.common_dir = common_dir
        self.members = []
        self.key_generator = key_generator
        self.share_script = share_script
        self.members = []
        self.recovery_threshold = None
        self.authenticate_session = authenticate_session
        # If a list of member IDs is passed in, generate fresh member identities.
        # Otherwise, recover the state of the consortium from the common directory
        # and the state of the service
        if members_info is not None:
            self.recovery_threshold = 0
            for m_local_id, has_share, m_data in members_info:
                new_member = infra.member.Member(
                    f"member{m_local_id}",
                    curve,
                    common_dir,
                    share_script,
                    has_share,
                    key_generator,
                    m_data,
                    authenticate_session=authenticate_session,
                )
                if has_share:
                    self.recovery_threshold += 1
                self.members.append(new_member)
        else:
            for f in os.listdir(self.common_dir):
                if re.search("member(.*)_cert.pem", f) is not None:
                    local_id = f.split("_")[0]
                    new_member = infra.member.Member(
                        local_id,
                        curve,
                        self.common_dir,
                        share_script,
                        is_recovery_member=os.path.isfile(
                            os.path.join(self.common_dir,
                                         f"{local_id}_enc_privk.pem")),
                        authenticate_session=authenticate_session,
                    )
                    self.members.append(new_member)
                    LOG.info(
                        f"Successfully recovered member {local_id}: {new_member.service_id}"
                    )

            if not self.members:
                LOG.warning("No consortium member to recover")
                return

            with remote_node.client(self.members[0].local_id) as c:
                r = c.post(
                    "/gov/query",
                    {
                        "text":
                        """tables = ...
                        non_retired_members = {}
                        tables["public:ccf.gov.members.info"]:foreach(function(service_id, info)
                        if info["status"] ~= "RETIRED" then
                            table.insert(non_retired_members, {service_id, info})
                        end
                        end)
                        return non_retired_members
                        """
                    },
                )
                for member_service_id, info in r.body.json():
                    status = info["status"]
                    member = self.get_member_by_service_id(member_service_id)
                    if member:
                        if (infra.member.MemberStatus[status] ==
                                infra.member.MemberStatus.ACTIVE):
                            member.set_active()
                    else:
                        LOG.warning(
                            f"Keys and certificates for consortium member {member_service_id} do not exist locally"
                        )

                r = c.post(
                    "/gov/query",
                    {
                        "text":
                        """tables = ...
                        return tables["public:ccf.gov.service.config"]:get(0)
                        """
                    },
                )
                self.recovery_threshold = r.body.json()["recovery_threshold"]