kopia lustrzana https://github.com/bugout-dev/moonstream
Merge 9a31d145e0
into 135af1765c
commit
07aeb52c51
|
@ -3,9 +3,9 @@ import json
|
|||
import logging
|
||||
import uuid
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
from typing import Any, Dict, List, Optional, Set, Tuple
|
||||
|
||||
from sqlalchemy import func, or_, text
|
||||
from sqlalchemy import func, or_, text, tuple_
|
||||
from sqlalchemy.dialects.postgresql import insert
|
||||
from sqlalchemy.engine import Row
|
||||
from sqlalchemy.exc import IntegrityError, NoResultFound
|
||||
|
@ -71,6 +71,12 @@ class CallRequestAlreadyRegistered(Exception):
|
|||
"""
|
||||
|
||||
|
||||
class CallRequestIdDuplicates(Exception):
|
||||
"""
|
||||
Raised when same call request IDs passed in one request.
|
||||
"""
|
||||
|
||||
|
||||
def parse_registered_contract_response(
|
||||
obj: Tuple[RegisteredContract, Blockchain]
|
||||
) -> data.RegisteredContractResponse:
|
||||
|
@ -431,6 +437,38 @@ def create_request_calls(
|
|||
return len(call_specs)
|
||||
|
||||
|
||||
def get_call_request_from_tuple(
|
||||
db_session: Session,
|
||||
metatx_requester_id: uuid.UUID,
|
||||
requests: Set[Tuple[str, str]],
|
||||
contract_id: Optional[uuid.UUID] = None,
|
||||
contract_address: Optional[str] = None,
|
||||
) -> List[CallRequest]:
|
||||
if contract_id is None and contract_address is None:
|
||||
raise ValueError(
|
||||
"At least one of contract_id or contract_address must be specified"
|
||||
)
|
||||
query = (
|
||||
db_session.query(CallRequest)
|
||||
.join(
|
||||
RegisteredContract,
|
||||
CallRequest.registered_contract_id == RegisteredContract.id,
|
||||
)
|
||||
.filter(RegisteredContract.metatx_requester_id == metatx_requester_id)
|
||||
.filter(tuple_(CallRequest.caller, CallRequest.request_id).in_(requests))
|
||||
)
|
||||
if contract_id is not None:
|
||||
query = query.filter(RegisteredContract.id == contract_id)
|
||||
if contract_address is not None:
|
||||
query = query.filter(
|
||||
RegisteredContract.address == Web3.toChecksumAddress(contract_address)
|
||||
)
|
||||
|
||||
existing_requests = query.all()
|
||||
|
||||
return existing_requests
|
||||
|
||||
|
||||
def get_call_request(
|
||||
db_session: Session,
|
||||
request_id: uuid.UUID,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Any, Dict, List, Optional, Set
|
||||
from typing import Any, Dict, List, Optional, Set, Tuple
|
||||
from uuid import UUID
|
||||
|
||||
from bugout.data import BugoutResource
|
||||
|
@ -329,6 +329,10 @@ class CallRequestResponse(BaseModel):
|
|||
return Web3.toChecksumAddress(v)
|
||||
|
||||
|
||||
class CallRequestsCheck(BaseModel):
|
||||
existing_requests: Set[Tuple[str, str]] = Field(default_factory=set)
|
||||
|
||||
|
||||
class CompleteCallRequestsAPIRequest(BaseModel):
|
||||
tx_hash: str
|
||||
|
||||
|
|
|
@ -5,14 +5,16 @@ Moonstream users can register contracts on Moonstream Engine. This allows them t
|
|||
as part of their chain-adjacent activities (like performing signature-based token distributions on the
|
||||
Dropper contract).
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict, List, Optional
|
||||
from typing import Dict, List, Optional, Set, Tuple
|
||||
from uuid import UUID
|
||||
|
||||
from bugout.data import BugoutUser
|
||||
from fastapi import Body, Depends, FastAPI, Form, Path, Query, Request
|
||||
from sqlalchemy.exc import NoResultFound
|
||||
from sqlalchemy.orm import Session
|
||||
from web3 import Web3
|
||||
|
||||
from .. import contracts_actions, data, db
|
||||
from ..middleware import (
|
||||
|
@ -316,6 +318,57 @@ async def list_requests_route(
|
|||
return [contracts_actions.parse_call_request_response(r) for r in requests]
|
||||
|
||||
|
||||
@app.get(
|
||||
"/requests/check",
|
||||
response_model=data.CallRequestsCheck,
|
||||
)
|
||||
async def check_requests_route(
|
||||
request_data: data.CreateCallRequestsAPIRequest = Body(...),
|
||||
user: BugoutUser = Depends(request_user_auth),
|
||||
db_session: Session = Depends(db.yield_db_session),
|
||||
) -> data.CallRequestsCheck:
|
||||
"""
|
||||
Implemented for pre-check until list of requests to be pushed into database.
|
||||
"""
|
||||
try:
|
||||
incoming_requests: Set[Tuple[str, str]] = set()
|
||||
incoming_request_ids: List[str] = []
|
||||
for r in request_data.specifications:
|
||||
caller_addr = Web3.toChecksumAddress(r.caller)
|
||||
incoming_requests.add((caller_addr, r.request_id))
|
||||
incoming_request_ids.append(r.request_id)
|
||||
|
||||
if len(incoming_requests) != len(incoming_request_ids):
|
||||
raise contracts_actions.CallRequestIdDuplicates(
|
||||
"There are same call_request_id's in one request"
|
||||
)
|
||||
|
||||
existing_requests = contracts_actions.get_call_request_from_tuple(
|
||||
db_session=db_session,
|
||||
metatx_requester_id=user.id,
|
||||
requests=incoming_requests,
|
||||
contract_id=request_data.contract_id,
|
||||
contract_address=request_data.contract_address,
|
||||
)
|
||||
except contracts_actions.CallRequestIdDuplicates:
|
||||
raise EngineHTTPException(
|
||||
status_code=400, detail="There are same call_request_id's in one request"
|
||||
)
|
||||
except Exception as err:
|
||||
logger.error(repr(err))
|
||||
raise EngineHTTPException(status_code=500)
|
||||
|
||||
existing_requests_set: Set[Tuple[str, str]] = set()
|
||||
if len(existing_requests) != 0:
|
||||
existing_requests_set = {
|
||||
(er.caller, str(er.request_id)) for er in existing_requests
|
||||
}
|
||||
|
||||
return data.CallRequestsCheck(
|
||||
existing_requests=existing_requests_set,
|
||||
)
|
||||
|
||||
|
||||
@app.get(
|
||||
"/requests/{request_id}", tags=["requests"], response_model=data.CallRequestResponse
|
||||
)
|
||||
|
@ -348,7 +401,7 @@ async def get_request(
|
|||
|
||||
@app.post("/requests", tags=["requests"], response_model=int)
|
||||
async def create_requests(
|
||||
data: data.CreateCallRequestsAPIRequest = Body(...),
|
||||
request_data: data.CreateCallRequestsAPIRequest = Body(...),
|
||||
user: BugoutUser = Depends(request_user_auth),
|
||||
db_session: Session = Depends(db.yield_db_session),
|
||||
) -> int:
|
||||
|
@ -361,11 +414,11 @@ async def create_requests(
|
|||
num_requests = contracts_actions.create_request_calls(
|
||||
db_session=db_session,
|
||||
metatx_requester_id=user.id,
|
||||
registered_contract_id=data.contract_id,
|
||||
contract_address=data.contract_address,
|
||||
call_specs=data.specifications,
|
||||
ttl_days=data.ttl_days,
|
||||
live_at=data.live_at,
|
||||
registered_contract_id=request_data.contract_id,
|
||||
contract_address=request_data.contract_address,
|
||||
call_specs=request_data.specifications,
|
||||
ttl_days=request_data.ttl_days,
|
||||
live_at=request_data.live_at,
|
||||
)
|
||||
except contracts_actions.InvalidAddressFormat as err:
|
||||
raise EngineHTTPException(
|
||||
|
|
Ładowanie…
Reference in New Issue