Skip to content

Commit

Permalink
14 oct update part-1. SubDomainRegistrar, PublicResolver added & all …
Browse files Browse the repository at this point in the history
…tests added for them
  • Loading branch information
Aviksaikat committed Oct 14, 2023
1 parent c460357 commit ba847f6
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 7 deletions.
28 changes: 28 additions & 0 deletions src/fds/contracts/Multibox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
Copyright 2023 The FairDataSociety Authors
This file is part of the FairDataSociety library.
The FairDataSociety library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The FairDataSociety library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the FairDataSociety library. If not, see <http:www.gnu.org/licenses/>.
handles Multibox contract
"""

from typing import Tuple, Union

from ape import convert, networks, project
from ape.api.accounts import AccountAPI
from ape.api.transactions import ReceiptAPI
from ape.types import AddressType

from fds.utils.Exceptions import AccountNotSetUp
142 changes: 142 additions & 0 deletions src/fds/contracts/PublicResolver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
"""
Copyright 2023 The FairDataSociety Authors
This file is part of the FairDataSociety library.
The FairDataSociety library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The FairDataSociety library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the FairDataSociety library. If not, see <http:www.gnu.org/licenses/>.
handles PublicResolver contract
"""
from typing import Tuple, Union

from ape import convert, networks, project
from ape.api.accounts import AccountAPI
from ape.api.transactions import ReceiptAPI
from ape.types import AddressType

from fds.utils.Exceptions import AccountNotSetUp


class PublicResolverClass:
def __init__(self, account: AccountAPI, contract_address: Union[AddressType, None] = None):
self.account = account
self.contract_address = contract_address
self.contract = None
self.web3 = networks.provider._web3

if contract_address:
self.contract = project.PublicResolver.at(self.contract_address)

def setAll(
self,
node: int,
address: AddressType,
content: str,
multihash: str,
x: int,
y: int,
name: str,
) -> ReceiptAPI:
"""
* Sets all required params in one attempt
* May only be called by the owner of that node in the ENS registry.
* @param node The node to update.
* @param addr The address to set.
* @param content The content hash to set
* @param multihash The multihash to set
* @param x the X coordinate of the curve point for the public key.
* @param y the Y coordinate of the curve point for the public key.
* @param name The name to set.
"""

"""
If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc".
If this is desired behavior, use f"{x!r}" or "{!r}".format(x).
Otherwise, decode the bytes
"""
self.node = f"0x{node.to_bytes(32, byteorder='big').hex()}"
self.address = address
self.content = content.encode("utf-8")
self.multihash = multihash.encode("utf-8")
self.x = x.to_bytes(32, byteorder="big")
self.y = y.to_bytes(32, byteorder="big")
self.name = name

return self.contract.setAll( # type: ignore
self.node,
self.address,
self.content,
self.multihash,
self.x,
self.y,
self.name,
sender=self.account,
)

def getAll(self, node: int) -> Tuple:
self.node = f"0x{node.to_bytes(32, byteorder='big').hex()}"

return self.contract.getAll(self.node) # type: ignore

def setPublicKey(self, node: int, x: int, y: int) -> ReceiptAPI:
"""
* Sets the SECP256k1 public key associated with an ENS node.
* @param node The ENS node to query
* @param x the X coordinate of the curve point for the public key.
* @param y the Y coordinate of the curve point for the public key.
"""
if not self.account:
raise AccountNotSetUp("Set up user account first")

self.node = f"0x{node.to_bytes(32, byteorder='big').hex()}"
self.x = x.to_bytes(32, byteorder="big")
self.y = y.to_bytes(32, byteorder="big")

return self.contract.setPubkey(self.node, self.x, self.y, sender=self.account) # type: ignore # noqa: 501

def getPublicKey(self, node: int) -> Tuple[int, int]:
"""
* Returns the SECP256k1 public key associated with an ENS node.
* Defined in EIP 619.
* @param node The ENS node to query
* @return x, y the X and Y coordinates of the curve point for the public key.
"""

self.node = f"0x{node.to_bytes(32, byteorder='big').hex()}"

return self.contract.pubkey(self.node) # type: ignore

def setMultiHash(self, node: int, _hash: str) -> ReceiptAPI:
"""
* Sets the multihash associated with an ENS node.
* May only be called by the owner of that node in the ENS registry.
* @param node The node to update.
* @param hash The multihash to set.
"""
if not self.account:
raise AccountNotSetUp("Set up user account first")

self.node = f"0x{node.to_bytes(32, byteorder='big').hex()}"
self.hash = _hash.encode("utf-8")

return self.contract.setMultihash(self.node, self.hash, sender=self.account) # type: ignore

def getMultiHash(self, node: int) -> str:
"""
* Returns the multihash associated with an ENS node.
* @param node The ENS node to query.
* @return The associated multihash.
"""
self.node = f"0x{node.to_bytes(32, byteorder='big').hex()}"

return convert(self.contract.multihash(self.node), str) # type: ignore
60 changes: 60 additions & 0 deletions src/fds/contracts/SubdomainRegistrar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
Copyright 2023 The FairDataSociety Authors
This file is part of the FairDataSociety library.
The FairDataSociety library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The FairDataSociety library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the FairDataSociety library. If not, see <http:www.gnu.org/licenses/>.
handles SubdomainRegistrar contract
"""
from typing import Union

from ape import networks, project
from ape.api.accounts import AccountAPI
from ape.api.transactions import ReceiptAPI
from ape.types import AddressType


class SubdomainRegistrarContractClass:
def __init__(self, account: AccountAPI, contract_address: Union[AddressType, None] = None):
self.account = account
self.contract_address = contract_address
self.contract = None
self.web3 = networks.provider._web3

if contract_address:
self.contract = project.SubdomainRegistrar.at(self.contract_address)

def getRootNode(self) -> str:
return self.contract.rootNode() # type: ignore

def register(self, label: int, owner_address: AddressType) -> ReceiptAPI:
"""
Register a name that's not currently registered
@param label The hash of the label to register.
@param owner The address of the new owner.
"""

self.label = label.to_bytes(32, byteorder="big")
self.owner_address = owner_address
self.label = f"0x{self.label.hex()}" # type: ignore

return self.contract.register(self.label, self.owner_address, sender=self.account) # type: ignore # noqa: 501

def getExpiryTime(self, label: int):
self.label = label.to_bytes(32, byteorder="big")
self.label = f"0x{self.label.hex()}" # type: ignore

expiryTime = self.contract.expiryTimes(self.label) # type: ignore

return expiryTime
Empty file removed src/fds/contracts/multibox.py
Empty file.
Empty file.
Empty file.
20 changes: 14 additions & 6 deletions src/fds/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,23 @@ def fdsContractDeploy(owner):

@pytest.fixture
def ensContract(owner):
contract = project.ENSRegistry.deploy(sender=owner)

return contract
return project.ENSRegistry.deploy(sender=owner)


@pytest.fixture
def ENS(owner, ensContract):
contract = ensContract
return EnsRegistry(owner, ensContract.address)


@pytest.fixture
def subDomainRegistrarContract(owner, ensContract):
node = 1
node = node.to_bytes(32, byteorder="big")
contract = project.SubdomainRegistrar.deploy(ensContract.address, node, sender=owner)

return contract

ENS = EnsRegistry(owner, contract.address)

return ENS
@pytest.fixture
def publicResolverContract(owner, ensContract):
return project.PublicResolver.deploy(ensContract.address, sender=owner)
2 changes: 1 addition & 1 deletion src/fds/tests/unit_tests/test_ensregistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def test_set_n_get_ttl(ENS):
assert ENS.getTTL(0) == 420


def test_fail_setting_ttl(owner, receiver, ensContract):
def test_fail_setting_ttl(owner, ensContract):
contract = ensContract

ENS = EnsRegistry(owner, contract.address)
Expand Down
54 changes: 54 additions & 0 deletions src/fds/tests/unit_tests/test_public_resolver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import pytest
from ape import convert
from ape.exceptions import ContractLogicError

from fds.contracts.PublicResolver import PublicResolverClass


def test_set_all(owner, sender, publicResolverContract, ENS):
assert ENS.owner(0) == owner.address

pubResClass = PublicResolverClass(owner, publicResolverContract.address)

pubResClass.setAll(0, sender.address, "hahaha", "eeehahaha", 16, 17, "jadu")

addr, content, multihash, x, y, name = pubResClass.getAll(0)

assert addr == sender.address
assert content.decode().replace("\x00", "") == "hahaha"
assert multihash.decode().replace("\x00", "") == "eeehahaha"
assert convert(x, int) == 16
assert convert(y, int) == 17
assert name.replace("\x00", "") == "jadu"


def test_set_publickey(owner, publicResolverContract):
pubResClass = PublicResolverClass(owner, publicResolverContract.address)
node = 0
pubResClass.setPublicKey(node, 22, 34)

x, y = pubResClass.getPublicKey(node)

assert convert(x, int) == 22
assert convert(y, int) == 34


# TODO: fixt this test
def test_multihash(owner, publicResolverContract):
pubResClass = PublicResolverClass(owner, publicResolverContract.address)
node = 0
_hash = "fairDataProtocl"
pubResClass.setMultiHash(node, _hash)

returned_hash = pubResClass.getMultiHash(node)

assert returned_hash == _hash


def test_fail_set_publickey(owner, publicResolverContract):
pubResClass = PublicResolverClass(owner, publicResolverContract.address)
node = 1

with pytest.raises(ContractLogicError):
# * trying to access other node
pubResClass.setPublicKey(node, 22, 34)
20 changes: 20 additions & 0 deletions src/fds/tests/unit_tests/test_subdomain_register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import pytest
from ape.exceptions import ContractLogicError

from fds.contracts.SubdomainRegistrar import SubdomainRegistrarContractClass


def test_load_ens_contract(owner, subDomainRegistrarContract):
contract = subDomainRegistrarContract
src = SubdomainRegistrarContractClass(owner, contract.address)
node = 1
node = node.to_bytes(32, byteorder="big")
assert src.getRootNode() == node


def test_register(owner, ensContract):
src = SubdomainRegistrarContractClass(owner, ensContract.address)

# ENS.setOwner(0, owner.address)
with pytest.raises(ContractLogicError):
src.register(0, owner.address)
4 changes: 4 additions & 0 deletions src/fds/utils/Exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ class ContractNotFoundException(Exception):

class InaccessibleGatewayException(Exception):
pass


class AccountNotSetUp(Exception):
pass

0 comments on commit ba847f6

Please sign in to comment.