Пример #1
0
    def monitor_settings(self):
        """Check if a modification of bridge settings is requested by seeing
        if the config file has been changed and try to update the bridge
        contract (gather 2/3 validators signatures).

        """
        config_data = load_config_data(self.config_file_path)
        t_anchor = self.eth_oracle.functions._tAnchor().call()
        config_t_anchor = (config_data['networks'][self.eth_net]['bridges'][
            self.aergo_net]['t_anchor'])
        if t_anchor != config_t_anchor:
            logger.info('\"Anchoring periode update requested: %s\"',
                        config_t_anchor)
            self.update_t_anchor(config_t_anchor)
        t_final = self.eth_oracle.functions._tFinal().call()
        config_t_final = (config_data['networks'][self.eth_net]['bridges'][
            self.aergo_net]['t_final'])
        if t_final != config_t_final:
            logger.info('\"Finality update requested: %s\"', config_t_final)
            self.update_t_final(config_t_final)
        if self.oracle_update:
            validators = self.eth_oracle.functions.getValidators().call()
            config_validators = \
                [val['eth-addr'] for val in config_data['validators']]
            if validators != config_validators:
                logger.info('\"Validator set update requested: %s\"',
                            config_validators)
                if self.update_validators(config_validators):
                    self.val_connect.use_new_validators(config_data)
            oracle = self.eth_bridge.functions._oracle().call()
            config_oracle = (config_data['networks'][self.eth_net]['bridges'][
                self.aergo_net]['oracle'])
            if oracle != config_oracle:
                logger.info('\"Oracle change requested: %s\"', config_oracle)
                self.update_oracle(config_oracle)
Пример #2
0
    def __init__(
        self,
        config_file_path: str,
        aergo_net: str,
        eth_net: str,
        root_path: str,
    ) -> None:
        self.config_file_path = config_file_path
        config_data = load_config_data(self.config_file_path)
        self.aergo_net = aergo_net
        self.eth_net = eth_net
        self.data_sources: List[SingleDataSource] = []
        try:
            aergo_providers = config_data['networks'][aergo_net]['providers']
            eth_providers = config_data['networks'][eth_net]['providers']
        except KeyError:
            # if providers were not registered, use the ip
            aergo_providers = [config_data['networks'][aergo_net]['ip']]
            eth_providers = [config_data['networks'][eth_net]['ip']]

        for i, aergo_ip in enumerate(aergo_providers):
            eth_ip = eth_providers[i]
            self.data_sources.append(
                SingleDataSource(config_file_path, aergo_net, eth_net,
                                 aergo_ip, eth_ip, root_path))
Пример #3
0
 def is_valid_aergo_validators(self, val_msg):
     config_data = load_config_data(self.config_file_path)
     config_vals = [val['eth-addr'] for val in config_data['validators']]
     for ds in self.data_sources:
         err_msg = ds.is_valid_aergo_validators(config_vals, val_msg)
         if err_msg is not None:
             return err_msg
     return None
Пример #4
0
 def is_valid_eth_oracle(self, oracle_msg):
     config_data = load_config_data(self.config_file_path)
     config_oracle = (config_data['networks'][self.aergo_net]['bridges'][
         self.eth_net]['oracle'])
     for ds in self.data_sources:
         err_msg = ds.is_valid_eth_oracle(config_oracle, oracle_msg)
         if err_msg is not None:
             return err_msg
     return None
Пример #5
0
 def is_valid_unfreeze_fee(self, new_fee_msg):
     config_data = load_config_data(self.config_file_path)
     config_fee = (config_data['networks'][self.aergo_net]['bridges'][
         self.eth_net]['unfreeze_fee'])
     for ds in self.data_sources:
         err_msg = ds.is_valid_unfreeze_fee(config_fee, new_fee_msg)
         if err_msg is not None:
             return err_msg
     return None
Пример #6
0
 def is_valid_aergo_t_final(
     self,
     tempo_msg,
 ) -> Optional[str]:
     config_data = load_config_data(self.config_file_path)
     config_tempo = (config_data['networks'][self.eth_net]['bridges'][
         self.aergo_net]["t_final"])
     for ds in self.data_sources:
         err_msg = ds.is_valid_aergo_t_final(config_tempo, tempo_msg)
         if err_msg is not None:
             return err_msg
     return None
Пример #7
0
    def __init__(
        self,
        config_file_path: str,
        aergo_net: str,
        eth_net: str,
        aergo_ip: str,
        eth_ip: str,
        root_path: str,
    ) -> None:
        self.config_file_path = config_file_path
        config_data = load_config_data(config_file_path)
        self.aergo_net = aergo_net
        self.eth_net = eth_net

        self.hera = herapy.Aergo()
        self.hera.connect(aergo_ip)

        self.web3 = Web3(Web3.HTTPProvider(eth_ip))
        eth_poa = config_data['networks'][eth_net]['isPOA']
        if eth_poa:
            self.web3.middleware_onion.inject(geth_poa_middleware, layer=0)
        assert self.web3.isConnected()

        # remember bridge contracts
        # eth bridge contract
        bridge_abi_path = (config_data['networks'][eth_net]['bridges']
                           [aergo_net]['bridge_abi'])
        with open(root_path + bridge_abi_path, "r") as f:
            bridge_abi = f.read()
        eth_bridge_addr = (
            config_data['networks'][eth_net]['bridges'][aergo_net]['addr'])
        self.eth_bridge = self.web3.eth.contract(address=eth_bridge_addr,
                                                 abi=bridge_abi)
        # eth oracle contract
        oracle_abi_path = (config_data['networks'][eth_net]['bridges']
                           [aergo_net]['oracle_abi'])
        with open(root_path + oracle_abi_path, "r") as f:
            oracle_abi = f.read()
        self.eth_oracle_addr = (
            config_data['networks'][eth_net]['bridges'][aergo_net]['oracle'])
        self.eth_oracle = self.web3.eth.contract(address=self.eth_oracle_addr,
                                                 abi=oracle_abi)
        # aergo bridge contract
        self.aergo_bridge = (
            config_data['networks'][aergo_net]['bridges'][eth_net]['addr'])
        # aergo oracle contract
        self.aergo_oracle = (
            config_data['networks'][aergo_net]['bridges'][eth_net]['oracle'])
Пример #8
0
    def monitor_settings(self):
        """Check if a modification of bridge settings is requested by seeing
        if the config file has been changed and try to update the bridge
        contract (gather 2/3 validators signatures).

        """
        config_data = load_config_data(self.config_file_path)
        t_anchor, t_final = query_aergo_tempo(self.hera, self.aergo_bridge)
        unfreeze_fee = query_unfreeze_fee(self.hera, self.aergo_bridge)
        config_t_anchor = (config_data['networks'][self.aergo_net]['bridges']
                           [self.eth_net]['t_anchor'])
        if t_anchor != config_t_anchor:
            logger.info(
                '\"Anchoring periode update requested: %s\"', config_t_anchor)
            self.update_t_anchor(config_t_anchor)
        config_t_final = (config_data['networks'][self.aergo_net]['bridges']
                          [self.eth_net]['t_final'])
        if t_final != config_t_final:
            logger.info('\"Finality update requested: %s\"', config_t_final)
            self.update_t_final(config_t_final)
        config_unfreeze_fee = (config_data['networks'][self.aergo_net]
                               ['bridges'][self.eth_net]['unfreeze_fee'])
        if unfreeze_fee != config_unfreeze_fee:
            logger.info(
                '\"Unfreeze fee update requested: %s\"', config_unfreeze_fee)
            self.update_unfreeze_fee(config_unfreeze_fee)
        if self.oracle_update:
            validators = query_aergo_validators(self.hera, self.aergo_oracle)
            config_validators = \
                [val['addr'] for val in config_data['validators']]
            if validators != config_validators:
                logger.info(
                    '\"Validator set update requested: %s\"',
                    config_validators
                )
                if self.update_validators(config_validators):
                    self.val_connect.use_new_validators(config_data)
            oracle = query_aergo_oracle(self.hera, self.aergo_bridge)
            config_oracle = (config_data['networks'][self.aergo_net]['bridges']
                             [self.eth_net]['oracle'])
            if oracle != config_oracle:
                logger.info('\"Oracle change requested: %s\"', config_oracle)
                self.update_oracle(config_oracle)
    def __init__(self,
                 config_file_path: str,
                 aergo_net: str,
                 eth_net: str,
                 privkey_name: str = None,
                 privkey_pwd: str = None,
                 validator_index: int = 0,
                 anchoring_on: bool = False,
                 auto_update: bool = False,
                 oracle_update: bool = False,
                 root_path: str = './') -> None:
        """ Initialize parameters of the bridge validator"""
        self.anchoring_on = anchoring_on
        self.auto_update = auto_update
        self.oracle_update = oracle_update
        self.data_sources = DataSources(config_file_path, aergo_net, eth_net,
                                        root_path)
        config_data = load_config_data(config_file_path)
        self.validator_index = validator_index
        self.aergo_net = aergo_net
        self.eth_net = eth_net
        self.aergo_oracle_id, self.eth_oracle_id = check_bridge_status(
            root_path, config_data, aergo_net, eth_net, auto_update,
            oracle_update)

        if privkey_name is None:
            privkey_name = 'validator'
        if privkey_pwd is None:
            privkey_pwd = getpass("Decrypt Aergo and Ethereum accounts '{}'\n"
                                  "Password: "******"\"Aergo validator Address: %s\"",
                    self.aergo_signer.address)

        # record private key for signing AergoAnchor
        logger.info("\"Ethereum validator Address: %s\"",
                    self.eth_signer.address)
Пример #10
0
    def __init__(self,
                 config_file_path: str,
                 aergo_net: str,
                 eth_net: str,
                 privkey_name: str = None,
                 privkey_pwd: str = None,
                 anchoring_on: bool = False,
                 auto_update: bool = False,
                 oracle_update: bool = False,
                 root_path: str = './',
                 eth_gas_price: int = None,
                 bridge_anchoring: bool = True) -> None:
        threading.Thread.__init__(self, name="EthProposerClient")
        if eth_gas_price is None:
            eth_gas_price = 10
        self.config_file_path = config_file_path
        config_data = load_config_data(config_file_path)
        self.eth_net = eth_net
        self.aergo_net = aergo_net
        self.anchoring_on = anchoring_on
        self.auto_update = auto_update
        self.oracle_update = oracle_update
        self.bridge_anchoring = bridge_anchoring
        logger.info("\"Connect Aergo and Ethereum providers\"")
        self.hera = herapy.Aergo()
        self.hera.connect(config_data['networks'][aergo_net]['ip'])

        # Web3 instance for reading blockchains state, shared with
        # EthValConnect.
        ip = config_data['networks'][eth_net]['ip']
        self.web3 = Web3(Web3.HTTPProvider(ip))
        eth_poa = config_data['networks'][eth_net]['isPOA']
        if eth_poa:
            self.web3.middleware_onion.inject(geth_poa_middleware, layer=0)
        assert self.web3.isConnected()

        # bridge contract
        bridge_abi_path = (config_data['networks'][eth_net]['bridges']
                           [aergo_net]['bridge_abi'])
        with open(root_path + bridge_abi_path, "r") as f:
            bridge_abi = f.read()
        eth_bridge_address = (
            config_data['networks'][eth_net]['bridges'][aergo_net]['addr'])
        self.eth_bridge = self.web3.eth.contract(address=eth_bridge_address,
                                                 abi=bridge_abi)
        # oracle contract
        oracle_abi_path = (config_data['networks'][eth_net]['bridges']
                           [aergo_net]['oracle_abi'])
        with open(root_path + oracle_abi_path, "r") as f:
            oracle_abi = f.read()
        eth_oracle_address = (
            config_data['networks'][eth_net]['bridges'][aergo_net]['oracle'])
        self.eth_oracle = self.web3.eth.contract(address=eth_oracle_address,
                                                 abi=oracle_abi)
        self.aergo_bridge = (
            config_data['networks'][aergo_net]['bridges'][eth_net]['addr'])

        # get the current t_anchor and t_final for anchoring on etherem
        self.t_anchor = self.eth_bridge.functions._tAnchor().call()
        self.t_final = self.eth_bridge.functions._tFinal().call()
        logger.info("\"%s (t_final=%s ) -> %s : t_anchor=%s\"", aergo_net,
                    self.t_final, eth_net, self.t_anchor)

        if privkey_name is None:
            privkey_name = 'proposer'
        keystore = config_data["wallet-eth"][privkey_name]['keystore']
        with open(root_path + keystore, "r") as f:
            encrypted_key = f.read()
        if privkey_pwd is None:
            privkey_pwd = getpass("Decrypt Ethereum keystore '{}'\n"
                                  "Password: "******"\"Connect to EthValidators\"")
        self.val_connect = EthValConnect(config_data, self.web3,
                                         eth_oracle_address, oracle_abi)
Пример #11
0
    def __init__(
        self,
        config_file_path: str,
        aergo_net: str,
        eth_net: str,
        eth_block_time: int,
        privkey_name: str = None,
        privkey_pwd: str = None,
        anchoring_on: bool = False,
        auto_update: bool = False,
        oracle_update: bool = False,
        aergo_gas_price: int = None,
        bridge_anchoring: bool = True
    ) -> None:
        threading.Thread.__init__(self, name="AergoProposerClient")
        if aergo_gas_price is None:
            aergo_gas_price = 0
        self.aergo_gas_price = aergo_gas_price
        self.config_file_path = config_file_path
        config_data = load_config_data(self.config_file_path)
        self.eth_block_time = eth_block_time
        self.eth_net = eth_net
        self.aergo_net = aergo_net
        self.anchoring_on = anchoring_on
        self.auto_update = auto_update
        self.oracle_update = oracle_update
        self.bridge_anchoring = bridge_anchoring
        logger.info("\"Connect Aergo and Ethereum providers\"")
        self.hera = herapy.Aergo()
        self.hera.connect(config_data['networks'][aergo_net]['ip'])

        ip = config_data['networks'][eth_net]['ip']
        self.web3 = Web3(Web3.HTTPProvider(ip))
        eth_poa = config_data['networks'][eth_net]['isPOA']
        if eth_poa:
            self.web3.middleware_onion.inject(geth_poa_middleware, layer=0)
        assert self.web3.isConnected()

        self.eth_bridge = (config_data['networks'][eth_net]['bridges']
                           [aergo_net]['addr'])
        self.aergo_bridge = (config_data['networks'][aergo_net]['bridges']
                             [eth_net]['addr'])
        self.aergo_oracle = (config_data['networks'][aergo_net]['bridges']
                             [eth_net]['oracle'])

        # get the current t_anchor and t_final for both sides of bridge
        self.t_anchor, self.t_final = query_aergo_tempo(
            self.hera, self.aergo_bridge
        )
        logger.info(
            "\"%s <- %s (t_final=%s) : t_anchor=%s\"", aergo_net, eth_net,
            self.t_final, self.t_anchor
        )

        if privkey_name is None:
            privkey_name = 'proposer'
        if privkey_pwd is None:
            privkey_pwd = getpass("Decrypt exported private key '{}'\n"
                                  "Password: "******"\"Connect to AergoValidators\"")
        self.val_connect = AergoValConnect(
            config_data, self.hera, self.aergo_oracle)
Пример #12
0
    def __init__(
        self,
        config_file_path: str,
        aergo_net: str,
        eth_net: str,
        eth_block_time: int,
        privkey_name: str = None,
        privkey_pwd: str = None,
        anchoring_on: bool = False,
        auto_update: bool = False,
        oracle_update: bool = False,
        aergo_gas_price: int = None,
        bridge_anchoring: bool = True,
        root_path: str = './',
        eco: bool = False
    ) -> None:
        threading.Thread.__init__(self, name="AergoProposerClient")
        if aergo_gas_price is None:
            aergo_gas_price = 0
        self.aergo_gas_price = aergo_gas_price
        self.config_file_path = config_file_path
        config_data = load_config_data(self.config_file_path)
        self.eth_block_time = eth_block_time
        self.eth_net = eth_net
        self.aergo_net = aergo_net
        self.anchoring_on = anchoring_on
        self.auto_update = auto_update
        self.oracle_update = oracle_update
        self.bridge_anchoring = bridge_anchoring
        self.eco = eco

        logger.info("\"Connect Aergo and Ethereum providers\"")
        self.hera = herapy.Aergo()
        self.hera.connect(config_data['networks'][aergo_net]['ip'])

        ip = config_data['networks'][eth_net]['ip']
        self.web3 = Web3(Web3.HTTPProvider(ip))
        eth_poa = config_data['networks'][eth_net]['isPOA']
        if eth_poa:
            self.web3.middleware_onion.inject(geth_poa_middleware, layer=0)
        assert self.web3.isConnected()

        eth_bridge_abi_path = (config_data['networks'][eth_net]['bridges']
                               [aergo_net]['bridge_abi'])
        with open(root_path + eth_bridge_abi_path, "r") as f:
            eth_bridge_abi = f.read()
        self.eth_bridge_addr = (config_data['networks'][eth_net]['bridges']
                                [aergo_net]['addr'])
        self.eth_bridge = self.web3.eth.contract(
            address=self.eth_bridge_addr,
            abi=eth_bridge_abi
        )

        self.aergo_bridge = (config_data['networks'][aergo_net]['bridges']
                             [eth_net]['addr'])
        self.aergo_oracle = (config_data['networks'][aergo_net]['bridges']
                             [eth_net]['oracle'])

        # get the current t_anchor and t_final for both sides of bridge
        self.t_anchor, self.t_final = query_aergo_tempo(
            self.hera, self.aergo_bridge
        )
        logger.info(
            "\"%s <- %s (t_final=%s) : t_anchor=%s\"", aergo_net, eth_net,
            self.t_final, self.t_anchor
        )

        if not anchoring_on and not auto_update:
            # if anchoring and auto update are off, use proposer as monitoring
            # system
            return

        if privkey_name is None:
            privkey_name = 'proposer'
        keystore_path = config_data["wallet"][privkey_name]['keystore']
        with open(root_path + keystore_path, "r") as f:
            keystore = f.read()
        if privkey_pwd is None:
            while True:
                try:
                    privkey_pwd = getpass(
                        "Decrypt Aergo keystore: '{}'\nPassword: "******"\"Wrong password, try again\"")
        else:
            self.aergo_tx = AergoTx(
                self.hera, keystore, privkey_pwd, self.aergo_oracle,
                aergo_gas_price, self.t_anchor, eth_block_time
            )

        logger.info("\"Connect to AergoValidators\"")
        self.val_connect = AergoValConnect(
            config_data, self.hera, self.aergo_oracle)
Пример #13
0
    def __init__(self,
                 config_file_path: str,
                 aergo_net: str,
                 eth_net: str,
                 privkey_name: str = None,
                 privkey_pwd: str = None,
                 validator_index: int = 0,
                 anchoring_on: bool = False,
                 auto_update: bool = False,
                 oracle_update: bool = False,
                 root_path: str = './') -> None:
        """ Initialize parameters of the bridge validator"""
        self.anchoring_on = anchoring_on
        self.auto_update = auto_update
        self.oracle_update = oracle_update
        self.data_sources = DataSources(config_file_path, aergo_net, eth_net,
                                        root_path)
        config_data = load_config_data(config_file_path)
        self.validator_index = validator_index
        self.aergo_net = aergo_net
        self.eth_net = eth_net
        self.aergo_oracle_id, self.eth_oracle_id = check_bridge_status(
            root_path, config_data, aergo_net, eth_net, auto_update,
            oracle_update)

        if privkey_name is None:
            privkey_name = 'validator'

        keystore_path = config_data["wallet-eth"][privkey_name]['keystore']
        with open(root_path + keystore_path, "r") as f:
            eth_keystore = f.read()
        keystore_path = config_data["wallet"][privkey_name]['keystore']
        with open(root_path + keystore_path, "r") as f:
            aergo_keystore = f.read()

        if privkey_pwd is None:
            while True:
                try:
                    privkey_pwd = getpass(
                        "Decrypt Aergo and Ethereum accounts '{}'\nPassword: "******"\"Wrong password for Eth key, try again\"")
                except HeraException:
                    logger.info("\"Wrong password for Aergo key, try again\"")
        else:
            self.eth_signer = EthSigner(eth_keystore, privkey_name,
                                        privkey_pwd)
            self.aergo_signer = AergoSigner(aergo_keystore, privkey_name,
                                            privkey_pwd)
        # record private key for signing EthAnchor
        logger.info("\"Aergo validator Address: %s\"",
                    self.aergo_signer.address)

        # record private key for signing AergoAnchor
        logger.info("\"Ethereum validator Address: %s\"",
                    self.eth_signer.address)