This is a reference Yagna Provider Agent implementation. Provider Agent is a module which effectively controls the behaviour of the Provider Node in the Yagna Network. It includes rules and logic for:
- Offer formulation
- Demand validation and evaluation
- Agreement negotiation
- Payment regimes
- Node Resources management
- Activity workflow control
- ExeUnit instantiation and control
- Invoice/Debit Note generation
Please refer https://docs.golem.network/docs/providers/provider-installation for instruction how to use Provider.
It is rather straightforward and minimal:
- at most two constrains:
- requires
golem.srv.comp.expiration
to be set - if provided (via env or CLI) sets also
golem.node.debug.subnet
- requires
- properties:
- linear pricing (see sample below: 0.01 GLM/sec + 1.2 GLM/CPUsec + 1.5 GLM const)
- hardware: memory and storage (sample below: 1 gib RAM and 10 gib disk)
- node name set via env or CLI
- runtime (sample below: wasmtime)
Provider subscribes to the network as many Offers as presets enumerated from CLI.
"properties": {
"golem": {
"com": {
"pricing": {
"model": "linear",
"model.linear": {
"coeffs": [
0.01,
1.2,
1.5
]
}
},
"scheme": "payu",
"scheme.payu": {
"debit-note.interval-sec?": 120.0
},
"usage": {
"vector": [
"golem.usage.duration_sec",
"golem.usage.cpu_sec"
]
}
},
"inf": {
"mem": {
"gib": 1.0
},
"storage": {
"gib": 10.0
}
},
"node": {
"id": {
"name": "__YOUR_NODE_NAME_GOES_HERE__"
}
},
"runtime": {
"name": "wasmtime",
"version": "0.1.0",
"wasm.wasi.version@v": "0.9.0"
}
}
},
"constraints": "(golem.srv.comp.expiration>0)"
}
Current implementation has two naive market strategies:
- accepting all proposals and agreements
- accepting limited number of agreements; will reject proposals and agreements above the limit
Provider Agent uses (hardcode) the second with limit of 1 agreement. It will accept all Proposals until first agreement approval.
Upon agreement termination (in case of failure, expiration or successful finish) Provider Agent will start accepting Proposals again until agreement confirmation; and so on.
Provider agent allow just one activity per agreement.
On activity finish Provider Agent will initiate Agreement termination.
This is workaround because terminate_agreement
operation is not supported yet in Market API.
Provider agent issues Debit Notes every scheme.payu.debit-note.interval-sec?
(120s by default).
The property is a subject of negotiations.
During negotiation Requestor and Provider both agree on timeout
at which Debit Notes are accepted by
Requestor. A property responsible for this is named golem.com.payment.debit-notes.accept-timeout?
.
Provider starts negotiations with 4min and it might be only
lower ie. Requestor might propose lower value, which Provider will accept as long as it is more than
5sec
. Base value for timeout
negotiations is controlled via CLI
and ENV DEBIT_NOTE_ACCEPTANCE_DEADLINE
. Provider is then entitled to break the Agreement after
negotiated timeout
elapses and Debit Note is not accepted.
What's more, Provider is entitled to break the Agreement, when there is no Activity for 90s (ie. idle Agreement).
Provider issues Invoice only once, after the Agreement is terminated.
Provider agent can be used with .env
file. Here
is list of additional environment variables that can be set.
Create separate working dir for the Provider Agent (please create ya-prov
in the main yagna source code directory),
and create .env
file there by copying
.env-template
from yagna repo main directory:
mkdir ya-prov && cd ya-prov && cp ../.env-template .env
and change NODE_NAME
there.
This can be displayed using cargo run -p ya-provider run --help
Parameter | Description | Env var |
---|---|---|
app-key | Authorization token. | YAGNA_APPKEY |
api-url | Yagna REST API address. | YAGNA_API_URL |
data-dir | Path to a directory where configuration files are stored. | DATA_DIR |
node-name | Node name to use in agreements. | NODE_NAME |
subnet | You can set this value to filter nodes with other identifiers than selected. Useful for test purposes. | SUBNET |
exe-unit-path | Path to JSON descriptor file for ExeUnits. | EXE_UNIT_PATH |
To obtain YAGNA_APPKEY
we need to be in this newly created workdir cd ya-prov
:
-
Run yagna service:
cargo run service run
If you want to set
debug
log level or higher its good to filter out core crates toinfo
:RUST_LOG=debug,tokio_core=info,tokio_reactor=info,hyper=info,web3=info cargo run service run
-
Create app-key token
In another console, go to the same directory and run: (it will change your
.env
file with newly created app-key)APP_KEY=`cargo run app-key create 'provider-agent'` sed -e "s/__GENERATED_APP_KEY__/$APP_KEY/" -i.bckp .env
This is the first ExeUnit we've prepared for you.
You need to clone its repository and build.
In following sections we assume you've cloned it to the same directory where yagna
is cloned.
cd ../.. # assuming you are in ./yagna/ya-prov
git clone [email protected]:golemfactory/ya-runtime-wasi.git
cd ya-runtime-wasi
cargo build
cd ../yagna/ya-prov
You also need to build ExeUnit supervisor.
cargo build -p ya-exe-unit
You can list available ExeUnits with command:
$ cargo run -p ya-provider exe-unit list
Available ExeUnits:
Name: wasmtime
Version: 0.1.0
Supervisor: /Users/tworec/git/yagna/target/debug/exe-unit
Runtime: /Users/tworec/git/ya-runtime-wasi/target/debug/ya-runtime-wasi
Description: This is just a sample descriptor for wasmtime exeunit used by ya-provider
Properties:
wasm.wasi.version@v "0.9.0"
Please refer to vm repo documentation.
Afterwards you'll need to update your exeunits-descriptor.json
(defined as EXE_UNIT_PATH
in .env
or os env).
Sample descriptor entry:
{
"name": "vm",
"version": "0.2.0",
"supervisor-path": "exe-unit",
"runtime-path": "/home/user/.local/lib/yagna/plugins/ya-runtime-vm/ya-runtime-vm",
"description": "vm runtime",
"extra-args": ["--cap-handoff"]
}
Provider uses presets to create market offers. On the first run, the Provider Agent will create
a default
preset. Presets are saved in a presets.json
file, located in application's data directory.
You can list presets by running command:
cargo run -p ya-provider preset list
The result will be something like this:
Available Presets:
Name: default
ExeUnit: wasmtime
Pricing model: linear
Coefficients:
Duration 0.1 GLM
CPU 0.2 GLM
Init price 1 GLM
Coefficients describe unit price of ExeUnit metrics:
- Duration -
golem.usage.duration_sec
- CPU -
golem.usage.cpu_sec
- Init price - constant price per created activity
In order to publish an offer based on a preset, that preset needs to be activated first.
To list all active presets, type:
cargo run -p ya-provider preset active
You can create preset in the interactive mode:
cargo run -p ya-provider preset create
...and non-interactively also:
cargo run -p ya-provider preset create \
--no-interactive \
--preset-name new-preset \
--exe-unit wasmtime \
--pricing linear \
--price Duration=1.2 CPU=3.4 "Init price"=0.2
If you don't specify any of price values, it will be defaulted to 0.0
.
Note: updating a preset will cancel (unsubscribe) all related offer subscriptions.
Updating in interactive mode:
cargo run -p ya-provider preset update new-preset
or using command line parameters:
cargo run -p ya-provider preset update new-preset \
--no-interactive \
--exe-unit wasmtime \
--pricing linear \
--price Duration=1.3 CPU=3.5 "Init price"=0.3
You can omit some parameters and the will be filled with previous values.
Note: removing a preset will cancel (unsubscribe) all related offer subscriptions.
cargo run -p ya-provider preset remove new-preset
When you activate a preset, a new offer will be published (subscribed) to the marketplace.
cargo run -p ya-provider preset activate new-preset
Note: deactivating a preset will cancel all related offer subscriptions.
cargo run -p ya-provider preset deactivate new-preset
You can list available metrics with command:
$ cargo run -p ya-provider preset list-metrics
Duration golem.usage.duration_sec
CPU golem.usage.cpu_sec
Left column is name of preset that should be used in commands. On the right side you can see agreement property, that will be set in usage vector.
Hardware profiles control the maximum amount of hardware resources assigned to computations. Provider Agent does not allow you to allocate all of your system resources. The remaining logical CPU cores, memory and storage will be utilized by the background applications, the operating system and Provider Agent itself.
Note: updating or activating another hardware profile will cancel (unsubscribe) all current offer subscriptions.
The available sub-commands for profile
are:
list List available profiles
active Show the name of an active profile
create Create a new profile
update Update a profile
remove Remove an existing profile
activate Activate a profile
cargo run -p ya-provider profile list
will print an output similar to:
{
"default": {
"cpu_threads": 3,
"mem_gib": 10.9375,
"storage_gib": 73.57168884277344
}
}
cargo run -p ya-provider profile active
will print:
"default"
Usage:
ya-provider profile create \
<name> \
--cpu-threads <cpu-threads> \
--mem-gib <mem-gib> \
--storage-gib <storage-gib>
E.g.:
ya-provider profile create half --cpu-threads 2 --mem-gib 8. --storage-gib 256.
Note: updating a profile will cancel all current offer subscriptions.
Usage is similar to profile creation.
E.g.:
ya-provider profile update half --cpu-threads 3 --mem-gib 5. --storage-gib 128.
Note: removing an active profile will cancel all current offer subscriptions.
E.g.:
ya-provider profile remove half
Note: activating a different profile will cancel all current offer subscriptions.
E.g.:
ya-provider profile activate some_other_profile
While the yagna service is still running (and you are in the ya-prov
directory)
you can now start Provider Agent.
cargo run -p ya-provider run