The Morse Protocol
The Morse protocol has been live on MainNet since July 2020, but the final update was pushed in February 2024. There will be no further development as we now focus on the launch of Shannon.
How Morse Works
POKT Network comprises 3 components: Applications, Nodes and the Network Layer.
An Application submits Relays, or API requests, meant to be routed to any public database node.
Nodes service these Relays by submitting them to the public databases they are meant for, and sending the response (if any) back to the Application.
The Network Layer comprises all the rules, protocols and finality storage that serve as the backbone of the interactions between Applications and Nodes, including (but not limited to), configuration, record tracking, governance and economic policy. The mechanism the Network uses to regulate the interactions between Applications and Nodes is Sessions.
Sessions are a data structure that is generated following the established Session Generation Algorithm, which uses data from the finality storage layer of the network to pseudorandomly group one Application with a set of Nodes that will service it for a limited time frame. There are two key components:
Overview
POKT Network’s Servicing layer is comprised of 2 main actors: Applications and Servicers.
An Application submits a Relay Request, or an API requests to be routed to any Relay Chain. A Servicer ‘services’ the Application, by routing the Relay Request to the Relay Chain and forwarding the response to the Application.
This interaction between an Application and a Servicer is the fundamental utility of POKT Network.
Basic Lifecycle
To register for decentralized infrastructure, an Application must stake the native cryptocurrency POKT in the network.
The amount of the sanctioned throughput (per request) is determined by the amount the Application stakes in the network.
To register to provide decentralized infrastructure, a Servicer must stake the native cryptocurrency POKT in the network.
After the subsequent staking, an Application is paired with Servicer(s), during which time the servicing interaction takes place.
For providing the decentralized infrastructure, Servicer receives an amount of the native cryptocurrency POKT proportional to the amount of throughput (in requests) served.
Once an Application or Servicer unstakes, they are unregistered from POKT Network and the stake is returned to their account.
Sessions
Distribution
The Servicer(s) that are paired to service an Application in a Session are equally distributed among all of the Servicers in the network.
Theoretically, this means that every Servicer serves the same amount as their peers and every Application theoretically will be evenly serviced by each Servicer over time.
Generation
The generation of a Session is key to the equal distribution property.
Equally distributed sessions are generated with pseudorandom seed data:
BlockHash: Hash of the last Session Block
AppPubKey: The Application’s public key
RelayChain: The identifier of the Relay Chain
The result of using this seed data is unique sessions for every Relay Chain of Application at any given Session period.
The Servicers that will serve each Application at any given time are extrapolated using this data, meaning any actor with the following blockchain data is able to generate the proper serving Servicers.
A single Dispatch API call to any full node on POKT Network will provide an Application client with the ServiceURL of their Session period Servicers.
Tumbling
Tumbling is the act of regenerating a Session with new seed data.
Sessions are tumbled periodically, every predetermined (by governance) quantity of blocks.
The tumbling mechanism allows for much greater Application security, as the same Validator(s) will service the Application only for a certain amount of time.
Throughput
The max Application throughput (in number of requests) is proportional to the amount staked.
The maximum a Servicer in a Session can service for a certain Application is determined using the following formula:
max_app_relays = base_throughput / (# of Servicers in Session * # of relay_chains staked for)
Relays
Payload
The request payload is the body of the RPC request
Data: The actual request body to be forwarded to the Relay Chain
e.g.
{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}
Method: The HTTP CRUD method
e.g.
POST
Path: Path variable for REST support
e.g:
"/v1/query/block"
Headers: HTTP Headers
e.g.
Content-Type: application/json
Metadata
The Relay Metadata is Protocol-level descriptive information that is needed for servicing.
BlockHeight: POKT Network block height when the request was made
The metadata mechanism allows for a configurable client synchronization module, enabling the Servicer to reject out-of-sync clients.
Since the Metadata is grouped into the request hash, this mechanism protects against Client level synchronization attacks where the Client is able to challenge single Servicers by requesting chain data at a different time than the majority.
Proof of Relay (Evidence)
A Proof of Relay is the portion of a Relay Request that is used for verification of the atomic work completed.
For each Application of each Session, a Servicer collects Relay Evidence in the form of a Proof of Relay. The amount of Relay Evidence is completely proportional to the amount of Relays serviced, meaning for each Relay successfully completed, the Servicer stores one piece of Relay Evidence.
Structure of the Proof of Relay
RequestHash: The SHA3-256 hash of the request payload
Connects the specific payload with the proof
Needed for the Application Challenge Mechanism
Entropy: A unique nonce (random number) that ensures uniqueness
Unique Relays are a requirement of Pocket Network for Claim/Proof Submission
Collisions are rejected by the Servicers
SessionBlockHeight: The block height of the session when the Relay was serviced
Needed to verify the participants of a Session
ServicerPubKey: The ED25519 Public Key of the Servicer
Needed to identify the Servicer
RelayChain: The identifier of the ‘relayed to’ blockchain
Ex: 0021 (Eth Mainnet)
AAT: The Application Authentication Token for the client serviced
Includes both App Public Key and Client Public Key
Needed for protocol level verification (app node pairings, client permissions, etc.)
ClientSignature: The Elliptic Curve Digital Signature of the client
Preserves the integrity of the Relay data
Needed at Proof/Claim verification level
Response
Response Payload
The response payload is the body of the RPC response:
Response: String representation of the HTTP response
Servicer Signature
The servicer signature completes the signature exchange needed to verify all parties in the servicing protocol.
Signature: preserves the integrity by signing the hash of the Proof of Relay and the response payload.
Claim/Proof Lifecycle
In order to participate in the network economic-incentive mechanism, the Servicer must first Claim and then Prove the completed work. For each Application of each Session, after servicing is complete and Relay Evidence is collected, the Servicer must send two subsequent transactions:
Claim Transaction
Merkle Root of Relay Evidence
Number of Relays serviced
Evidence Type (Relay or Challenge)
Proof Transaction
Selected Relay
Corresponding Merkle Proof for selected Relay
Evidence Type (Relay or Challenge)
Upon successful completion of BOTH transactions, a reward is minted to the Servicer address.
Merkle Tree
POKT Network requires a specific Merkle tree implementation that ensures no two leafs of the Merkle tree are identical (for Relay replay protection). Plasma-Core’s Merkle sum tree satisfies this property.
By using the hash of the Relay data (integrity is validated by verifying the Application Client Signature) in conjunction with replay protection from the Plasma tree, Pocket Network can probabilistically guarantee work completed without the Servicer actually transmitting the entirety of its Relay Evidence to the rest of the network.
A fancier name for this is a Zero Knowledge Range Proof.
Zero Knowledge Range Proof
In order to complete a successful ZKRP in POKT Network, the following steps must be executed by each Servicer for each Session:
Generate the Merkle Tree using the SHA3-256 hash of the Relay Evidence as the leafs.
Submit a Claim Transaction to preserve the integrity of the local Merkle tree and corresponding Relay Evidence, as well as inform the protocol of the range or number of leaves possible to select from.
After a protocol-wide waiting period (determined by governance), the Servicer generates the selected leaf (using the latest block hash as pseudorandom entropy to prevent knowledge of the selection during claim generation) and subsequently creates a Merkle Proof (branch) for the pseudorandomly selected leaf.
The Servicer submits a Proof Transaction containing the selected leaf (Relay Evidence) and the corresponding Merkle Proof (branch).
The protocol verifies the Merkle proof against the previously submitted Merkle root (in the Claim Transaction), verifies the session (proper app/node pair, not overserviced etc.), and then verifies the client signature against the Proof of Relay (integrity check).
All of the Validators confirm the validity of the Proof Transaction, completing the Zero Knowledge Range Proof.
Tokens are minted to the address of the Servicer proportional to the amount of Relays served.
Last updated