Terminus webapp server side spec
Terminus whitelist server side should allow us to
- Save up blockchain state space by indexing additional state information trough our nodes
- Allow our customers to enchase blockchain state with their additional information
Proposed specification:
data classes:
class TerminusContracts(BaseModel):
resource_id: uuid
contract_address: str
pools: List[uuid] #I suspect this is how foreign key should work, but how does it scales if this list is veeeery long?
class TerminusContractsListResponse(BaseModel):
contracts: List[TerminusContracts] = Field(default_factory=list)
class TerminusPool(BaseModel):
resource_id: uuid
identities: List[uuid] #To paginate probably must migrate in to new /TerminusPoolIdentities/ paginated resource?
class TerminusIdentity(BaseModel):
resource_id: uuid
address: str
endpoints:
GET /terminus/${DiamondAddress} -> (TerminusContract)
GET /terminus/${DiamondAddress}/pools/${poolId} -> (TerminusPool)
GET /terminus/${DiamondAddress}/pools/${poolId}/refresh -> (TerminusPool)
GET /terminus/${DiamondAddress}/pools/${poolId}/${address} -> (TerminusIdentity)
API logic:
GET /terminus/${DiamondAddress} -> (TerminusContract):
terminus_contract_resource_id: BugoutResource = bc.list_resources(
params = { "contract_address": DiamondAddress }
)[0]
terminus_resource = bc.get_resource( resource_id = terminus_contract_resource_id)
1. Update resource from web3 provider
2. Return resource
Case if terminus_contract not found:
Check web3 -> if contract exists and payment service conditions are met - create resource and set up crawler
GET /terminus/${DiamondAddress}/pools/${poolId} -> (TerminusPool):
terminus_pool: BugoutResource = bc.get_resource(
resource_id=terminus_contract[poolId],
)
1. Update resource from web3 provider
2. Return resource
Case if resource not found:
If payment service conditions are met - create resource and set up crawler.
For each address found in crawler:
add TerminusIdentity.
GET /terminus/${DiamondAddress}/pools/${poolId}/${address} -> (TerminusIdentity)
terminus_pool_resource: BugoutResource = bc.get_resource(
resource_id=terminus_pool.identities[],
)
if address in terminus_pool_resource.identities
terminus_identity_resource: BugoutResource = bc.get_resource(
resource_id=address,
)
terminus_identity_record_resource: BugoutResource = bc.get_pool_resource(
resource_id=web3.sha(DiamondAddress + poolId + address),
)
@peersky: Wanted to put in writing what we discussed verbally in earlier meeting.
ID fields
Better for ID fields to have no semantic connection with the data they describe. If we used the hashing scheme that you were initially considering, for example, it could cause problems if we migrated from a contract at one address to another. This is just one reason to not put semantic information in ID.
There are situations in which we might want to put semantic information in primary key, but at this point it would bring more headaches than we need.
Simple data model
Better to make a simple, composable data model for now and we can add additional functionality (like KYC) later. Invariably, if we put too much stuff in the data model compared to the functionality we want to offer on day 1, most of it will become obsolete as soon as we release. Even worse, it might become an obstacle to rapid development of the data model when we do want to make the correct changes.
I suggest we create the following types of resources:
Customer
Contains the following information
-
id- primary key we use to refer to customer in DB -
name- name of customer -
notes- human-readable/writeable notes about customer
This data should only be visible to Terminus admins (anyone who has appropriate token on the Moonstream Terminus contract).
Contract
Contains the following information:
-
id- primary key we use to refer to contract in DB -
blockchain- chain which Terminus contract is deployed -
address- address of the contract on that blockchain -
customer_id- foreign key toCustomer.id -
controller- address of Terminus controller -
name- human friendly name for contract -
notes- human friendly notes about contract
customer_id only visible to admins
name, notes only visible to admins and Terminus controller
Pool
Contains the following information:
-
id- primary key -
contract_id- foreign key toContract.id -
pool_number- ID of pool on Terminus contract (uint256) -
capacity- capacity of pool -
is_transferable- true/false depending on whether pool is transferable -
is_burnable- true/false depending on whether pool is burnable -
pool_controller- address of pool controller -
name- human friendly name for pool -
notes- notes about pool
name, notes only visible to admins and Terminus controller
PoolAuthorization
Contains the following information:
-
id- primary key -
pool_id- foreign key intoPool.id -
address- authorized address for pool
PoolOwner
Contains the following information:
-
id- primary key -
pool_id- foreign key intoPool.id -
address- address of token owner -
num_tokens- number of tokens they own
AddressAnnotation
Contains the following information:
-
address -
annotator- address of account that created annotation -
name- name for address -
notes- notes for address
Each resource is only visible to its annotator.
Better for ID fields to have no semantic connection with the data they describe. If we used the hashing scheme that you were initially considering, for example, it could cause problems if we migrated from a contract at one address to another. This is just one reason to not put semantic information in ID.
@zomglings
I like idea with Contract objects. I think we should treat Contract as blockchain specific object, not a Diamond/Terminus specific.
Assuming Contract is blockchain property - such hashing scheme would just represent blockchain state more precise: Contract.address is immutable property in it's blockchain nature.
This semantic connection would allow to avoid potential bugs that might occur if there occurs mismatch of env in frontend and address stored in Contract.address (failed migration, did not update field correctly, wrong branch etc).
I have feeling that the more we work with blockchain, the more it will make sense for us to use such scheme.
My concern is here that Im not aware how this can impact performance of db, I want to run benchmark after implementation to compare db access speed for approach when we hash on frontend and access by hash and selected for now approach when we do
- ListResources matching criteria
- Access resource[0] of ^^^