Skip to content

Commit

Permalink
add reputer page
Browse files Browse the repository at this point in the history
  • Loading branch information
kpeluso committed May 15, 2024
1 parent 8453e57 commit 6851b82
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 6 deletions.
10 changes: 5 additions & 5 deletions pages/learn/architecture.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ message WorkerAttributedLoss {
}

// eq13 in the litepaper
message LossBundle {
message ValueBundle {
option (gogoproto.equal) = true;

uint64 topic_id = 1;
Expand All @@ -157,21 +157,21 @@ message LossBundle {
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
repeated WorkerAttributedLoss inferer_losses = 5;
repeated WorkerAttributedLoss forcaster_losses = 6;
repeated WorkerAttributedValue inferer_values = 5;
repeated WorkerAttributedValue forcaster_values = 6;
string naive_loss = 7 [
(cosmos_proto.scalar) = "cosmos.Uint",
(gogoproto.customtype) = "cosmossdk.io/math.Uint",
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
repeated WorkerAttributedLoss one_out_losses = 8 [
repeated WorkerAttributedValue one_out_values = 8 [
(cosmos_proto.scalar) = "cosmos.Uint",
(gogoproto.customtype) = "cosmossdk.io/math.Uint",
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
repeated WorkerAttributedLoss one_in_naive_losses = 9 [
repeated WorkerAttributedValue one_in_naive_values = 9 [
(cosmos_proto.scalar) = "cosmos.Uint",
(gogoproto.customtype) = "cosmossdk.io/math.Uint",
(gogoproto.nullable) = false,
Expand Down
3 changes: 2 additions & 1 deletion pages/nops/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"deploy-chain": "Deploy Allora Chain",
"run-full-node": "Run a Full Node",
"stake-a-validator": "Stake a Validator",
"validator-operations": "Validator Operations"
"validator-operations": "Validator Operations",
"reputers": "Reputers"
}
149 changes: 149 additions & 0 deletions pages/nops/reputers.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Reputers

Reputers do the following actions on Allora:

* Source ground truth as specified by the [topic metadata](../learn/architecture.mdx#topics)
* e.g. the actual price of ETH as of a moment in time
* Calculate loss of workers inferences and forecast-implied inferences relative to that ground truth
* e.g. A topic's loss function is an [L1-norm](https://machinelearningmastery.com/vector-norms-machine-learning/) applied to each worker's inference and the revealed price of ETH in 10 days per CoinGecko API. Reputers apply this loss function to every inference received in a request and respond with a [`ValueBundle` of losses](../learn/architecture.mdx#loss-calculation)
* Secure topics [with their stake](../learn/architecture.mdx#stake)
* the more a reputer stakes in a topic, the more they influence the consensus of losses
* reputers can be [delegated to](../learn/architecture.mdx#delegated-stake) as well, increasing the extent to which they [secure the topic](../learn/architecture.mdx#topic-security-vs-chain-security)
* Receive rewards based on how close to consensus their reported losses are
* a stake-weighted average of each reported loss is taken among reputers per topic per epoch
* the closer a reputer's values are to the average, the more they are rewarded


## Setup a Reputer Node with `docker-compose`

A full working example for a reputer node for ETH price prediction topics is provided in the [`docker-compose.yml` file](https://github.com/allora-network/coin-prediction-reputer/blob/main/docker-compose.yml) of our example repo.

### Components of the Example Reputer Node

This example contains a service for sourcing truth -- called the "`truth` service" -- a Blockless worker node for responding to Blockless requests and calculating topic-specific los functions, and a Blockless head node for initiating requests.

In practice, you would only run a head node as a side car to a validator node. This way, chain validators can initiate requests to collect inferences and forecasts from workers, and ground-truth-informed loss calculations from reputers.

You can read more about the lifecycle of Blockless requests [on the Blockless docs](https://blockless.network/docs/protocol/networking).

If you were just acting as a reputer, you would only be responding to requests from another peer's head node, not your own head node.


## Setup a Reputer Node Manually

Here, we'll recreate the steps contained within the `docker-compose.yml` file. We'll setup a reputer that sources ground truth and calculates losses for ETH price prediction topics, plus a head node for development and testing purposes.

### Generate keys

Create a set of keys for your head and worker nodes. These keys will be used in the configuration of the head and worker nodes.

#### Create head keys

```
docker run -it --entrypoint=bash -v ./head-data:/data alloranetwork/allora-inference-base:latest -c "mkdir -p /data/keys && (cd /data/keys && allora-keys)"
```

#### Create worker keys

```
docker run -it --entrypoint=bash -v ./worker-data:/data alloranetwork/allora-inference-base:latest -c "mkdir -p /data/keys && (cd /data/keys && allora-keys)"
```

Important note: If no keys are specified in the volumes, new keys will be automatically created inside `head-data/keys` and `worker-data/keys` when first running step 4.

### Connect the worker node to the head node

At this step, both worker and head nodes identities are generated inside `head-data/keys` and `worker-data/keys`.

Now, we must register the worker with the head. When the head initiates a request, it will ping all the Blockless workers that have registered to it.

To instruct the worker node to connect to the head node:
- run `cat head-data/keys/identity` to extract the head node's peer_id
- copy this printed peer_id to replace the `head-id` placeholder value specified inside the docker-compose.yml file (or docker-compose.arm64.yml based on your configuration) when running the worker service: `--boot-nodes=/ip4/172.22.0.100/tcp/9010/p2p/head-id`

### Run setup

Once all the above is set up, run `docker compose up`
This will bring up the head, the worker and the truth nodes (which will run an initial update).

### Keep it updated

You can keep the state updated by hitting the url:

```
http://localhost:8000/update/<token-name>/<token-from>/<token-to>
```
where:
- `token-name`: the name of the token on internal database, e.g. ETHUSD
- `token-from`: the name of the token on Coingecko naming, e.g. ethereum
- `token-to`: the name of the token on Coingecko naming, e.g. usd

It is expected that this endpoint is hit periodically, as this is crucial for maintaining the accuracy of the provided ground truth.


## Testing docker-compose setup

The head node has the only open port, and responds to requests in port 6000.

Example request:
```
curl --location 'http://localhost:6000/api/v1/functions/execute' --header 'Accept: application/json, text/plain, */*' --header 'Content-Type: application/json;charset=UTF-8' --data '{
"function_id": "bafybeigpiwl3o73zvvl6dxdqu7zqcub5mhg65jiky2xqb4rdhfmikswzqm",
"method": "allora-inference-function.wasm",
"parameters": null,
"topic": "1",
"config": {
"env_vars": [
{
"name": "BLS_REQUEST_PATH",
"value": "/api"
},
{
"name": "ALLORA_ARG_PARAMS",
"value": "1711064725"
}
],
"number_of_nodes": -1,
"timeout" : 2
}
}'
```


## Testing the Truth Service

Here we'll setup a reputer with only the "truth service", which fetches the ground truth.

To only test the truth service, you can simply follow these steps:

- Run `docker compose up --build truth` and wait for the initial data load.
- Requests can now be sent, e.g. ETH price ground truths can be fetched with:
```
$ curl http://localhost:8000/get/ETHUSD/1711105645
{"value":"3227.311942291347"}
```
or you can trigger an update to the current ETH price:
```
$ curl http://localhost:8000/update/ETHUSD/ethereum/usd
```


## Connecting to the Allora network

In order to connect to the Allora network, both the head and the worker need to register against it. More details on [allora-inference-base](https://github.com/allora-network/allora-inference-base) repo.

The following optional flags are used in the `command:` section of the `docker-compose.yml` file to define the connectivity with the Allora network.

```
--allora-chain-key-name=index-provider # your local key name in your keyring
--allora-chain-restore-mnemonic='pet sock excess ...' # your node's Allora address mnemonic
--allora-node-rpc-address= # RPC address of a node in the chain
--allora-chain-topic-id= # The topic id from the chain that you want to provide predictions for
```
In order for the nodes to register with the chain, a funded address is needed first.
If these flags are not provided, the nodes will not register to the appchain and will not attempt to connect to the appchain.


## Learn More

Learn more by directly checking out the code and README for [the example ETH price reputer](https://github.com/allora-network/coin-prediction-reputer).

0 comments on commit 6851b82

Please sign in to comment.