Allora off-chain nodes publish inferences, forecasts, and losses informed by a configurable ground truth and applying a configurable loss function to the Allora chain.
- Clone the repository
- Make sure to remove any .env file so it doesn't clash with the automated environment variables
- Copy config.example.json and populate with your variables. You can either populate with your existing wallet or leave it empty for it to be autocreated
cp config.example.json config.json
- Run command below to load your config.json file to environment
chmod +x init.config
./init.config
from the root directory. This will:
- Load your config.json file into the environment. Depending on whether you provided your wallet details or not it will also do the following:
- Automatically create allora keys for you. You will have to request for some tokens from faucet to be able to register your worker and stake your reputer. You can find your address in ./data/env_file
- Automatically export the needed variables from the account created to be used by the offchain node and bundles it with the your provided config.json and then pass them to the node as environemnt variable
- Run
docker compose up --build
. This will:- Run the both the offchain node and the source services, communicating through endpoints attached to the internal dns
Please note that the environment variable will be created as bumdle of your config.json and allora account secrets, please make sure to remove every secrets before commiting to remote git repository
- Clone the repository
- Install Go 1.22.5
- Install the dependencies:
go mod download
- Copy environment variables:
cp .env.example .env
- Fill in the environment variables in
.env
with your own values - If you're a worker...
- Configure your inference and/or forecast models in
adapters/
and/or another source linked to by adapters inadapters/
directory.
- Configure your inference and/or forecast models in
- If you're a reputer...
- Configure your repute and/or loss models in
adapters/
and/or another source linked to by adapters inadapters/
directory.
- Configure your repute and/or loss models in
- Map each topic to the appropriate adapter in
config.json
. - Run the following commands:
chmod +x start.local
./start.local
Some metrics has been provided for in the node. You can access them with port :2112/metrics
. Here are the following list of existing metrics:
allora_worker_inference_request_count
: The total number of times worker requests inference from sourceallora_worker_forecast_request_count
: The total number of times worker requests forecast from sourceallora_reputer_truth_request_count
: The total number of times reputer requests truth from sourceallora_worker_data_build_count
: The total number of times worker built data successfullyallora_reputer_data_build_count
: The total number of times reputer built data successfullyallora_worker_chain_submission_count
: The total number of worker commits to the chainallora_reputer_chain_submission_count
: The total number of reputer commits to the chain
Please note that we will keep updating the list as more metrics are being added
Visualization of timeline and submission windows for an actor, in this case, a worker. Reputers have submission windows too, but they are fixed to be 1 full topic's epoch length.
Example configuration:
- Topic epoch length is 100 blocks
- Topic submission window is 10 blocks
- Near zone is 2 submission windows (20 blocks)
Epoch N Epoch N+1
|---------|----------------------------------|-----------------------------------|--------→
Block: 1000 1100 1200
↑ ↑ ↑
Epoch Start Epoch End Next Epoch End
(& Submission & Next Epoch Start
Window Start) (& Next Submission
Window Start)
Detailed View of Zones (assuming epoch length = 100 blocks):
Block 1000 Block 1010 Block 1080 Block 1100
|-----------|--------------------------|--------------|
|← Far Zone →|← Near Zone →|
|← SW →|
(SW = Submission Window)
Zone Breakdown (example numbers):
• Epoch Length: 100 blocks
• Submission Window: 100 blocks (coincides with epoch)
• Near Zone: Last 20 blocks (NUM_SUBMISSION_WINDOWS_FOR_SUBMISSION_NEARNESS * WorkerSubmissionWindow)
-------------------------------
- Full cycle transition points
- Block 1000: Epoch N starts & Submission Window opens
- Block 1010: Submission Window closes. Waiting for next window, typically from far zone.
- Block 1080: Enters Near Zone (more frequent checks)
- Block 1100: Epoch N ends & Epoch N+1 starts
- Submissions
- Submissions are accepted within the submission window
- Submission window opens at epoch start
- Waiting Zone Behavior
- The behaviour of the node when waiting for the submission window depends on its nearness to the submission window to reduce likelihood of missing a window.
- Far Zone: Longer intervals between checks, optimized for efficiency
- This is controlled by
blockDurationEstimated
andwindowCorrectionFactor
- This is controlled by
- Near Zone: More frequent checks with randomization for fair participation
- Submissions are separated - they must happen within the submission window
The node introduces a random offset to the submission time to avoid the thundering herd problem alleviating mempool congestion.
There are several ways to configure the node. In order of preference, you can do any of these:
- Set the
ALLORA_OFFCHAIN_NODE_CONFIG_JSON
env var with a configuration as a JSON string. - Set the
ALLORA_OFFCHAIN_NODE_CONFIG_FILE_PATH
env var pointing to a file, which contains configuration as JSON. An example if provided inconfig.example.json
.
Each option completely overwrites the other options.
This is the entrypoint for the application that simply builds and runs the Go program.
It spins off a distinct processes per role worker, reputer per topic configered in config.json
.
- LOG_LEVEL: Set the logging level. Valid values are
debug
,info
,warn
,error
,fatal
,panic
. Defaults toinfo
. - LOG_TIME_FORMAT: Sets the format of the timestamp in the log. Valid values are
unix
,unixms
,unixmicro
,iso8601
. Defaults toiso8601
.
The wallet configuration is done in config.json
under the wallet
field.
gas
can be set toauto
or a specific gas value. If set toauto
, the node will automatically calculate the gas limit based on the estimated gas used by the transactions.gasAdjustment
is used to adjust the gas limit.gasPrices
andmaxFees
fields are used to set the gas prices and max fees for the wallet. They are expressed inuallo
.
Error handling is done differently for different types of errors. Note: when an account sequence mismatch is detected, the node will attempt to set the expected sequence number and retry the transaction before broadcasting. Note: the node will check if the actor is whitelisted on worker setup and before submitting a payload.
accounSequenceRetryDelay
: For the "account sequence mismatch" error.retryDelay
: For all other errors that need retry delays.
The node will automatically detect the submission window length for each topic on each actor type. This can be configured by the following settings in the config.json:
blockDurationEstimated
: Estimated network block time in seconds. Minimum is 1.windowCorrectionFactor
: Correction factor to fine-tune the submission window length. Higher values optimize the number of calls for window checking. Minimum is 0.5.
A complete example is provided in config.example.json
.
These below are excerpts of the configuration (with some parts omitted for brevity) for different setups:
{
"worker": [
{
"topicId": 1,
"inferenceEntrypointName": "api-worker-reputer",
"loopSeconds": 10,
"parameters": {
"InferenceEndpoint": "http://source:8000/inference/{Token}",
"Token": "ETH"
}
}
]
}
{
"worker": [
{
"topicId": 1,
"forecastEntrypointName": "api-worker-reputer",
"loopSeconds": 10,
"parameters": {
"ForecastEndpoint": "http://source:8000/forecasts/{TopicId}/{BlockHeight}"
}
}
]
}
{
"worker": [
{
"topicId": 1,
"inferenceEntrypointName": "api-worker-reputer",
"forecastEntrypointName": "api-worker-reputer",
"loopSeconds": 10,
"parameters": {
"InferenceEndpoint": "http://source:8000/inference/{Token}",
"ForecastEndpoint": "http://source:8000/forecasts/{TopicId}/{BlockHeight}",
"Token": "ETH"
}
}
]
}
{
"reputer": [
{
"topicId": 1,
"groundTruthEntrypointName": "api-worker-reputer",
"lossFunctionEntrypointName": "api-worker-reputer",
"loopSeconds": 30,
"minStake": 100000,
"groundTruthParameters": {
"GroundTruthEndpoint": "http://localhost:8888/gt/{Token}/{BlockHeight}",
"Token": "ETHUSD"
},
"lossFunctionParameters": {
"LossFunctionService": "http://localhost:5000",
"LossMethodOptions": {
"loss_method": "sqe"
}
}
}
]
}
{
"worker": [
{
"topicId": 1,
"inferenceEntrypointName": "api-worker-reputer",
"forecastEntrypointName": "api-worker-reputer",
"loopSeconds": 10,
"parameters": {
"InferenceEndpoint": "http://source:8000/inference/{Token}",
"ForecastEndpoint": "http://source:8000/forecasts/{TopicId}/{BlockHeight}",
"Token": "ETH"
}
}
],
"reputer": [
{
"topicId": 1,
"groundTruthEntrypointName": "api-worker-reputer",
"lossFunctionEntrypointName": "api-worker-reputer",
"loopSeconds": 30,
"minStake": 100000,
"groundTruthParameters": {
"GroundTruthEndpoint": "http://localhost:8888/gt/{Token}/{BlockHeight}",
"Token": "ETHUSD"
},
"lossFunctionParameters": {
"LossFunctionService": "http://localhost:5000",
"LossMethodOptions": {
"loss_method": "sqe"
}
}
}
]
}
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.