Exemple #1
0
 def get_tempo(
     self,
     hera: herapy.Aergo,
     aergo_from: str,
     aergo_to: str,
     oracle_to: str,
     id_to: str,
     tempo_msg,
     tempo_str,
     tempo_id,
     current_tempo,
 ):
     # 1 - check destination nonce is correct
     nonce = int(
         hera.query_sc_state(
             oracle_to, ["_sv__nonce"]).var_proofs[0].value
     )
     if nonce != tempo_msg.destination_nonce:
         err_msg = ("Incorrect Nonce, got: {}, expected: {}"
                    .format(tempo_msg.destination_nonce, nonce))
         logger.warning(
             error_log_template, self.validator_index, "false",
             "\u231B " + tempo_str, aergo_to, err_msg
         )
         return Approval(error=err_msg)
     config_data = self.load_config_data()
     tempo = (config_data['networks'][aergo_to]['bridges']
              [aergo_from][tempo_str])
     # 2 - check new tempo is different from current one to prevent
     # update spamming
     if current_tempo == tempo:
         err_msg = "Not voting for a new {}".format(tempo_str)
         logger.warning(
             error_log_template, self.validator_index, "false",
             "\u231B " + tempo_str, aergo_to, err_msg
         )
         return Approval(error=err_msg)
     # 3 - check tempo matches the one in config
     if tempo != tempo_msg.tempo:
         err_msg = ("Invalid {}, got: {}, expected: {}"
                    .format(tempo_str, tempo_msg.tempo, tempo))
         logger.warning(
             error_log_template, self.validator_index, "false",
             "\u231B " + tempo_str, aergo_to, err_msg
         )
         return Approval(error=err_msg)
     # sign anchor and return approval
     msg = bytes(
         str(tempo) + str(nonce) + id_to + tempo_id,
         'utf-8'
     )
     h = hashlib.sha256(msg).digest()
     sig = hera.account.private_key.sign_msg(h)
     approval = Approval(address=self.address, sig=sig)
     logger.info(
         success_log_template, self.validator_index, "true",
         "\u231B " + tempo_str, aergo_to, tempo_msg.tempo,
         tempo_msg.destination_nonce
     )
     return approval
Exemple #2
0
 def get_validators(
     self,
     hera: herapy.Aergo,
     oracle_to: str,
     id_to: str,
     aergo_to,
     val_msg,
 ):
     # 1 - check destination nonce is correct
     nonce = int(
         hera.query_sc_state(
             oracle_to, ["_sv__nonce"]).var_proofs[0].value
     )
     if nonce != val_msg.destination_nonce:
         err_msg = ("Incorrect Nonce, got: {}, expected: {}"
                    .format(val_msg.destination_nonce, nonce))
         logger.warning(
             error_log_template, self.validator_index, "false",
             "\U0001f58b validator set", aergo_to, err_msg
         )
         return Approval(error=err_msg)
     config_data = self.load_config_data()
     config_vals = [val['addr'] for val in config_data['validators']]
     # 2 - check new validators are different from current ones to prevent
     # update spamming
     current_validators = query_validators(hera, oracle_to)
     if current_validators == config_vals:
         err_msg = "Not voting for a new validator set"
         logger.warning(
             error_log_template, self.validator_index, "false",
             "\U0001f58b validator set", aergo_to, err_msg
         )
         return Approval(error=err_msg)
     # 3 - check validators are same in config file
     if config_vals != val_msg.validators:
         err_msg = ("Invalid validator set, got: {}, expected: {}"
                    .format(val_msg.validators, config_vals))
         logger.warning(
             error_log_template, self.validator_index, "false",
             "\U0001f58b validator set", aergo_to, err_msg
         )
         return Approval(error=err_msg)
     # sign validators
     data = ""
     for val in config_vals:
         data += val
     data += str(nonce) + id_to + "V"
     data_bytes = bytes(data, 'utf-8')
     h = hashlib.sha256(data_bytes).digest()
     sig = hera.account.private_key.sign_msg(h)
     approval = Approval(address=self.address, sig=sig)
     logger.info(
         success_log_template, self.validator_index, "true",
         "\U0001f58b validator set", aergo_to, val_msg.validators,
         val_msg.destination_nonce
     )
     return approval
Exemple #3
0
    def get_oracle(self, hera: herapy.Aergo, aergo_from: str, aergo_to: str,
                   oracle_to: str, id_to: str, bridge_to: str, oracle_msg):
        """Get a vote(signature) from the validator to update the
        oracle controlling the bridge contract

        """
        # 1 - check destination nonce is correct
        nonce = int(
            hera.query_sc_state(oracle_to, ["_sv__nonce"]).var_proofs[0].value)
        if nonce != oracle_msg.destination_nonce:
            err_msg = ("Incorrect Nonce, got: {}, expected: {}".format(
                oracle_msg.destination_nonce, nonce))
            logger.warning(error_log_template, self.validator_index, "false",
                           "\U0001f58b oracle change", aergo_to, err_msg)
            return Approval(error=err_msg)

        config_data = self.load_config_data()
        config_oracle = \
            config_data['networks'][aergo_to]['bridges'][aergo_from]['oracle']
        # 2 - check new oracle is different from current one to prevent
        # update spamming
        current_oracle = query_oracle(hera, bridge_to)
        if current_oracle == config_oracle:
            err_msg = "Not voting for a new oracle"
            logger.warning(error_log_template, self.validator_index, "false",
                           "\U0001f58b oracle change", aergo_to, err_msg)
            return Approval(error=err_msg)
        # 3 - check validators are same in config file
        if config_oracle != oracle_msg.oracle:
            err_msg = ("Invalid oracle, got: {}, expected: {}".format(
                oracle_msg.oracle, config_oracle))
            logger.warning(error_log_template, self.validator_index, "false",
                           "\U0001f58b oracle change", aergo_to, err_msg)
            return Approval(error=err_msg)

        # sign validators
        data = oracle_msg.oracle \
            + str(oracle_msg.destination_nonce) + id_to + "O"
        data_bytes = bytes(data, 'utf-8')
        h = hashlib.sha256(data_bytes).digest()
        sig = hera.account.private_key.sign_msg(h)
        approval = Approval(address=self.address, sig=sig)
        logger.info(success_log_template, self.validator_index, "true",
                    "\U0001f58b oracle change", aergo_to,
                    "\"{}\"".format(oracle_msg.oracle),
                    oracle_msg.destination_nonce)
        return approval
Exemple #4
0
 def GetValidatorsSignature(self, val_msg, context):
     if not (self.auto_update and self.oracle_update):
         return Approval(error="Oracle validators update not enabled")
     if val_msg.is_from_mainnet:
         return self.get_validators(self.hera2, self.oracle2, self.id2,
                                    self.aergo2, val_msg)
     else:
         return self.get_validators(self.hera1, self.oracle1, self.id1,
                                    self.aergo2, val_msg)
Exemple #5
0
    def GetAnchorSignature(self, anchor, context):
        """ Verifies the anchors are valid and signes them
            aergo1 and aergo2 must be trusted.
        """
        if not self.anchoring_on:
            return Approval(error="Anchoring not enabled")
        destination = ""
        bridge_id = ""
        if anchor.is_from_mainnet:
            # aergo1 is considered to be mainnet side of bridge
            err_msg = self.is_valid_anchor(
                anchor, self.hera1, self.hera2, self.oracle2)
            destination = self.aergo2
            bridge_id = self.id2
        else:
            err_msg = self.is_valid_anchor(
                anchor, self.hera2, self.hera1, self.oracle1)
            destination = self.aergo1
            bridge_id = self.id1
        if err_msg is not None:
            logger.warning(
                error_log_template, self.validator_index, "false",
                "\u2693 anchor", destination, err_msg
            )
            return Approval(error=err_msg)

        # sign anchor and return approval
        msg = bytes(
            anchor.root + ',' + str(anchor.height)
            + str(anchor.destination_nonce) + bridge_id + "R", 'utf-8'
        )
        h = hashlib.sha256(msg).digest()
        sig = self.hera1.account.private_key.sign_msg(h)
        approval = Approval(address=self.address, sig=sig)
        logger.info(
            success_log_template, self.validator_index, "true",
            "\u2693 anchor", destination,
            "{{\"root\": \"0x{}\", \"height\": {}}}"
            .format(anchor.root, anchor.height),
            anchor.destination_nonce
        )
        return approval
Exemple #6
0
    def GetOracleSignature(self, oracle_msg, context):
        if not (self.auto_update and self.oracle_update):
            return Approval(error="Oracle update not enabled")

        if oracle_msg.is_from_mainnet:
            return self.get_oracle(self.hera2, self.aergo1, self.aergo2,
                                   self.oracle2, self.id2, self.bridge2,
                                   oracle_msg)
        else:
            return self.get_oracle(self.hera1, self.aergo2, self.aergo1,
                                   self.oracle1, self.id1, self.bridge1,
                                   oracle_msg)
Exemple #7
0
    def GetTFinalSignature(self, tempo_msg, context):
        """Get a vote(signature) from the validator to update the t_final
        setting in the Aergo bridge contract

        """
        if not self.auto_update:
            return Approval(error="Setting update not enabled")
        if tempo_msg.is_from_mainnet:
            current_tempo = query_tempo(self.hera2, self.oracle2,
                                        ["_sv__tFinal"])
            return self.get_tempo(self.hera2, self.aergo1, self.aergo2,
                                  self.oracle2, self.id2, tempo_msg, 't_final',
                                  "F", current_tempo)
        else:
            current_tempo = query_tempo(self.hera1, self.oracle1,
                                        ["_sv__tFinal"])
            return self.get_tempo(self.hera1, self.aergo2, self.aergo1,
                                  self.oracle1, self.id1, tempo_msg, 't_final',
                                  "F", current_tempo)