Skip to content

Commit

Permalink
Contract register via resource creation
Browse files Browse the repository at this point in the history
  • Loading branch information
kompotkot committed Aug 14, 2024
1 parent 68251d8 commit fba1a1f
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 54 deletions.
83 changes: 67 additions & 16 deletions engineapi/engineapi/contracts_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from datetime import datetime, timedelta
from typing import Any, Dict, List, Optional, Set, Tuple

from bugout.data import BugoutResourceHolder
from sqlalchemy import func, or_, text, tuple_
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.engine import Row
Expand All @@ -20,7 +21,11 @@
MetatxRequester,
RegisteredContract,
)
from .settings import bugout_client
from .settings import (
MOONSTREAM_ADMIN_ACCESS_TOKEN,
MOONSTREAM_APPLICATION_ID,
bugout_client,
)

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -164,30 +169,72 @@ def validate_method_and_params(
return call_request_type


def create_resource_for_registered_contract(user_id: uuid.UUID) -> uuid.UUID:
resource_data = {"type": "metatx_requester"}
creator_permissions = ["create", "read", "update", "delete"]

resource = bugout_client.create_resource(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
application_id=MOONSTREAM_APPLICATION_ID,
resource_data=resource_data,
)
logger.info(f"Created resource with ID: {str(resource.id)}")

resource_holder = bugout_client.add_resource_holder_permissions(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
resource_id=resource.id,
holder_permissions=BugoutResourceHolder(
holder_id=str(user_id),
holder_type="user",
permissions=["create", "read", "update", "delete"],
),
)
logger.info(
f"Granted {creator_permissions} permissions for resource {str(resource.id)} to metatx requester with ID: {user_id}"
)

return resource.id


def delete_resource_for_registered_contract(resource_id: uuid.UUID) -> None:
resource = bugout_client.delete_resource(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
resource_id=resource_id,
)
logger.info(f"Delete resource with ID: {resource.id} for registered contract")


def register_contract(
db_session: Session,
blockchain_name: str,
address: str,
metatx_requester_id: uuid.UUID,
user_id: uuid.UUID,
title: Optional[str],
description: Optional[str],
image_uri: Optional[str],
) -> Tuple[RegisteredContract, Blockchain]:
"""
Register a contract against the Engine instance
"""
blockchain = (
db_session.query(Blockchain)
.filter(Blockchain.name == blockchain_name)
.one_or_none()
)

if blockchain is None:
raise UnsupportedBlockchain("Unsupported blockchain specified")

try:
blockchain = (
db_session.query(Blockchain)
.filter(Blockchain.name == blockchain_name)
.one_or_none()
resource_id = create_resource_for_registered_contract(user_id=user_id)
except Exception as err:
logger.error(repr(err))
raise Exception(
f"Unhandled exception during resource creation for user with ID: {str(user_id)}"
)
if blockchain is None:
raise UnsupportedBlockchain("Unsupported blockchain specified")

metatx_requester_stmt = insert(MetatxRequester.__table__).values(
id=metatx_requester_id
)
try:
metatx_requester_stmt = insert(MetatxRequester.__table__).values(id=resource_id)
metatx_requester_stmt_do_nothing_stmt = (
metatx_requester_stmt.on_conflict_do_nothing()
)
Expand All @@ -196,7 +243,7 @@ def register_contract(
contract = RegisteredContract(
blockchain_id=blockchain.id,
address=Web3.toChecksumAddress(address),
metatx_requester_id=metatx_requester_id,
metatx_requester_id=resource_id,
title=title,
description=description,
image_uri=image_uri,
Expand All @@ -205,11 +252,15 @@ def register_contract(
db_session.commit()
except IntegrityError as err:
db_session.rollback()
delete_resource_for_registered_contract(resource_id)
raise ContractAlreadyRegistered()
except Exception as err:
db_session.rollback()
delete_resource_for_registered_contract(resource_id)
logger.error(repr(err))
raise
raise Exception(
f"Unhandled exception during creating new registered contract for user with ID: {str(user_id)}"
)

return (contract, blockchain)

Expand Down Expand Up @@ -260,7 +311,7 @@ def update_registered_contract(

def get_registered_contract(
db_session: Session,
metatx_requester_id: uuid.UUID,
metatx_requester_ids: List[uuid.UUID],
contract_id: uuid.UUID,
) -> Tuple[RegisteredContract, Blockchain]:
"""
Expand All @@ -269,7 +320,7 @@ def get_registered_contract(
contract_with_blockchain = (
db_session.query(RegisteredContract, Blockchain)
.join(Blockchain, Blockchain.id == RegisteredContract.blockchain_id)
.filter(RegisteredContract.metatx_requester_id == metatx_requester_id)
.filter(RegisteredContract.metatx_requester_id.in_(metatx_requester_ids))
.filter(RegisteredContract.id == contract_id)
.one()
)
Expand Down Expand Up @@ -697,7 +748,7 @@ def handle_register(args: argparse.Namespace) -> None:
blockchain=args.blockchain,
address=args.address,
contract_type=args.contract_type,
moonstream_user_id=args.user_id,
user_id=args.user_id,
title=args.title,
description=args.description,
image_uri=args.image_uri,
Expand Down
25 changes: 16 additions & 9 deletions engineapi/engineapi/routes/metatx.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,21 @@ async def get_registered_contract_route(
"""
Get the contract by ID.
"""
user = user_authorization
_, token = user_authorization

try:
metatx_requester_ids = contracts_actions.fetch_metatx_requester_ids(token=token)

contract_with_blockchain = contracts_actions.get_registered_contract(
db_session=db_session,
metatx_requester_id=user.id,
metatx_requester_ids=metatx_requester_ids,
contract_id=contract_id,
)
except contracts_actions.MetatxRequestersNotFound:
raise EngineHTTPException(
status_code=404,
detail="Metatx requester IDs not found",
)
except NoResultFound:
raise EngineHTTPException(
status_code=404,
Expand All @@ -172,12 +179,12 @@ async def register_contract_route(
"""
Allows users to register contracts.
"""
user = user_authorization
user, _ = user_authorization

try:
contract_with_blockchain = contracts_actions.register_contract(
db_session=db_session,
metatx_requester_id=user.id,
user_id=user.id,
blockchain_name=contract.blockchain,
address=contract.address,
title=contract.title,
Expand Down Expand Up @@ -213,7 +220,7 @@ async def update_contract_route(
user_authorization: Tuple[BugoutUser, UUID] = Depends(request_user_auth),
db_session: Session = Depends(db.yield_db_session),
) -> data.RegisteredContractResponse:
user = user_authorization
user, _ = user_authorization

try:
contract_with_blockchain = contracts_actions.update_registered_contract(
Expand Down Expand Up @@ -252,7 +259,7 @@ async def delete_contract_route(
"""
Allows users to delete contracts that they have registered.
"""
user = user_authorization
user, _ = user_authorization

try:
deleted_contract_with_blockchain = contracts_actions.delete_registered_contract(
Expand Down Expand Up @@ -347,7 +354,7 @@ async def check_requests_route(
"""
Implemented for pre-check until list of requests to be pushed into database.
"""
user = user_authorization
user, _ = user_authorization

try:
incoming_requests: Set[Tuple[str, str]] = set()
Expand Down Expand Up @@ -429,7 +436,7 @@ async def create_requests(
At least one of `contract_id` or `contract_address` must be provided in the request body.
"""
user = user_authorization
user, _ = user_authorization

try:
num_requests = contracts_actions.create_request_calls(
Expand Down Expand Up @@ -482,7 +489,7 @@ async def delete_requests(
"""
Allows users to delete requests.
"""
user = user_authorization
user, _ = user_authorization

try:
deleted_requests = contracts_actions.delete_requests(
Expand Down
36 changes: 7 additions & 29 deletions engineapi/engineapi/scripts/metatx_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from sqlalchemy.sql import delete, distinct, func, insert, update

from .. import db, models
from ..contracts_actions import create_resource_for_registered_contract
from ..settings import (
MOONSTREAM_ADMIN_ACCESS_TOKEN,
MOONSTREAM_APPLICATION_ID,
Expand All @@ -22,8 +23,6 @@ def generate_handler(args: argparse.Namespace):
3. Grant permissions for resource to metatx requester
4. Replace metatx requester table with uuid of resource
"""
resource_data = {"type": "metatx_requester"}

with db.yield_db_session_ctx() as db_session:
query = (
db_session.query(
Expand Down Expand Up @@ -59,54 +58,33 @@ def generate_handler(args: argparse.Namespace):
f"Processing metatx_requester_id: {mr_id} with registered_contracts_cnt: {registered_contracts_cnt} and call_requests_cnt: {call_requests_cnt}"
)

# Create Brood resource
try:
resource = bugout_client.create_resource(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
application_id=MOONSTREAM_APPLICATION_ID,
resource_data=resource_data,
)
print(f"Created resource with ID: {resource.id}")
except Exception as e:
print(str(e))
continue

# Grant access for resource to metatx requester
# Create Brood resource and grant permissions to user
try:
resource_holder = bugout_client.add_resource_holder_permissions(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
resource_id=resource.id,
holder_permissions=BugoutResourceHolder(
holder_id=str(mr_id),
holder_type="user",
permissions=["create", "read", "update", "delete"],
),
)
print("Granted permissions for resource to metatx requester")
resource_id = create_resource_for_registered_contract(user_id=mr_id)
except Exception as e:
print(str(e))
continue

try:
# Create new metatx_requester_id equal to resource ID
metatx_requester_stmt = insert(models.MetatxRequester).values(
id=str(resource.id)
id=str(resource_id)
)
db_session.execute(metatx_requester_stmt)

# Update RegisteredContract table
update_registered_contract = (
update(models.RegisteredContract)
.where(models.RegisteredContract.metatx_requester_id == str(mr_id))
.values(metatx_requester_id=str(resource.id))
.values(metatx_requester_id=str(resource_id))
)
db_session.execute(update_registered_contract)

# Update CallRequest table
update_call_request = (
update(models.CallRequest)
.where(models.CallRequest.metatx_requester_id == str(mr_id))
.values(metatx_requester_id=str(resource.id))
.values(metatx_requester_id=str(resource_id))
)
db_session.execute(update_call_request)

Expand All @@ -118,7 +96,7 @@ def generate_handler(args: argparse.Namespace):

db_session.commit()
print(
f"Updated all metatx_requester_id from {str(mr_id)} to {str(resource.id)} successfully in each table"
f"Updated all metatx_requester_id from {str(mr_id)} to {str(resource_id)} successfully in each table"
)

except Exception as e:
Expand Down

0 comments on commit fba1a1f

Please sign in to comment.