Technical Architecture

The high-level technical design of the Allora protocol

The primary goal of Allora is to incentivize data scientists (workers) to provide high-quality inferences. Inferences include predictions of arbitrary future events or difficult computations requiring specialized knowledge. Allora accomplishes this with a technical architecture summarized by the following diagram and elaborated in the paragraphs below.

A high-level diagram of our protocol. Here, "b7s" = "b(lockles)s" refers to [Blockless nodes](https://github.com/blocklessnetwork/b7s) that run off-chain computation, either providing inferences from with proprietary models or running topic-specific logic to score those inferences.

A high-level diagram of Allora. Here, "b7s" = "b(lockles)s" refers to Blockless nodes that run off-chain computation, either providing inferences from proprietary models or running topic-specific logic to score those inferences.

Topics

To ensure inferences from workers are high-quality, Allora aims to incentivize workers more if proven more accurate. The world is, of course, vast and diverse. This makes it challenging to compare inferences of problems that differ vastly in difficulty and possibilities.

To categorize problems, we introduce the concept of topics. A topic is a Schelling point to focus the efforts of the protocol. A topic creator will write a function that rewards those for correctly inferring outcomes, where "correct" is defined by the topic creator. Concretely, a topic has the following attributes:

type Topic struct {
    id uint64
    metadata string             # provides more details about the topic
    weight_logic string         # weight-adjustment logic (see below)
    weight_cadence uint64       # how often in seconds the weight-adjustment logic is ran
    weight_last_ran uint64      # last time at which the weight-adjustment logic was ran
    inference_cadence uint64    # how often in seconds inferences are collected
    inference_last_ran uint64   # last time at which inferences were last collected
    active bool                 # if the topic is accepting new inferences or not
}

Workers commit inferences to topics based on their expertise, providing some means of categorizing domain expertise. However, we still lack a means of differentiating which workers have more expertise or are more trustworthy within the same topic. Allora uses weights to determine this reputation.

Weights

Trust between network participants is communicated via weights, W. Weights are a matrix of numbers where w_ij represents the weight of actor i in actor j, where a higher value indicates more "trust" has been aggregated over the worker's history of participating in the topic. Weights are initialized to be uniform across all other workers registered in a protocol topic. How exactly these weights are updated is determined by the topic-specific weight-adjustment logic (weight_logic) that maps inferences, ground truth, and the current weights matrix to a new weights matrix. For example, in a topic for predicting the traffic in San Francisco next week, the weight adjustment logic may be:

  1. Get a list of predictions made exactly 1 day ago => P_i(t) is a prediction of worker (old parlance: "miner")
    1. It will return a combination of (worker_id, prediction_string)
    2. prediction_string is a string to support any inference; however, it will be a stringified number for this example
  2. Get current weights per worker
    1. It will return triples of (worker_id_i, worker_id_j, weight_uint64)
  3. Get current traffic delays on the 101 from a city data source
  4. Calculate simple loss per worker i at time t : L(i, t) = | B(t) - P_i(t) |
  5. Normalize all losses to be within 0-1 by dividing by the sum of losses across workers
  6. Calculate an exponential moving average (EMA) with the current weights and the normalized losses calculated above.
  7. Commit the EMA'd weights to the appchain

Topic creators write weight-adjustment logic in any language that suits them, then compile this code to WASM using any number of tools. However, we recommend the Blockless CLI). This compiled data is stored as weight_logic in the topic struct at the time of topic creation, which is enabled via the Allora appchain's CLI. The weight logic is called every weight_cadence seconds by the Allora appchain. Each time, weight_last_ran is set to the current UNIX epoch. weight_logic is wrapped within a function manifest and sent to nodes (b7s) in the Blockless Network, which specializes in running arbitrary computations off-chain. This approach lightens the load on the Allora appchain and Tendermint validators, enables writing weight-adjustment logic in any WASM-compilable programming language, and supports arbitrary, customizable valuation techniques for all types of inference.

In the go code for the Allora chain, the weights are defined as follows:

message Weight {  
  option (gogoproto.equal) = true;

  uint64 topic_id = 1;  
  string reputer = 2;  
  string worker = 3;  
  string weight = 4 [  
    (cosmos_proto.scalar)  = "cosmos.Uint",  
    (gogoproto.customtype) = "cosmossdk.io/math.Uint",  
    (gogoproto.nullable)   = false,  
    (amino.dont_omitempty) = true  
  ];  
}

Inferences

We referred to the above as the "valuation" of inferences and mentioned a need to decouple the provision and valuation of inferences. To decouple them, we use the fields inference_cadence and inference_last_ran, which determine when weights should be collected from workers. Every inference_cadence seconds, the Allora appchain solicits inferences from workers, and sets inference_last_ran as the current UNIX epoch.

Workers receive and respond to requests by running worker b7s, which are the same as ordinary b7s but feature two special modifications. Normally, b7s can respond to any request and run the WASM in the request's manifest. However, to keep models private and differentiated (each worker may have a model that's more accurate under certain circumstances than others; hence, we care about model diversity), we require worker b7s to have a special extension that lets them query a privately-held machine learning model for new inferences. To prevent well-intentioned but inappropriate b7s from accidentally accepting a request before a qualified worker can respond (or, similarly, to prevent a worker b7s with a model for a different topic from accidentally accepting a request), we also require that b7s listen to topic-specific channels called subgroups, as initially implemented here. Subgroups allow qualified worker b7s -- b7s that have relevant models -- to have priority access to requests that they have expressed expertise in (i.e. that they have models for).

Inferences returned by workers are then batch committed to the Allora appchain and are truncated weight_cadence seconds after their commitment. Directly committing these values on-chain provides a number of benefits. This ensures we can keep a reliable, even if ephemeral, record of who should be rewarded for their effort. Additionally, it enables consumers to bridge verifiably updated inferences themselves from the Allora appchain to their destination of choice (optionally using whatever transformation of W they want to determine their confidence in the bridged inferences) without requiring the Allora Protocol to update data on all possible destination chains. Furthermore, it enables the protocol to distribute rewards for liveness and availability in a verifiably justified manner.

In the go code for the Allora chain, the inferences are defined as follows:

message Inference {
  option (gogoproto.equal) = true;

  uint64 topic_id = 1;
  string worker = 2;
  string value = 3 [
    (cosmos_proto.scalar)  = "cosmos.Uint",
    (gogoproto.customtype) = "cosmossdk.io/math.Uint",
    (gogoproto.nullable)   = false,
    (amino.dont_omitempty) = true
  ];
  bytes extra_data = 4;
  string proof = 5;
}

Stake

The role of reputers is to indicate their view of the reputation of others. They source ground truth data and compare that to the inferences of workers to determine what worker reputation should be. Reputers first interface with weights indirectly by providing stake to the protocol. This is a financial signal saying how one's allocation of trust accurately represents which workers and other reputers are accurate. Stake also contributes to the protocol-determined importance of that topic relative to others -- a topic with more total stake receives more protocol emissions.

Validators are responsible for operating most of the infrastructure associated with instantiating the Allora Network. They stake in the network to guarantee security.

Similarly, to register within a topic, reputers and workers must place a minimum stake in the Allora native token. This is a relatively small, fixed amount intended to thwart sybil and DDoS attacks. Once this minimum amount is staked, workers and reputers are entitled to participate in the network and receive emissions in return for their work. Participants are no longer eligible to receive emissions when the stake dips below this amount.

Participants can stake using the Allora appchain's CLI.

Rewards

Protocol emissions distribute the Allora native token according to a predetermined schedule. In other words, at each block, more of the native ALLO token is "mined" and distributed to topics in proportion to their stake.

Within each topic, weights determine rewards. Rewards are calculated by normalizing a stake-weighted emissions average allocated to topic workers. Similarly for reputers, the square-of-stake-weighted average of weight is taken and then normalized to the allotted reputer rewards, to emphasize the consequences of the focused efforts of reputers (i.e., their stake allocation). More advanced methods for rewarding workers and reputers are planned for the future. Notably, if a reputer is a worker (or vice versa), they are entitled to both rewards. The record of committed inferences is consulted to determine whether or not a participant is entitled to worker rewards. Otherwise, they are solely given reputer rewards.

The Allora appchain executes both of these calculations at regular intervals, which ensures instant, trustless settlement of all rewards at the time of calculation.

Consumption

As mentioned earlier, the Allora Cosmos appchain provides a trustless settlement layer for all financial flows and is the source of truth for Allora. However, consumers of inferences produced by Allora will wish to leverage the power of decentralized AI on applications located in various places, on any blockchain.

The Allora appchain features a recent record of inferences and a means of deriving trust (the weight matrix W). With this data, and for a fee, consumers can bridge data from the Allora appchain to any other chain on which a "spoke" of the Allora protocol is deployed. Such "spoke" contracts ensure the data was correctly bridged and consumers burned the ALLO token. This increases the value of all stakes and emissions earned via emissions from participation within the network.


What’s Next