Skip to content

Commit

Permalink
Add support of mainnet part of IMA
Browse files Browse the repository at this point in the history
  • Loading branch information
DimaStebaev committed Mar 11, 2024
1 parent 866f449 commit 0dcd1a4
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 24 deletions.
14 changes: 13 additions & 1 deletion python/src/skale_contracts/network.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Module for work with networks"""

from __future__ import annotations
from typing import TYPE_CHECKING
from typing import cast, TYPE_CHECKING
from web3 import Web3
from web3.providers.base import BaseProvider

Expand All @@ -28,9 +28,21 @@ def skale_contracts(self) -> SkaleContracts:
"""Get SkaleContracts object associated with the network"""
return self._skale_contracts

def is_listed(self) -> bool:
"""Return if the network is present in the skale-contract repository"""
return False

def as_listed(self) -> ListedNetwork:
"""Cast to ListedNetwork"""
return cast(ListedNetwork, self)


class ListedNetwork(Network):
"""Network that is listed in the metadata"""
def __init__(self, skale_contracts: SkaleContracts, provider: BaseProvider, path: str):
super().__init__(skale_contracts, provider)
self.path = path

def is_listed(self) -> bool:
"""Return if the network is present in the skale-contract repository"""
return True
22 changes: 9 additions & 13 deletions python/src/skale_contracts/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,16 @@
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING
from attr import dataclass
from eth_utils.address import to_canonical_address
import requests

from .constants import REPOSITORY_URL, NETWORK_TIMEOUT
from .instance import Instance, InstanceData
from .network import ListedNetwork

if TYPE_CHECKING:
from eth_typing import Address
from .network import Network


@dataclass
class ProjectMetadata:
"""Contains project metadata"""
name: str
path: str
from .project_metadata import ProjectMetadata


class Project(ABC):
Expand All @@ -30,8 +22,8 @@ def __init__(self, network: Network, metadata: ProjectMetadata) -> None:
self.network = network
self._metadata = metadata

@abstractmethod
@property
@abstractmethod
def github_repo(self) -> str:
"""URL of github repo with the project"""

Expand All @@ -53,7 +45,10 @@ def get_instance(self, alias_or_address: str) -> Instance:

def download_abi_file(self, version: str) -> str:
"""Download file with ABI"""
response = requests.get(self.get_abi_url(version), timeout=NETWORK_TIMEOUT)
url = self.get_abi_url(version)
response = requests.get(url, timeout=NETWORK_TIMEOUT)
if response.status_code != 200:
raise RuntimeError(f"Can't download abi file from {url}")
return response.text

def get_abi_url(self, version: str) -> str:
Expand All @@ -66,8 +61,9 @@ def get_abi_filename(self, version: str) -> str:

def get_instance_data_url(self, alias: str) -> str:
"""Get URL of a file containing address for provided alias"""
if isinstance(self.network, ListedNetwork):
return f'{REPOSITORY_URL}{self.network.path}/{self._metadata.path}/{alias}.json'
if self.network.is_listed():
return f'{REPOSITORY_URL}{self.network.as_listed().path}/' + \
f'{self._metadata.path}/{alias}.json'
raise ValueError('Network is unknown')

@abstractmethod
Expand Down
10 changes: 6 additions & 4 deletions python/src/skale_contracts/project_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
from typing import TYPE_CHECKING
from attr import dataclass

from .project import ProjectMetadata
from .projects.skale_manager import SkaleManagerProject

from . import projects
from .project_metadata import ProjectMetadata

if TYPE_CHECKING:
from .project import Project
Expand All @@ -17,10 +16,13 @@
class Projects:
"""Contains all known projects"""
skale_manager = ProjectMetadata(name='skale-manager', path='skale-manager')
mainnet_ima = ProjectMetadata(name='mainnet-ima', path='mainnet-ima')


def create_project(network: Network, name: str) -> Project:
"""Create Project object based on it's name"""
if name == Projects.skale_manager.name:
return SkaleManagerProject(network, Projects.skale_manager)
return projects.SkaleManager(network, Projects.skale_manager)
if name == Projects.mainnet_ima.name:
return projects.MainnetIma(network, Projects.mainnet_ima)
raise ValueError(f'Project with name {name} is unknown')
8 changes: 8 additions & 0 deletions python/src/skale_contracts/project_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Tools for project metadata processing"""
from attr import dataclass

@dataclass
class ProjectMetadata:
"""Contains project metadata"""
name: str
path: str
5 changes: 5 additions & 0 deletions python/src/skale_contracts/projects/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Supported projects"""
from .ima import MainnetImaProject as MainnetIma
from .skale_manager import SkaleManagerProject as SkaleManager

__all__ = ["MainnetIma", "SkaleManager"]
44 changes: 40 additions & 4 deletions python/src/skale_contracts/projects/ima.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
from __future__ import annotations
from typing import cast, TYPE_CHECKING

from ..instance import Instance, DEFAULT_GET_VERSION_FUNCTION
from ..project import Project
from skale_contracts.instance import Instance, DEFAULT_GET_VERSION_FUNCTION
from skale_contracts.project import Project

from .skale_manager import CONTRACT_MANAGER_ABI


if TYPE_CHECKING:
Expand Down Expand Up @@ -36,8 +38,42 @@ def github_repo(self) -> str:

class MainnetImaInstance(ImaInstance):
"""Represents IMA instance on mainnet"""

def __init__(self, project: Project, address: Address) -> None:
super().__init__(project, address)
self._contract_manager: Contract | None = None

def get_contract_address(self, name: str) -> Address:
raise NotImplementedError("get_contract_address")
if name == 'MessageProxyForMainnet':
return self.address
if name == 'CommunityPool':
return cast(
Address,
self.get_contract("MessageProxyForMainnet").functions.communityPool().call()
)
if name == 'Linker':
return cast(
Address,
self.get_contract("MessageProxyForMainnet").functions.linker().call()
)
return cast(
Address,
self.contract_manager.functions.getContract(name).call()
)

@property
def contract_manager(self) -> Contract:
"""ContractManager contract of a skale-manager instance associated with the IMA"""
if self._contract_manager is None:
self._contract_manager = self.web3.eth.contract(
address=cast(
Address,
self.get_contract("MessageProxyForMainnet")
.functions.contractManagerOfSkaleManager().call()
),
abi=CONTRACT_MANAGER_ABI
)
return self._contract_manager


class MainnetImaProject(ImaProject):
Expand All @@ -47,4 +83,4 @@ def create_instance(self, address: Address) -> Instance:
return MainnetImaInstance(self, address)

def get_abi_filename(self, version: str) -> str:
return f'ima-{version}-abi.json'
return f'mainnet-ima-{version}-abi.json'
4 changes: 2 additions & 2 deletions python/src/skale_contracts/projects/skale_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from __future__ import annotations
from typing import cast, TYPE_CHECKING

from ..instance import Instance, DEFAULT_GET_VERSION_FUNCTION
from ..project import Project
from skale_contracts.instance import Instance, DEFAULT_GET_VERSION_FUNCTION
from skale_contracts.project import Project


if TYPE_CHECKING:
Expand Down

0 comments on commit 0dcd1a4

Please sign in to comment.