kopia lustrzana https://github.com/bugout-dev/moonstream
Request type PK name and default set to dropper if not specified
rodzic
1bd2f3706b
commit
ba78712cc5
|
@ -50,26 +50,19 @@ def upgrade():
|
|||
|
||||
# Types
|
||||
op.create_table('call_request_types',
|
||||
sa.Column('id', sa.UUID(), nullable=False),
|
||||
sa.Column('request_type', sa.VARCHAR(length=128), nullable=False),
|
||||
sa.Column('name', sa.VARCHAR(length=128), nullable=False),
|
||||
sa.Column('description', sa.String(), nullable=True),
|
||||
sa.Column('required_params', postgresql.ARRAY(sa.String()), nullable=True),
|
||||
sa.Column('method', sa.String(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id', name=op.f('pk_call_request_types')),
|
||||
sa.UniqueConstraint('id', name=op.f('uq_call_request_types_id'))
|
||||
sa.PrimaryKeyConstraint('name', name=op.f('pk_call_request_types')),
|
||||
sa.UniqueConstraint('name', name=op.f('uq_call_request_types_name'))
|
||||
)
|
||||
|
||||
op.create_index(op.f('ix_call_request_types_request_type'), 'call_request_types', ['request_type'], unique=True)
|
||||
|
||||
op.add_column('call_requests', sa.Column('call_request_type_id', sa.UUID(), nullable=True))
|
||||
op.create_foreign_key(op.f('fk_call_requests_call_request_type_id_call_request_types'), 'call_requests', 'call_request_types', ['call_request_type_id'], ['id'], ondelete='CASCADE')
|
||||
op.add_column('call_requests', sa.Column('call_request_type_name', sa.VARCHAR(length=128), nullable=True))
|
||||
op.create_foreign_key(op.f('fk_call_requests_call_request_type_name_call_request_types'), 'call_requests', 'call_request_types', ['call_request_type_name'], ['name'], ondelete='CASCADE')
|
||||
|
||||
# Manual - Start
|
||||
op.execute(f"INSERT INTO call_request_types (id, request_type, description, required_params, method) VALUES ('{str(uuid.uuid4())}', 'raw', 'A generic smart contract. You can ask users to submit arbitrary calldata to this contract.',ARRAY ['calldata'],''),('{str(uuid.uuid4())}', 'dropper-v0.2.0', 'A Dropper v0.2.0 contract. You can authorize users to submit claims against this contract.',ARRAY ['dropId','requestID','blockDeadline','amount','signer','signature'],'claim');")
|
||||
op.execute("UPDATE call_requests SET call_request_type_id = (SELECT call_request_types.id FROM call_request_types INNER JOIN registered_contracts ON call_requests.registered_contract_id = registered_contracts.id WHERE call_request_types.request_type = registered_contracts.contract_type);")
|
||||
op.alter_column("call_requests", "call_request_type_id", nullable=False)
|
||||
op.alter_column("call_request_types", "required_params", nullable=False)
|
||||
op.alter_column("call_request_types", "method", nullable=False)
|
||||
op.execute(f"INSERT INTO call_request_types (name, description) VALUES ('raw','A generic smart contract. You can ask users to submit arbitrary calldata to this contract.'),('dropper-v0.2.0','A Dropper v0.2.0 contract. You can authorize users to submit claims against this contract.');")
|
||||
op.execute("UPDATE call_requests SET call_request_type_name = (SELECT call_request_types.name FROM call_request_types INNER JOIN registered_contracts ON call_requests.registered_contract_id = registered_contracts.id WHERE call_request_types.name = registered_contracts.contract_type);")
|
||||
op.alter_column("call_requests", "call_request_type_name", nullable=False)
|
||||
# Manual - End
|
||||
|
||||
op.drop_index('ix_registered_contracts_contract_type', table_name='registered_contracts')
|
||||
|
@ -105,10 +98,10 @@ def upgrade():
|
|||
# Other
|
||||
op.create_unique_constraint(op.f('uq_registered_contracts_blockchain_id'), 'registered_contracts', ['blockchain_id', 'metatx_requester_id', 'address'])
|
||||
|
||||
op.create_unique_constraint(op.f('uq_call_requests_id'), 'call_requests', ['id'])
|
||||
op.create_unique_constraint(op.f('uq_registered_contracts_id'), 'registered_contracts', ['id'])
|
||||
op.create_unique_constraint(op.f('uq_leaderboard_scores_id'), 'leaderboard_scores', ['id'])
|
||||
op.create_unique_constraint(op.f('uq_leaderboards_id'), 'leaderboards', ['id'])
|
||||
# op.create_unique_constraint(op.f('uq_call_requests_id'), 'call_requests', ['id'])
|
||||
# op.create_unique_constraint(op.f('uq_registered_contracts_id'), 'registered_contracts', ['id'])
|
||||
# op.create_unique_constraint(op.f('uq_leaderboard_scores_id'), 'leaderboard_scores', ['id'])
|
||||
# op.create_unique_constraint(op.f('uq_leaderboards_id'), 'leaderboards', ['id'])
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
|
|
|
@ -82,14 +82,14 @@ def parse_registered_contract_response(
|
|||
|
||||
|
||||
def parse_call_request_response(
|
||||
obj: Tuple[CallRequest, RegisteredContract, CallRequestType, CallRequestType]
|
||||
obj: Tuple[CallRequest, RegisteredContract]
|
||||
) -> data.CallRequestResponse:
|
||||
return data.CallRequestResponse(
|
||||
id=obj[0].id,
|
||||
contract_id=obj[0].registered_contract_id,
|
||||
contract_address=obj[1].address,
|
||||
metatx_requester_id=obj[0].metatx_requester_id,
|
||||
call_request_type=obj[2].request_type,
|
||||
call_request_type=obj[0].call_request_type_name,
|
||||
caller=obj[0].caller,
|
||||
method=obj[0].method,
|
||||
parameters=obj[0].parameters,
|
||||
|
@ -100,38 +100,48 @@ def parse_call_request_response(
|
|||
|
||||
|
||||
def validate_method_and_params(
|
||||
call_request_type: str,
|
||||
method: str,
|
||||
parameters: Dict[str, Any],
|
||||
request_types: List[CallRequestType],
|
||||
) -> CallRequestType:
|
||||
method: str, parameters: Dict[str, Any], call_request_type: Optional[str] = None
|
||||
) -> str:
|
||||
"""
|
||||
Validate the given method and parameters for the specified contract_type.
|
||||
"""
|
||||
for rt in request_types:
|
||||
if rt.request_type == call_request_type:
|
||||
if method != rt.method:
|
||||
raise CallRequestMethodValueError(
|
||||
f"Method must be {rt.method} for {rt.request_type} request type"
|
||||
)
|
||||
if call_request_type is None or call_request_type == "dropper-v0.2.0":
|
||||
call_request_type = "dropper-v0.2.0"
|
||||
if method != "claim":
|
||||
raise CallRequestMethodValueError(
|
||||
"Method must be 'claim' for dropper contract type"
|
||||
)
|
||||
required_params = {
|
||||
"dropId",
|
||||
"requestID",
|
||||
"blockDeadline",
|
||||
"amount",
|
||||
"signer",
|
||||
"signature",
|
||||
}
|
||||
if set(parameters.keys()) != required_params:
|
||||
raise CallRequestRequiredParamsValueError(
|
||||
f"Parameters must have {required_params} keys for dropper contract type"
|
||||
)
|
||||
try:
|
||||
Web3.toChecksumAddress(parameters["signer"])
|
||||
except:
|
||||
raise InvalidAddressFormat("Parameter signer must be a valid address")
|
||||
|
||||
required_params_set = set(rt.required_params)
|
||||
if set(parameters.keys()) != required_params_set:
|
||||
raise CallRequestRequiredParamsValueError(
|
||||
f"Parameters must have only {rt.required_params} key for {rt.request_type} request type"
|
||||
)
|
||||
elif call_request_type == "raw":
|
||||
if method != "":
|
||||
raise CallRequestMethodValueError(
|
||||
"Method must be empty string for raw contract type"
|
||||
)
|
||||
if set(parameters.keys()) != {"calldata"}:
|
||||
raise CallRequestRequiredParamsValueError(
|
||||
"Parameters must have only 'calldata' key for raw contract type"
|
||||
)
|
||||
|
||||
if "signer" in parameters:
|
||||
try:
|
||||
Web3.toChecksumAddress(parameters["signer"])
|
||||
except:
|
||||
raise InvalidAddressFormat(
|
||||
"Parameter signer must be a valid address"
|
||||
)
|
||||
else:
|
||||
raise UnsupportedCallRequestType(f"Unknown contract type {call_request_type}")
|
||||
|
||||
return rt
|
||||
|
||||
raise UnsupportedCallRequestType(f"Unknown request type {call_request_type}")
|
||||
return call_request_type
|
||||
|
||||
|
||||
def register_contract(
|
||||
|
@ -353,8 +363,6 @@ def request_calls(
|
|||
except NoResultFound:
|
||||
raise ValueError("Invalid registered_contract_id or metatx_requester_id")
|
||||
|
||||
request_types = db_session.query(CallRequestType).all()
|
||||
|
||||
# Normalize the caller argument using Web3.toChecksumAddress
|
||||
for specification in call_specs:
|
||||
normalized_caller = Web3.toChecksumAddress(specification.caller)
|
||||
|
@ -362,10 +370,9 @@ def request_calls(
|
|||
# Validate the method and parameters for the contract_type
|
||||
try:
|
||||
call_request_type = validate_method_and_params(
|
||||
specification.call_request_type,
|
||||
specification.method,
|
||||
specification.parameters,
|
||||
request_types,
|
||||
method=specification.method,
|
||||
parameters=specification.parameters,
|
||||
call_request_type=specification.call_request_type,
|
||||
)
|
||||
except UnsupportedCallRequestType as err:
|
||||
raise UnsupportedCallRequestType(err)
|
||||
|
@ -379,6 +386,7 @@ def request_calls(
|
|||
logger.error(
|
||||
f"Unhandled error occurred during methods and parameters validation, err: {err}"
|
||||
)
|
||||
raise Exception()
|
||||
|
||||
expires_at = None
|
||||
if ttl_days is not None:
|
||||
|
@ -386,7 +394,7 @@ def request_calls(
|
|||
|
||||
request = CallRequest(
|
||||
registered_contract_id=registered_contract.id,
|
||||
call_request_type_id=call_request_type.id,
|
||||
call_request_type_name=call_request_type,
|
||||
metatx_requester_id=metatx_requester_id,
|
||||
caller=normalized_caller,
|
||||
method=specification.method,
|
||||
|
@ -408,20 +416,16 @@ def request_calls(
|
|||
def get_call_requests(
|
||||
db_session: Session,
|
||||
request_id: uuid.UUID,
|
||||
) -> Tuple[CallRequest, RegisteredContract, CallRequestType, CallRequestType]:
|
||||
) -> Tuple[CallRequest, RegisteredContract]:
|
||||
"""
|
||||
Get call request by ID.
|
||||
"""
|
||||
results = (
|
||||
db_session.query(CallRequest, RegisteredContract, CallRequestType)
|
||||
db_session.query(CallRequest, RegisteredContract)
|
||||
.join(
|
||||
RegisteredContract,
|
||||
CallRequest.registered_contract_id == RegisteredContract.id,
|
||||
)
|
||||
.join(
|
||||
CallRequestType,
|
||||
CallRequest.call_request_type_id == CallRequestType.id,
|
||||
)
|
||||
.filter(CallRequest.id == request_id)
|
||||
.all()
|
||||
)
|
||||
|
@ -432,9 +436,9 @@ def get_call_requests(
|
|||
f"Incorrect number of results found for request_id {request_id}"
|
||||
)
|
||||
|
||||
call_request, registered_contract, call_request_type = results[0]
|
||||
call_request, registered_contract = results[0]
|
||||
|
||||
return (call_request, registered_contract, call_request_type)
|
||||
return (call_request, registered_contract)
|
||||
|
||||
|
||||
def list_blockchains(
|
||||
|
@ -473,15 +477,11 @@ def list_call_requests(
|
|||
|
||||
# If show_expired is False, filter out expired requests using current time on database server
|
||||
query = (
|
||||
db_session.query(CallRequest, RegisteredContract, CallRequestType)
|
||||
db_session.query(CallRequest, RegisteredContract)
|
||||
.join(
|
||||
RegisteredContract,
|
||||
CallRequest.registered_contract_id == RegisteredContract.id,
|
||||
)
|
||||
.join(
|
||||
CallRequestType,
|
||||
CallRequest.call_request_type_id == CallRequestType.id,
|
||||
)
|
||||
.filter(CallRequest.caller == Web3.toChecksumAddress(caller))
|
||||
)
|
||||
|
||||
|
|
|
@ -204,8 +204,7 @@ class DropUpdatedResponse(BaseModel):
|
|||
|
||||
|
||||
class CallRequestTypeResponse(BaseModel):
|
||||
id: UUID
|
||||
request_type: str
|
||||
name: str
|
||||
description: str
|
||||
|
||||
class Config:
|
||||
|
@ -271,7 +270,7 @@ class RegisteredContractResponse(BaseModel):
|
|||
class CallSpecification(BaseModel):
|
||||
caller: str
|
||||
method: str
|
||||
call_request_type: str
|
||||
call_request_type: Optional[str] = None
|
||||
parameters: Dict[str, Any]
|
||||
|
||||
@validator("caller")
|
||||
|
|
|
@ -165,22 +165,12 @@ class CallRequestType(Base): # type: ignore
|
|||
|
||||
__tablename__ = "call_request_types"
|
||||
|
||||
id = Column(
|
||||
UUID(as_uuid=True),
|
||||
name = Column(
|
||||
VARCHAR(128),
|
||||
primary_key=True,
|
||||
default=uuid.uuid4,
|
||||
unique=True,
|
||||
)
|
||||
request_type = Column(VARCHAR(128), nullable=False, unique=True, index=True)
|
||||
description = Column(String, nullable=True)
|
||||
required_params = Column(ARRAY(String), nullable=False)
|
||||
method = Column(String, nullable=False)
|
||||
|
||||
call_requests = relationship(
|
||||
"CallRequest",
|
||||
back_populates="call_request_type",
|
||||
cascade="all, delete, delete-orphan",
|
||||
)
|
||||
|
||||
|
||||
class MetatxRequester(Base): # type: ignore
|
||||
|
@ -301,9 +291,9 @@ class CallRequest(Base):
|
|||
ForeignKey("registered_contracts.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
)
|
||||
call_request_type_id = Column(
|
||||
UUID(as_uuid=True),
|
||||
ForeignKey("call_request_types.id", ondelete="CASCADE"),
|
||||
call_request_type_name = Column(
|
||||
VARCHAR(128),
|
||||
ForeignKey("call_request_types.name", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
)
|
||||
metatx_requester_id = Column(
|
||||
|
@ -332,7 +322,6 @@ class CallRequest(Base):
|
|||
registered_contract = relationship(
|
||||
"RegisteredContract", back_populates="call_requests"
|
||||
)
|
||||
call_request_type = relationship("CallRequestType", back_populates="call_requests")
|
||||
metatx_requester = relationship("MetatxRequester", back_populates="call_requests")
|
||||
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue