Run multiple Ponder indexers in payment stack (#588)

* Separate ponder indexer and ponder watcher and add second ponder indexer

* Handle review changes

* Update config to point ponder watcher to indexer 2 to indexer 1

* Update Ponder demo

* Use deployed ERC20 contract in second Ponder indexer

* Add order by timestamp in Ponder watcher app entities query

* Upgrade go-nitro version to v0.1.2-ts-port-0.1.9

* Decrease Ponder start block to process contract transfer event at deployment

---------

Co-authored-by: Shreerang Kale <shreerangkale@gmail.com>
This commit is contained in:
Nabarun Gogoi 2023-10-19 12:26:10 +05:30 committed by GitHub
parent 2402220273
commit 4a90cedeb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 326 additions and 133 deletions

View File

@ -15,16 +15,16 @@ services:
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
ponder-app-indexer: ponder-app-indexer-1:
hostname: ponder-app-indexer hostname: ponder-app-indexer-1
restart: unless-stopped restart: unless-stopped
image: cerc/ponder:local image: cerc/ponder:local
working_dir: /app/examples/token-erc20 working_dir: /app/examples/token-erc20
environment: environment:
CERC_PONDER_CHAIN_ID: ${PONDER_CHAIN_ID:-99} CERC_PONDER_CHAIN_ID: ${PONDER_CHAIN_ID:-99}
CERC_PONDER_RPC_URL_1: ${PONDER_RPC_URL_1:-http://ipld-eth-server-2:8081} CERC_PONDER_RPC_URL_1: ${PONDER_RPC_URL_1:-http://ipld-eth-server-2:8081}
CERC_PONDER_NITRO_PK: ${CERC_PONDER_INDEXER_NITRO_PK:-58368d20ff12f17669c06158c21d885897aa56f9be430edc789614bf9851d53f} CERC_PONDER_NITRO_PK: ${CERC_PONDER_INDEXER_NITRO_PK_1:-58368d20ff12f17669c06158c21d885897aa56f9be430edc789614bf9851d53f}
CERC_PONDER_NITRO_CHAIN_PK: ${CERC_PONDER_INDEXER_NITRO_CHAIN_PK:-fb1e9af328c283ca3e2486e7c24d13582b7912057d8b9542ff41503c85bc05c0} CERC_PONDER_NITRO_CHAIN_PK: ${CERC_PONDER_INDEXER_NITRO_CHAIN_PK_1:-fb1e9af328c283ca3e2486e7c24d13582b7912057d8b9542ff41503c85bc05c0}
CERC_PONDER_NITRO_CHAIN_URL: ${CERC_PONDER_NITRO_CHAIN_URL:-http://fixturenet-eth-geth-1:8546} CERC_PONDER_NITRO_CHAIN_URL: ${CERC_PONDER_NITRO_CHAIN_URL:-http://fixturenet-eth-geth-1:8546}
CERC_RELAY_MULTIADDR: ${CERC_RELAY_MULTIADDR} CERC_RELAY_MULTIADDR: ${CERC_RELAY_MULTIADDR}
CERC_UPSTREAM_NITRO_ADDRESS: ${CERC_UPSTREAM_NITRO_ADDRESS:-0x660a4bEF3fbC863Fcd8D3CDB39242aE513d7D92e} CERC_UPSTREAM_NITRO_ADDRESS: ${CERC_UPSTREAM_NITRO_ADDRESS:-0x660a4bEF3fbC863Fcd8D3CDB39242aE513d7D92e}
@ -33,44 +33,42 @@ services:
command: ["bash", "./ponder-start.sh"] command: ["bash", "./ponder-start.sh"]
volumes: volumes:
- ../config/ponder/ponder-start.sh:/app/examples/token-erc20/ponder-start.sh - ../config/ponder/ponder-start.sh:/app/examples/token-erc20/ponder-start.sh
- ../config/ponder/ponder.indexer.config.ts:/app/examples/token-erc20/ponder.config.ts - ../config/ponder/ponder.indexer-1.config.ts:/app/examples/token-erc20/ponder.config.ts
- ../config/ponder/base-rates-config.json:/app/examples/token-erc20/base-rates-config.json - ../config/ponder/base-rates-config.json:/app/examples/token-erc20/base-rates-config.json
- peers_ids:/peers - peers_ids:/peers
- nitro_deployment:/nitro - nitro_deployment:/nitro
- erc20_deployment:/erc20 - erc20_deployment:/erc20
- ponder_indexer_nitro_data:/app/examples/token-erc20/.ponder/nitro-db - ponder_indexer_1_nitro_data:/app/examples/token-erc20/.ponder/nitro-db
ports: ports:
- "42070" - "127.0.0.1:42070:42070"
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
ponder-app-watcher: ponder-app-indexer-2:
hostname: ponder-app-watcher hostname: ponder-app-indexer-2
depends_on:
- ponder-app-indexer
restart: unless-stopped restart: unless-stopped
image: cerc/ponder:local image: cerc/ponder:local
working_dir: /app/examples/token-erc20 working_dir: /app/examples/token-erc20
environment: environment:
CERC_PONDER_CHAIN_ID: ${PONDER_CHAIN_ID:-99} CERC_PONDER_CHAIN_ID: ${PONDER_CHAIN_ID:-99}
CERC_PONDER_NITRO_PK: ${CERC_PONDER_WATCHER_NITRO_PK:-febb3b74b0b52d0976f6571d555f4ac8b91c308dfa25c7b58d1e6a7c3f50c781} CERC_INDEXER_GQL_ENDPOINT: ${CERC_INDEXER_GQL_ENDPOINT:-http://ponder-app-indexer-1:42070/graphql}
CERC_PONDER_NITRO_CHAIN_PK: ${CERC_PONDER_WATCHER_NITRO_CHAIN_PK:-be4aa664815ea3bc3d63118649a733f6c96b243744310806ecb6d96359ab62cf} CERC_PONDER_NITRO_PK: ${CERC_PONDER_INDEXER_NITRO_PK_2:-0aca28ba64679f63d71e671ab4dbb32aaa212d4789988e6ca47da47601c18fe2}
CERC_PONDER_NITRO_CHAIN_PK: ${CERC_PONDER_INDEXER_NITRO_CHAIN_PK_2:-6177345b77c4069ac4d553f8b43cf68a799ca4bb63eac93d6cf796d63694ebf0}
CERC_PONDER_NITRO_CHAIN_URL: ${CERC_PONDER_NITRO_CHAIN_URL:-http://fixturenet-eth-geth-1:8546} CERC_PONDER_NITRO_CHAIN_URL: ${CERC_PONDER_NITRO_CHAIN_URL:-http://fixturenet-eth-geth-1:8546}
CERC_RELAY_MULTIADDR: ${CERC_RELAY_MULTIADDR} CERC_RELAY_MULTIADDR: ${CERC_RELAY_MULTIADDR}
CERC_INDEXER_GQL_ENDPOINT: ${CERC_INDEXER_GQL_ENDPOINT:-http://ponder-app-indexer:42070/graphql}
CERC_INDEXER_NITRO_ADDRESS: ${CERC_INDEXER_NITRO_ADDRESS:-0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d} CERC_INDEXER_NITRO_ADDRESS: ${CERC_INDEXER_NITRO_ADDRESS:-0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d}
CERC_INDEXER_NITRO_PAY_AMOUNT: ${CERC_INDEXER_NITRO_PAY_AMOUNT:-50} CERC_UPSTREAM_NITRO_PAY_AMOUNT: ${CERC_UPSTREAM_NITRO_PAY_AMOUNT:-100}
command: ["bash", "./ponder-start.sh"] command: ["bash", "./ponder-start.sh"]
volumes: volumes:
- ../config/ponder/ponder-start.sh:/app/examples/token-erc20/ponder-start.sh - ../config/ponder/ponder-start.sh:/app/examples/token-erc20/ponder-start.sh
- ../config/ponder/ponder.watcher.config.ts:/app/examples/token-erc20/ponder.config.ts - ../config/ponder/ponder.indexer-2.config.ts:/app/examples/token-erc20/ponder.config.ts
- ../config/ponder/base-rates-config.json:/app/examples/token-erc20/base-rates-config.json - ../config/ponder/base-rates-config.json:/app/examples/token-erc20/base-rates-config.json
- peers_ids:/peers - peers_ids:/peers
- nitro_deployment:/nitro - nitro_deployment:/nitro
- erc20_deployment:/erc20 - erc20_deployment:/erc20
- ponder_watcher_nitro_data:/app/examples/token-erc20/.ponder/nitro-db - ponder_indexer_2_nitro_data:/app/examples/token-erc20/.ponder/nitro-db
ports: ports:
- "42069" - "127.0.0.1:42071:42070"
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
@ -78,5 +76,5 @@ volumes:
peers_ids: peers_ids:
nitro_deployment: nitro_deployment:
erc20_deployment: erc20_deployment:
ponder_indexer_nitro_data: ponder_indexer_1_nitro_data:
ponder_watcher_nitro_data: ponder_indexer_2_nitro_data:

View File

@ -0,0 +1,39 @@
version: '3.7'
services:
ponder-app-watcher:
hostname: ponder-app-watcher
depends_on:
- ponder-app-indexer-1
restart: unless-stopped
image: cerc/ponder:local
working_dir: /app/examples/token-erc20
environment:
CERC_PONDER_CHAIN_ID: ${PONDER_CHAIN_ID:-99}
CERC_PONDER_NITRO_PK: ${CERC_PONDER_WATCHER_NITRO_PK:-febb3b74b0b52d0976f6571d555f4ac8b91c308dfa25c7b58d1e6a7c3f50c781}
CERC_PONDER_NITRO_CHAIN_PK: ${CERC_PONDER_WATCHER_NITRO_CHAIN_PK:-be4aa664815ea3bc3d63118649a733f6c96b243744310806ecb6d96359ab62cf}
CERC_PONDER_NITRO_CHAIN_URL: ${CERC_PONDER_NITRO_CHAIN_URL:-http://fixturenet-eth-geth-1:8546}
CERC_RELAY_MULTIADDR: ${CERC_RELAY_MULTIADDR}
CERC_INDEXER_GQL_ENDPOINT: ${CERC_INDEXER_GQL_ENDPOINT:-http://ponder-app-indexer-2:42070/graphql}
CERC_INDEXER_NITRO_ADDRESS: ${CERC_INDEXER_NITRO_ADDRESS:-0xB2B22ec3889d11f2ddb1A1Db11e80D20EF367c01}
CERC_INDEXER_NITRO_PAY_AMOUNT: ${CERC_INDEXER_NITRO_PAY_AMOUNT:-50}
command: ["bash", "./ponder-start.sh"]
volumes:
- ../config/ponder/ponder-start.sh:/app/examples/token-erc20/ponder-start.sh
- ../config/ponder/ponder.watcher.config.ts:/app/examples/token-erc20/ponder.config.ts
- ../config/ponder/base-rates-config.json:/app/examples/token-erc20/base-rates-config.json
- peers_ids:/peers
- nitro_deployment:/nitro
- erc20_deployment:/erc20
- ponder_watcher_nitro_data:/app/examples/token-erc20/.ponder/nitro-db
ports:
- "127.0.0.1:42069:42069"
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
peers_ids:
nitro_deployment:
erc20_deployment:
ponder_watcher_nitro_data:

View File

@ -2,7 +2,9 @@
"freeQueriesLimit": 10, "freeQueriesLimit": 10,
"freeQueriesList": [], "freeQueriesList": [],
"queries": { "queries": {
"getLogEvents": "50" "getLogEvents": "50",
"getEthLogs": "50",
"getEthBlock": "50"
}, },
"mutations": {} "mutations": {}
} }

View File

@ -7,11 +7,16 @@ fi
erc20_address_file="/app/deployment/erc20-address.json" erc20_address_file="/app/deployment/erc20-address.json"
# Check and exit if a deployment already exists (on restarts) echo ETH_RPC_URL=${CERC_ETH_RPC_ENDPOINT} > .env
echo ACCOUNT_PRIVATE_KEY=${CERC_PRIVATE_KEY_DEPLOYER} >> .env
# Check and keep container running if a deployment already exists (on restarts)
if [ -f ${erc20_address_file} ]; then if [ -f ${erc20_address_file} ]; then
echo "${erc20_address_file} already exists, skipping ERC20 contract deployment" echo "${erc20_address_file} already exists, skipping ERC20 contract deployment"
cat ${erc20_address_file} cat ${erc20_address_file}
exit
# Keep the container running
tail -f
fi fi
wait_for_chain_endpoint() { wait_for_chain_endpoint() {
@ -46,8 +51,6 @@ wait_for_chain_endpoint
echo "Using CERC_PRIVATE_KEY_DEPLOYER from env" echo "Using CERC_PRIVATE_KEY_DEPLOYER from env"
echo ETH_RPC_URL=${CERC_ETH_RPC_ENDPOINT} > .env
echo ACCOUNT_PRIVATE_KEY=${CERC_PRIVATE_KEY_DEPLOYER} >> .env
yarn token:deploy:docker --file ${erc20_address_file} yarn token:deploy:docker --file ${erc20_address_file}
# Keep the container running # Keep the container running

View File

@ -35,7 +35,7 @@ export const config: Config = {
network: "fixturenet", network: "fixturenet",
abi: "./abis/AdventureGold.json", abi: "./abis/AdventureGold.json",
address: process.env.ERC20_CONTRACT, address: process.env.ERC20_CONTRACT,
startBlock: 5, startBlock: 1,
maxBlockRange: 100, maxBlockRange: 100,
}, },
], ],

View File

@ -0,0 +1,64 @@
import { type Config, AppMode } from "@ponder/core";
import contractAddresses from "./nitro-addresses.json" assert { type: "json" };
export const config: Config = {
networks: [
{
name: "fixturenet",
chainId: Number(process.env.PONDER_CHAIN_ID),
indexerUrl: process.env.INDEXER_GQL_ENDPOINT,
maxRpcRequestConcurrency: 1,
pollingInterval: 5000,
payments: {
nitro: {
address: process.env.INDEXER_NITRO_ADDRESS!,
fundingAmounts: {
// TODO: Pass amounts from env
directFund: "1000000000000",
virtualFund: "1000000000",
},
},
paidRPCMethods: [
"eth_getLogs",
"eth_getBlockByNumber",
"eth_getBlockByHash",
],
amount: process.env.UPSTREAM_NITRO_PAY_AMOUNT!,
},
},
],
contracts: [
{
name: "AdventureGold",
network: "fixturenet",
abi: "./abis/AdventureGold.json",
address: process.env.ERC20_CONTRACT,
startBlock: 1,
maxBlockRange: 100,
},
],
options: {
mode: AppMode.Indexer,
},
nitro: {
privateKey: process.env.PONDER_NITRO_PK!,
chainPrivateKey: process.env.PONDER_NITRO_CHAIN_PK!,
chainUrl: process.env.PONDER_NITRO_CHAIN_URL!,
contractAddresses,
relayMultiAddr: process.env.RELAY_MULTIADDR!,
store: "./.ponder/nitro-db",
payments: {
cache: {
maxAccounts: 1000,
accountTTLInSecs: 1800,
maxVouchersPerAccount: 1000,
voucherTTLInSecs: 300,
maxPaymentChannels: 10000,
paymentChannelTTLInSecs: 1800,
},
ratesFile: "./base-rates-config.json",
requestTimeoutInSecs: 10,
},
},
};

View File

@ -15,7 +15,7 @@ export const config: Config = {
network: "fixturenet", network: "fixturenet",
abi: "./abis/AdventureGold.json", abi: "./abis/AdventureGold.json",
address: process.env.ERC20_CONTRACT, address: process.env.ERC20_CONTRACT,
startBlock: 5, startBlock: 1,
maxBlockRange: 100, maxBlockRange: 100,
}, },
], ],

View File

@ -29,7 +29,7 @@ laconic-so --stack fixturenet-payments deploy --cluster payments up
# 32***: geth in statediffing mode and ipld-eth-server(s) # 32***: geth in statediffing mode and ipld-eth-server(s)
# 4005: in-process go-nitro node's RPC endpoint # 4005: in-process go-nitro node's RPC endpoint
# 3005: in-process go-nitro node's p2p TCP endpoint # 3005: in-process go-nitro node's p2p TCP endpoint
# 5005: in-process go-nitro node's p2p WS endpoin # 5005: in-process go-nitro node's p2p WS endpoint
# 4006: out-of-process go-nitro node's RPC endpoint # 4006: out-of-process go-nitro node's RPC endpoint
# 3006: out-of-process go-nitro node's p2p TCP endpoint # 3006: out-of-process go-nitro node's p2p TCP endpoint
# 5006: out-of-process go-nitro node's p2p WS endpoint # 5006: out-of-process go-nitro node's p2p WS endpoint
@ -38,7 +38,9 @@ laconic-so --stack fixturenet-payments deploy --cluster payments up
# 9090: MobyMask v3 watcher relay node endpoint # 9090: MobyMask v3 watcher relay node endpoint
# 8080: MobyMask snap # 8080: MobyMask snap
# 3004: MobyMask v3 app # 3004: MobyMask v3 app
# 32***: geth with statediffing # 42070: Ponder indexer-1
# 42071: Ponder indexer-2
# 42069: Ponder watcher
``` ```
If running in the cloud, ensure all the of the above ports are open. The geth port can be retrieved with: If running in the cloud, ensure all the of the above ports are open. The geth port can be retrieved with:
@ -60,7 +62,8 @@ This will allow you to access the entirety of the app as if it were running loca
## Demo ## Demo
Follow the [demo](./demo.md) to try out end-to-end payments. - Follow the [mobymask-demo](./mobymask-demo.md) to try out MobyMask end-to-end payments.
- Follow the [ponder-demo](./ponder-demo.md) to try out Ponder end-to-end payments.
## Clean up ## Clean up

View File

@ -3,13 +3,10 @@
Stack components: Stack components:
* `ipld-eth-db` database for statediffed data * `ipld-eth-db` database for statediffed data
* Local geth + lighthouse blockchain "fixturenet" running in statediffing mode * Local geth + lighthouse blockchain "fixturenet" running in statediffing mode
* `ipld-eth-server-1` and `ipld-eth-server-2` both of which run an ETH RPC API and a GQL server; they both serve data from `ipld-eth-db` * `ipld-eth-server-1` which runs an ETH RPC API and a GQL server; they both serve data from `ipld-eth-db`
* `ipld-eth-server-1` runs an in-process go-nitro node for payments required for configured RPC requests * It runs an in-process go-nitro node for payments required for configured RPC requests
* A go-nitro deployment acting as the remote Nitro node for `ipld-eth-server-2`
* A MobyMask v3 watcher that pays the `ipld-eth-server-1` for ETH RPC requests * A MobyMask v3 watcher that pays the `ipld-eth-server-1` for ETH RPC requests
* A MobyMask v3 app that pays the watcher for reads (GQL queries) and writes * A MobyMask v3 app that pays the watcher for reads (GQL queries) and writes
* An example ERC20 Ponder indexer app that pays the `ipld-eth-server-2` for ETH RPC requests
* An example ERC20 Ponder watcher app that pays the Ponder indexer app for GQL queries
## Setup ## Setup
@ -61,12 +58,6 @@ Stack components:
docker logs -f $(docker ps -aq --filter name="ipld-eth-server-1") docker logs -f $(docker ps -aq --filter name="ipld-eth-server-1")
``` ```
* In another terminal, check `ipld-eth-server-2`'s logs to keep track of incoming RPC requests from the Ponder app in indexer mode:
```bash
docker logs -f $(docker ps -aq --filter name="ipld-eth-server-2")
```
* MetaMask flask wallet setup for running the MobyMask app: * MetaMask flask wallet setup for running the MobyMask app:
* Get the geth nodes port mapped to host: * Get the geth nodes port mapped to host:
@ -213,96 +204,6 @@ Stack components:
# } # }
``` ```
### ERC20 Ponder App
* Run the ponder app in indexer mode:
```bash
docker exec -it payments-ponder-app-indexer-1 bash -c "DEBUG=laconic:payments pnpm start"
# Expected output:
# 08:00:28.701 INFO payment Nitro node setup with address 0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d
# laconic:payments Starting voucher subscription... +0ms
# ...
# 09:58:54.288 INFO payment Creating ledger channel with nitro node 0x660a4bEF3fbC863Fcd8D3CDB39242aE513d7D92e
# ...
# 09:59:14.230 INFO payment Creating payment channel with nitro node 0x660a4bEF3fbC863Fcd8D3CDB39242aE513d7D92e
# ...
# 09:59:14.329 INFO payment Using payment channel 0x10f049519bc3f862e2b26e974be8666886228f30ea54aab06e2f23718afffab0
```
* Export the payment channel id to a variable:
```bash
export PONDER_UPSTREAM_PAYMENT_CHANNEL=<PAYMENT_CHANNEL_ID>
```
* On starting the Ponder app in indexer mode, it creates a payment channel with the `ipld-eth-server-2`'s (external) Nitro node and then starts the historical sync service
* The sync service makes several ETH RPC requests to the `ipld-eth-server-2` to fetch required data; check the `ipld-eth-server-2` logs for charged RPC requests (`eth_getBlockByNumber`, `eth_getLogs`):
```bash
# Expected output:
# ...
# 2023/10/18 05:29:38 INFO Serving a paid RPC request method=eth_getBlockByNumber cost=50 sender=0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d
# time="2023-10-18T05:29:38Z" level=debug msg=START api_method=eth_getBlockByNumber api_params="[latest true]" api_reqid=0 conn="172.26.0.19:42306" user_id= uuid=54992dc3-6d77-11ee-9ede-0242ac1a000f
# WARN [10-18|05:29:38.292] Attempting GerRPCCalls, but default PluginLoader has not been initialized
# time="2023-10-18T05:29:38Z" level=debug msg=END api_method=eth_getBlockByNumber api_params="[latest true]" api_reqid=0 conn="172.26.0.19:42306" duration=22 user_id= uuid=54992dc3-6d77-11ee-9ede-0242ac1a000f
# time="2023-10-18T05:29:40Z" level=debug msg=START api_method=eth_getLogs api_params="[map[address:0x32353a6c91143bfd6c7d363b546e62a9a2489a20 fromBlock:0x5 toBlock:0x68]]" api_reqid=1 conn="172.26.0.19:42306" user_id= uuid=55d19200-6d77-11ee-9ede-0242ac1a000f
# 2023/10/18 05:29:40 INFO Serving a paid RPC request method=eth_getLogs cost=50 sender=0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d
# WARN [10-18|05:29:40.340] Attempting GerRPCCalls, but default PluginLoader has not been initialized
# time="2023-10-18T05:29:40Z" level=debug msg="retrieving log cids for receipt ids"
# time="2023-10-18T05:29:40Z" level=debug msg=END api_method=eth_getLogs api_params="[map[address:0x32353a6c91143bfd6c7d363b546e62a9a2489a20 fromBlock:0x5 toBlock:0x68]]" api_reqid=1 conn="172.26.0.19:42306" duration=20 user_id= uuid=55d19200-6d77-11ee-9ede-0242ac1a000f
# ...
```
* Check the ponder - ipld-eth-server-2 payment channel status:
```bash
docker exec payments-nitro-rpc-client-1 npm exec -c "nitro-rpc-client get-payment-channel $PONDER_UPSTREAM_PAYMENT_CHANNEL -s false -h go-nitro -p 4006"
# Expected output ('PaidSoFar' is non zero):
# {
# ID: '0x1178ac0f2a43e54a122216fa6afdd30333b590e49e50317a1f9274a591da0f96',
# Status: 'Open',
# Balance: {
# AssetAddress: '0x0000000000000000000000000000000000000000',
# Payee: '0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce',
# Payer: '0x67d5b55604d1af90074fcb69b8c51838fff84f8d',
# PaidSoFar: 215000n,
# RemainingFunds: 999785000n
# }
# }
```
* In another terminal run the ponder app in watcher mode:
```bash
docker exec -it payments-ponder-app-watcher-1 bash -c "DEBUG=laconic:payments pnpm start"
# Expected output:
# 11:23:22.057 DEBUG app Started using config file: ponder.config.ts
# 08:02:12.548 INFO payment Nitro node setup with address 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db
# laconic:payments Starting voucher subscription... +0ms
# 08:02:17.417 INFO payment Creating ledger channel with nitro node 0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d ...
# 08:02:37.135 INFO payment Creating payment channel with nitro node 0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d ...
# 08:02:37.313 INFO payment Using payment channel 0x4b8e67f6a6fcfe114fdd60b85f963344ece4c77d4eea3825688c74b45ff5509b
# ...
# 11:23:22.436 INFO server Started responding as healthy
```
* Check the terminal in which ponder is running in indexer mode. Logs of payment for `eth_getLogs` queries can be seen:
```bash
# ...
# 08:02:37.763 DEBUG realtime Finished processing new head block 89 (network=fixturenet)
# laconic:payments Received a payment voucher of 50 from 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db +444ms
# laconic:payments Serving a paid query for 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db +1ms
# 08:02:37.804 DEBUG payment Verified payment for GQL queries getLogEvents
# laconic:payments Received a payment voucher of 50 from 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db +45ms
# laconic:payments Serving a paid query for 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db +0ms
# 08:02:37.849 DEBUG payment Verified payment for GQL queries getLogEvents
```
## Clean Up ## Clean Up

View File

@ -0,0 +1,182 @@
# Demo
Stack components:
* `ipld-eth-db` database for statediffed data
* Local geth + lighthouse blockchain "fixturenet" running in statediffing mode
* `ipld-eth-server-2` which runs an ETH RPC API and a GQL server; they both serve data from `ipld-eth-db`
* A go-nitro deployment acting as the remote Nitro node for `ipld-eth-server-2`
* Example ERC20 Ponder apps
* `ponder-app-indexer-1` that pays the `ipld-eth-server-2` for ETH RPC requests
* `ponder-app-indexer-2` that pays `ponder-app-indexer-1` for GQL queries
* `ponder-app-watcher` that pays `ponder-app-indexer-2` for GQL queries
## Setup
* In a terminal, check `ipld-eth-server-2`'s logs to keep track of incoming RPC requests from the `ponder-app-indexer-1`:
```bash
docker logs -f $(docker ps -aq --filter name="ipld-eth-server-2")
```
## Run
### ERC20 Ponder App
* Run the first indexer Ponder app:
```bash
docker exec -it payments-ponder-app-indexer-1-1 bash -c "DEBUG=laconic:payments pnpm start"
# Expected output:
# 12:57:03.751 INFO payment Nitro node setup with address 0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d
# laconic:payments Starting voucher subscription... +0ms
# ...
# 09:58:54.288 INFO payment Creating ledger channel with nitro node 0x660a4bEF3fbC863Fcd8D3CDB39242aE513d7D92e ...
# 09:59:14.230 INFO payment Creating payment channel with nitro node 0x660a4bEF3fbC863Fcd8D3CDB39242aE513d7D92e ...
# 09:59:14.329 INFO payment Using payment channel 0x1ff59db391b7a55bed723b930ab53c80e7ce857487c1e58771aa5a0737d71625
```
* Export the payment channel id to a variable:
```bash
export PONDER_UPSTREAM_PAYMENT_CHANNEL=<PAYMENT_CHANNEL_ID>
```
* On starting the Ponder app in indexer mode, it creates a payment channel with the `ipld-eth-server-2`'s (external) Nitro node and then starts the historical sync service
* The sync service makes several ETH RPC requests to the `ipld-eth-server-2` to fetch required data; check the `ipld-eth-server-2` logs for charged RPC requests (`eth_getBlockByNumber`, `eth_getLogs`):
```bash
# Expected output:
# ...
# 2023/10/18 05:29:38 INFO Serving a paid RPC request method=eth_getBlockByNumber cost=50 sender=0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d
# time="2023-10-18T05:29:38Z" level=debug msg=START api_method=eth_getBlockByNumber api_params="[latest true]" api_reqid=0 conn="172.26.0.19:42306" user_id= uuid=54992dc3-6d77-11ee-9ede-0242ac1a000f
# WARN [10-18|05:29:38.292] Attempting GerRPCCalls, but default PluginLoader has not been initialized
# time="2023-10-18T05:29:38Z" level=debug msg=END api_method=eth_getBlockByNumber api_params="[latest true]" api_reqid=0 conn="172.26.0.19:42306" duration=22 user_id= uuid=54992dc3-6d77-11ee-9ede-0242ac1a000f
# ...
# 2023/10/18 05:29:40 INFO Serving a paid RPC request method=eth_getLogs cost=50 sender=0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d
# WARN [10-18|05:29:40.340] Attempting GerRPCCalls, but default PluginLoader has not been initialized
# time="2023-10-18T05:29:40Z" level=debug msg="retrieving log cids for receipt ids"
# ...
```
* Check the Ponder - ipld-eth-server-2 payment channel status:
```bash
docker exec payments-nitro-rpc-client-1 npm exec -c "nitro-rpc-client get-payment-channel $PONDER_UPSTREAM_PAYMENT_CHANNEL -s false -h go-nitro -p 4006"
# Expected output ('PaidSoFar' is non zero):
# {
# ID: '0x1ff59db391b7a55bed723b930ab53c80e7ce857487c1e58771aa5a0737d71625',
# Status: 'Open',
# Balance: {
# AssetAddress: '0x0000000000000000000000000000000000000000',
# Payee: '0x660a4bef3fbc863fcd8d3cdb39242ae513d7d92e',
# Payer: '0x67d5b55604d1af90074fcb69b8c51838fff84f8d',
# PaidSoFar: 7200n,
# RemainingFunds: 999992800n
# }
# }
```
* In another terminal run the second indexer Ponder app:
```bash
docker exec -it payments-ponder-app-indexer-2-1 bash -c "DEBUG=laconic:payments pnpm start"
# Expected output:
# 08:00:28.701 INFO payment Nitro node setup with address 0xB2B22ec3889d11f2ddb1A1Db11e80D20EF367c01
# laconic:payments Starting voucher subscription... +0ms
# ...
# 09:58:54.288 INFO payment Creating ledger channel with nitro node 0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d ...
# 09:59:14.230 INFO payment Creating payment channel with nitro node 0x67D5b55604d1aF90074FcB69b8C51838FFF84f8d ...
# 09:59:14.329 INFO payment Using payment channel 0xfbf9d7eb7c18446883c7f57f4c94db5607f414a224b3e921c787db07371d2a70
```
* On starting indexer Ponder app, it creates a payment channel with first indexer and then starts the sync services
* Check logs in `ponder-indexer-1` to see payments made from `ponder-indexer-2` from GQL queries to fetch network data
```bash
# ...
# laconic:payments Received a payment voucher of 100 from 0xB2B22ec3889d11f2ddb1A1Db11e80D20EF367c01 +23ms
# laconic:payments Serving a paid query for 0xB2B22ec3889d11f2ddb1A1Db11e80D20EF367c01 +0ms
# 13:01:05.671 DEBUG payment Verified payment for GQL queries getEthLogs
# laconic:payments Received a payment voucher of 100 from 0xB2B22ec3889d11f2ddb1A1Db11e80D20EF367c01 +20ms
# laconic:payments Serving a paid query for 0xB2B22ec3889d11f2ddb1A1Db11e80D20EF367c01 +0ms
# 13:01:05.691 DEBUG payment Verified payment for GQL queries getEthBlock
# 13:01:07.598 INFO realtime Fetched missing blocks [686, 687] (network=fixturenet)
# 13:01:07.598 DEBUG realtime Started processing new head block 686 (network=fixturenet)
# ...
```
* In another terminal run the Ponder app in watcher mode:
```bash
docker exec -it payments-ponder-app-watcher-1 bash -c "DEBUG=laconic:payments pnpm start"
# Expected output:
# 11:23:22.057 DEBUG app Started using config file: ponder.config.ts
# 08:02:12.548 INFO payment Nitro node setup with address 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db
# laconic:payments Starting voucher subscription... +0ms
# 08:02:17.417 INFO payment Creating ledger channel with nitro node 0xB2B22ec3889d11f2ddb1A1Db11e80D20EF367c01 ...
# 08:02:37.135 INFO payment Creating payment channel with nitro node 0xB2B22ec3889d11f2ddb1A1Db11e80D20EF367c01 ...
# 08:02:37.313 INFO payment Using payment channel 0xc48622577dfa389283beb19ed946274eb034587d72e61445dc997304be671f1a
# ...
# 11:23:22.436 INFO server Started responding as healthy
```
* Check the terminal of the second indexer Ponder app. Logs of payment for `getLogEvents` queries can be seen:
```bash
# ...
# 08:02:37.763 DEBUG realtime Finished processing new head block 89 (network=fixturenet)
# laconic:payments Received a payment voucher of 50 from 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db +444ms
# laconic:payments Serving a paid query for 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db +1ms
# 08:02:37.804 DEBUG payment Verified payment for GQL queries getLogEvents
# laconic:payments Received a payment voucher of 50 from 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db +45ms
# laconic:payments Serving a paid query for 0x111A00868581f73AB42FEEF67D235Ca09ca1E8db +0ms
# 08:02:37.849 DEBUG payment Verified payment for GQL queries getLogEvents
```
* Open watcher Ponder app endpoint http://localhost:42069
* Try GQL query to see transfer events
```graphql
{
transferEvents (orderBy: "timestamp", orderDirection: "desc") {
id
amount
from {
id
}
to {
id
}
timestamp
}
}
```
* Transfer an ERC20 token on chain
* Get the deployed ERC20 token address
```bash
export TOKEN_ADDRESS=$(docker exec payments-ponder-er20-contracts-1 jq -r '.address' ./deployment/erc20-address.json)
```
* Transfer token
```bash
docker exec -it payments-ponder-er20-contracts-1 bash -c "yarn token:transfer:docker --token ${TOKEN_ADDRESS} --to 0xe22AD83A0dE117bA0d03d5E94Eb4E0d80a69C62a --amount 5000"
```
* Wait for a log in watcher Ponder app
```bash
06:40:47.567 INFO handlers Processed 1 event (up to Oct 19, 2023)
```
* Check the GQL query again in http://localhost:42069 to see a new `TransferEvent` entity

View File

@ -10,7 +10,7 @@ repos:
- git.vdb.to/cerc-io/ipld-eth-server@payments - git.vdb.to/cerc-io/ipld-eth-server@payments
# nitro repo # nitro repo
- github.com/cerc-io/ts-nitro@v0.1.15 - github.com/cerc-io/ts-nitro@v0.1.15
- github.com/cerc-io/go-nitro@ts-interop # TODO: Use release - github.com/cerc-io/go-nitro@v0.1.2-ts-port-0.1.9
# mobymask watcher repos # mobymask watcher repos
- github.com/cerc-io/watcher-ts@v0.2.66 - github.com/cerc-io/watcher-ts@v0.2.66
# this is mobymask-v3 # this is mobymask-v3
@ -55,4 +55,5 @@ pods:
- watcher-mobymask-v3 - watcher-mobymask-v3
- mobymask-snap - mobymask-snap
- mobymask-app-v3 - mobymask-app-v3
- ponder - ponder-indexer
- ponder-watcher