From d9ea3743a7ac6cd2d91aed160ea24608187f0a7a Mon Sep 17 00:00:00 2001 From: Felipe Alvarado Date: Wed, 20 Mar 2024 10:30:41 +0100 Subject: [PATCH] Add convert name for chain and validate addresses --- .../create_pr_with_new_address.py | 17 ++- .../validate_new_address_issue_input_data.py | 110 ++++++++++++++---- 2 files changed, 100 insertions(+), 27 deletions(-) diff --git a/.github/scripts/github_adding_addresses/create_pr_with_new_address.py b/.github/scripts/github_adding_addresses/create_pr_with_new_address.py index 7c65c3655..dfce7bbb5 100644 --- a/.github/scripts/github_adding_addresses/create_pr_with_new_address.py +++ b/.github/scripts/github_adding_addresses/create_pr_with_new_address.py @@ -16,13 +16,22 @@ from gnosis.eth import EthereumClient +def convert_chain_name(name: str) -> str: + # Change every symbol that is not a word or digit for underscore + name_converted = re.sub(r"[^\w\d]+", r"_", name.upper().replace(")", "")) + # Add underscore at the beggining if start by digit + if name_converted[0].isdigit(): + name_converted = "_" + name_converted + return name_converted + + def get_chain_enum_name(chain_id: int) -> Optional[str]: try: url = f"https://raw.githubusercontent.com/ethereum-lists/chains/master/_data/chains/eip155-{chain_id}.json" response = requests.get(url) if response.status_code == 200: - return response.json().get("name").upper().replace(" ", "_") + return convert_chain_name(response.json().get("name")) return None except IOError as e: print(f"Error getting chain name: {e}") @@ -34,7 +43,7 @@ def get_contract_block_from_tx_hash(rpc_url: str, tx_hash: str) -> Optional[int] tx = ethereum_client.get_transaction(tx_hash) if not tx: print(f"Transaction not found: {tx_hash}") - return + return None return tx.get("blockNumber") @@ -113,7 +122,7 @@ def upsert_chain_id( branch_name, ) - print(f"Entry '{chain_enum_name} = {chain_id}' added successfully.") + print(f"Entry '{chain_enum_name} = {chain_id}' added successfully.") else: print("Error: EthereumNetwork class definition not found in the file.") @@ -369,7 +378,7 @@ def execute_issue_changes() -> None: chain_enum_name = get_chain_enum_name(chain_id) if not chain_enum_name: - return + return None branch_name = create_issue_branch(repo, chain_id, version) diff --git a/.github/scripts/github_adding_addresses/validate_new_address_issue_input_data.py b/.github/scripts/github_adding_addresses/validate_new_address_issue_input_data.py index e4971b693..7c1418448 100644 --- a/.github/scripts/github_adding_addresses/validate_new_address_issue_input_data.py +++ b/.github/scripts/github_adding_addresses/validate_new_address_issue_input_data.py @@ -6,6 +6,7 @@ import json import os +import re import uuid from typing import Any, Dict, Optional @@ -18,13 +19,22 @@ ERRORS = [] -def get_chain_name(chain_id: int) -> Optional[str]: +def convert_chain_name(name: str) -> str: + # Change every symbol that is not a word or digit for underscore + name_converted = re.sub(r"[^\w\d]+", r"_", name.upper().replace(")", "")) + # Add underscore at the beggining if start by digit + if name_converted[0].isdigit(): + name_converted = "_" + name_converted + return name_converted + + +def get_chain_enum_name(chain_id: int) -> Optional[str]: try: url = f"https://raw.githubusercontent.com/ethereum-lists/chains/master/_data/chains/eip155-{chain_id}.json" response = requests.get(url) if response.status_code == 200: - return response.json().get("name") + return convert_chain_name(response.json().get("name")) return None except IOError as e: print(f"Error getting chain name: {e}") @@ -53,7 +63,7 @@ def get_contract_address_and_block_from_tx_hash( tx = ethereum_client.get_transaction(tx_hash) if not tx: print(f"Transaction not found: {tx_hash}") - return + return None return { "block": tx.get("blockNumber"), "address": mk_contract_address_2( @@ -65,17 +75,17 @@ def get_contract_address_and_block_from_tx_hash( def validate_chain(chain_id_input: str) -> Optional[Dict[str, Any]]: if not chain_id_input.isdigit(): ERRORS.append("Chain ID is required.") - return + return None if not chain_id_input: ERRORS.append("Chain ID is required.") - return + return None chain_id = int(chain_id_input) - chain_name = (get_chain_name(chain_id), chain_id) + chain_name = get_chain_enum_name(chain_id) if not chain_name: ERRORS.append(f"Chain with chain ID: {chain_id} not found.") - return + return None print(f"Chain name: {chain_name}") return {"chain_id": chain_id, "chain_name": chain_name} @@ -84,22 +94,22 @@ def validate_chain(chain_id_input: str) -> Optional[Dict[str, Any]]: def validate_rpc(rpc_url: str, chain_id: int) -> None: if not rpc_url: ERRORS.append("RPC URL is required.") - return + return None if not chain_id: ERRORS.append("Unable to validate RPC URL without chain ID.") - return + return None rpc_chain_id = get_chain_id_from_rpc_url(rpc_url) if not rpc_chain_id: ERRORS.append(f"Unable to validate RPC URL {rpc_url}.") - return + return None if rpc_chain_id != int(chain_id): ERRORS.append( f"Chain ID {chain_id} provided is different than chain id obtained from RPC URL {rpc_url} {rpc_chain_id}." ) - return + return None print(f"Chain ID obtained from rpc url: {rpc_chain_id}") @@ -108,51 +118,103 @@ def validate_not_required_url(field_name: str, url: str) -> None: if url: if not validators.url(url): ERRORS.append(f"{field_name} URL ({url}) provided is not valid.") - return + return None print(f"Validating {field_name} URL -> {url}") - return + return None print(f"Skipping {field_name} URL validation!") def validate_version(version: str) -> None: - if version not in ["1.3.0", "1.3.0 L2", "1.4.1", "1.4.1 L2"]: + if version not in ["1.3.0", "1.3.0+L2", "1.4.1", "1.4.1+L2"]: ERRORS.append(f"Version {version} is not valid.") - return + return None print(f"Validating version: {version}!") +def validate_master_copy_address_by_version(address: str, version: str) -> None: + valid_versions_master_copy = { + "1.3.0": [ + "0x69f4D1788e39c87893C980c06EdF4b7f686e2938", + "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", + ], + "1.3.0+L2": [ + "0x3E5c63644E683549055b9Be8653de26E0B4CD36E", + "0xfb1bffC9d739B8D520DaF37dF666da4C687191EA", + ], + "1.4.1": ["0x41675C099F32341bf84BFc5382aF534df5C7461a"], + "1.4.1+L2": ["0x29fcB43b46531BcA003ddC8FCB67FFE91900C762"], + } + + if version not in valid_versions_master_copy.keys(): + ERRORS.append("Unable to validate Master copy address without valid version.") + return None + + if address not in valid_versions_master_copy[version]: + ERRORS.append( + f"Master copy address {address} is not valid for version {version}" + ) + return None + + print(f"Master copy address {address} is valid for version {version}") + + +def validate_proxy_address_by_version(address: str, version: str) -> None: + valid_versions_proxy = { + "1.3.0": [ + "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", + "0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC", + ], + "1.3.0+L2": [ + "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", + "0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC", + ], + "1.4.1": ["0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67"], + "1.4.1+L2": ["0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67"], + } + + if version not in valid_versions_proxy.keys(): + ERRORS.append("Unable to validate Proxy address without valid version.") + return None + + if address not in valid_versions_proxy[version]: + ERRORS.append(f"Proxy address {address} is not valid for version {version}") + return None + + print(f"Proxy address {address} is valid for version {version}") + + def validate_address_and_transactions( type: str, address: str, tx_hash: str, rpc_url: str ) -> Optional[Dict[str, Any]]: if not address and not tx_hash: print("Skipping address and tx validation. Not data provided!") - return + return None if not address: ERRORS.append(f"{type} address is required.") - return + return None if not tx_hash: ERRORS.append(f"{type} tx_hash is required.") - return + return None if not rpc_url: ERRORS.append(f"Unable to validate {type} address and tx without RPC URL.") - return + return None tx_info = get_contract_address_and_block_from_tx_hash(rpc_url, tx_hash) if not tx_info: ERRORS.append(f"Unable to obtain {type} Tx info {tx_hash}") - return + return None if tx_info["address"] != address: ERRORS.append( f"{type} address obtained from Tx is diferent than provided {tx_info['address']}" ) - return + return None print(f"{type} Tx. info: {tx_info}") return tx_info @@ -200,6 +262,8 @@ def validate_issue_inputs() -> None: validate_not_required_url("EtherscanClientUrl", etherscan_client_url) validate_not_required_url("EtherscanClientApiUrl", etherscan_client_api_url) validate_version(version) + validate_master_copy_address_by_version(address_master_copy, version) + validate_proxy_address_by_version(address_proxy, version) tx_master_info = validate_address_and_transactions( "Master copy", address_master_copy, tx_hash_master_copy, rpc_url ) @@ -208,13 +272,13 @@ def validate_issue_inputs() -> None: ) if len(ERRORS) > 0: - errors_comment = "\n".join(ERRORS) + errors_comment = "\n- ".join(ERRORS) add_message_to_env( "Validation has failed with the following errors:" + f"\n- {errors_comment}" + "\n\n Validation failed!❌" ) - return + return None chain_name_comment = chain_name if chain_name else "N/A" tx_master_block_comment = tx_master_info.get("block") if tx_master_info else "N/A" tx_proxy_block_comment = tx_proxy_info.get("block") if tx_proxy_info else "N/A"