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)
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))
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
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
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
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
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'])
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)
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)
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)
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)
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)