ritual/README.md

222 lines
7.7 KiB
Markdown

# infernet-container-starter
Starter examples for deploying to infernet.
# Getting Started
To interact with infernet, one could either create a job by accessing an infernet
node directly through it's API (we'll refer to this as an off-chain job), or by
creating a subscription on-chain (we'll refer to this as an on-chain job).
## Requesting an off-chain job: Hello World!
The easiest way to get started is to run our hello-world container.
This is a simple [flask-app](projects/hello-world/container/src/app.py) that
is compatible with `infernet`, and simply
[echoes what you send to it](./projects/hello-world/container/src/app.py#L16).
We already have it [hosted on docker hub](https://hub.docker.com/r/ritualnetwork/hello-world-infernet) .
If you're curious how it's made, you can
follow the instructions [here](projects/hello-world/container/README.md) to build your own infernet-compatible
container.
### Install Docker
To run this, you'll need to have docker installed. You can find instructions
for installing docker [here](https://docs.docker.com/install/).
### Running Locally
First, ensure that the docker daemon is running.
Then, from the top-level project directory, Run the following make command:
```
project=hello-world make deploy-container
```
This will deploy an infernet node along with the `hello-world` image.
### Creating an off-chain job through the API
You can create an off-chain job by posting to the `node` directly.
```bash
curl -X POST http://127.0.0.1:4000/api/jobs \
-H "Content-Type: application/json" \
-d '{"containers":["hello-world"], "data": {"some": "input"}}'
# returns
{"id":"d5281dd5-c4f4-4523-a9c2-266398e06007"}
```
This will return the id of that job.
### Getting the status/result/errors of a job
You can check the status of a job like so:
```bash
curl -X GET http://127.0.0.1:4000/api/jobs?id=d5281dd5-c4f4-4523-a9c2-266398e06007
# returns
[{"id":"d5281dd5-c4f4-4523-a9c2-266398e06007", "result":{"container":"hello-world","output": {"output":"hello, world!, your input was: {'source': 1, 'data': {'some': 'input'}}"}} ,"status":"success"}]
```
### Configuration
This project already comes with a pre-filled config file. The config
file for the hello-world project is located [here](projects/hello-world/container/config.json):
```bash
projects/hello-world/config.json
```
## Requesting an on-chain job
In this section we'll go over how to request an on-chain job in a local testnet.
### Infernet's Anvil Testnet
To request an on-chain job, you'll need to deploy contracts using the infernet sdk.
We already have a public [anvil node](https://hub.docker.com/r/ritualnetwork/infernet-anvil) docker image which has the
corresponding infernet sdk contracts deployed, along with a node that has
registered itself to listen to on-chain subscription events.
* Coordinator Address: `0x5FbDB2315678afecb367f032d93F642f64180aa3`
* Node Address: `0x70997970C51812dc3A010C7d01b50e0d17dc79C8` (This is the second account in the anvil's accounts.)
### Deploying Infernet Node & Infernet's Anvil Testnet
This step is similar to the section above:
```bash
project=hello-world make deploy-container
```
In another terminal, run `docker container ls`, you should see something like this
```bash
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c2ca0ffe7817 ritualnetwork/infernet-anvil:0.0.0 "anvil --host 0.0.0.…" 9 seconds ago Up 8 seconds 0.0.0.0:8545->3000/tcp anvil-node
0b686a6a0e5f ritualnetwork/hello-world-infernet:0.0.2 "gunicorn app:create…" 9 seconds ago Up 8 seconds 0.0.0.0:3000->3000/tcp hello-world
28b2e5608655 ritualnetwork/infernet-node:0.1.1 "/app/entrypoint.sh" 10 seconds ago Up 10 seconds 0.0.0.0:4000->4000/tcp deploy-node-1
03ba51ff48b8 fluent/fluent-bit:latest "/fluent-bit/bin/flu…" 10 seconds ago Up 10 seconds 2020/tcp, 0.0.0.0:24224->24224/tcp deploy-fluentbit-1
a0d96f29a238 redis:latest "docker-entrypoint.s…" 10 seconds ago Up 10 seconds 0.0.0.0:6379->6379/tcp deploy-redis-1
```
You can see that the anvil node is running on port `8545`, and the infernet
node is running on port `4000`. Same as before.
### Deploying Consumer Contracts
We have a [sample forge project](./projects/hello-world/contracts) which contains
a simple consumer contract, [`SaysGM`](./projects/hello-world/contracts/src/SaysGM.sol).
All this contract does is to request a job from the infernet node, and upon receiving
the result, it will use the `forge` console to print the result.
**Anvil Logs**: First, it's useful to look at the logs of the anvil node to see what's going on. In
a new terminal, run `docker logs -f anvil-node`.
**Deploying the contracts**: In another terminal, run the following command:
```bash
project=hello-world make deploy-contracts
```
You should be able to see the following logs in the anvil logs:
```bash
eth_sendRawTransaction
eth_getTransactionReceipt
Transaction: 0x23ca6b1d1823ad5af175c207c2505112f60038fc000e1e22509816fa29a3afd6
Contract created: 0x663f3ad617193148711d28f5334ee4ed07016602
Gas used: 476669
Block Number: 1
Block Hash: 0x6b026b70fbe97b4a733d4812ccd6e8e25899a1f6c622430c3fb07a2e5c5c96b7
Block Time: "Wed, 17 Jan 2024 22:17:31 +0000"
eth_getTransactionByHash
eth_getTransactionReceipt
eth_blockNumber
```
We can see that a new contract has been created at `0x663f3ad617193148711d28f5334ee4ed07016602`.
That's the address of the `SaysGM` contract.
### Calling the contract
Now, let's call the contract. In the same terminal, run the following command:
```bash
project=hello-world make call-contract
```
You should first see that a transaction was sent to the `SaysGm` contract:
```bash
eth_getTransactionReceipt
Transaction: 0xe56b5b6ac713a978a1631a44d6a0c9eb6941dce929e1b66b4a2f7a61b0349d65
Gas used: 123323
Block Number: 2
Block Hash: 0x3d6678424adcdecfa0a8edd51e014290e5f54ee4707d4779e710a2a4d9867c08
Block Time: "Wed, 17 Jan 2024 22:18:39 +0000"
eth_getTransactionByHash
```
Then, right after that you should see another transaction submitted by the `node`,
which is the result of the job request:
```bash
eth_chainId
eth_sendRawTransaction
_____ _____ _______ _ _ _
| __ \|_ _|__ __| | | | /\ | |
| |__) | | | | | | | | | / \ | |
| _ / | | | | | | | |/ /\ \ | |
| | \ \ _| |_ | | | |__| / ____ \| |____
|_| \_\_____| |_| \____/_/ \_\______|
subscription Id 1
interval 1
redundancy 1
node 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
input:
0x
output:
0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000607b276f7574707574273a202268656c6c6f2c20776f726c64212c20796f757220696e707574207761733a207b27736f75726365273a20302c202764617461273a20273437366636663634323036643666373236653639366536373231277d227d
proof:
0x
Transaction: 0x949351d02e2c7f50ced2be06d14ca4311bd470ec80b135a2ce78a43f43e60d3d
Gas used: 94275
Block Number: 3
Block Hash: 0x57ed0cf39e3fb3a91a0d8baa5f9cb5d2bdc1875f2ad5d6baf4a9466f522df354
Block Time: "Wed, 17 Jan 2024 22:18:40 +0000"
eth_blockNumber
eth_newFilter
```
We can see that the address of the `node` matches the address of the node in
our ritual anvil node.
### Next Steps
To learn more about on-chain requests, check out the following resources:
1. [Tutorial](./projects/hello-world/contracts/Tutorial.md) on this project's consumer smart contracts.
2. [Infernet Callback Consumer Tutorial](https://docs.ritual.net/infernet/sdk/consumers/Callback)
3. [Infernet Nodes Docoumentation](https://docs.ritual.net/infernet/nodes)