From 44fb4079710358d01ab7b134f4b9f7b352401ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emanuel=20Tesa=C5=99?= Date: Mon, 11 Dec 2023 14:38:14 +0100 Subject: [PATCH] Rename Pusher to Airnode feed (#150) --- local-test-configuration/README.md | 20 +++---- .../{pusher-1 => airnode-feed-1}/.env.example | 0 .../airnode-feed.json} | 0 .../secrets.example.env | 0 .../{pusher-2 => airnode-feed-2}/.env.example | 0 .../airnode-feed.json} | 0 .../secrets.example.env | 0 .../scripts/initialize-chain.ts | 58 ++++++++++--------- 8 files changed, 41 insertions(+), 37 deletions(-) rename local-test-configuration/{pusher-1 => airnode-feed-1}/.env.example (100%) rename local-test-configuration/{pusher-1/pusher.json => airnode-feed-1/airnode-feed.json} (100%) rename local-test-configuration/{pusher-1 => airnode-feed-1}/secrets.example.env (100%) rename local-test-configuration/{pusher-2 => airnode-feed-2}/.env.example (100%) rename local-test-configuration/{pusher-2/pusher.json => airnode-feed-2/airnode-feed.json} (100%) rename local-test-configuration/{pusher-2 => airnode-feed-2}/secrets.example.env (100%) diff --git a/local-test-configuration/README.md b/local-test-configuration/README.md index ef2a474a..5c3eebda 100644 --- a/local-test-configuration/README.md +++ b/local-test-configuration/README.md @@ -1,11 +1,11 @@ # Local Airseeker test -The idea is to use the Docker images for Pusher, Signed API and Airseeker and run them locally. Specifically, this is -the setup: +The idea is to use the Docker images for Airnode feed, Signed API and Airseeker and run them locally. Specifically, this +is the setup: -- Use 2 pushers with Nodary API and reasonable fetch limits. Each pusher has a different Airnode mnemonic to mimic a - different API. One of the APIs is delayed so that the beacons have different values. -- Use 2 signed APIs and each Pusher pushes to a separate Signed API. +- Use 2 Airnode feeds with Nodary API and reasonable fetch limits. Each Airnode feed has a different Airnode mnemonic to + mimic a different API. One of the APIs is delayed so that the beacons have different values. +- Use 2 signed APIs and each Airnode feed pushes to a separate Signed API. - We run Airseeker only on Hardhat network for setup simplicity. Initially, I wanted to have a Polygon testnet as well, but gave up on that idea for now. The setup can be easily extended to run on any chain, just by not starting Hardhat network and using a different RPCs. @@ -19,7 +19,7 @@ assets from the Nodary API to see Airseeker updates. missing secrets. Some of the secrets are the deployed contract addresses, which you'll get by following the next instructions. -- Build all of the Docker containers. Do build containers for Pusher and Signed API you need to run +- Build all of the Docker containers. Do build containers for Airnode feed and Signed API you need to run [this command](https://github.com/api3dao/signed-api/blob/0bad6fc8dd6aaffaa12cf099ab6bbf7c98d487c8/package.json#L11) from the signed-api repository. For Airseeker, you can run `pnpm docker:build` from the root of this repository. @@ -37,16 +37,16 @@ docker run --publish 4002:80 -it --init --volume $(pwd)/local-test-configuration You can go to `http://localhost:4001/` and `http://localhost:4002/` to see the Signed API 1 and 2 respectively. -- Start Pusher 1 (in a separate terminal): +- Start Airnode feed 1 (in a separate terminal): ```sh -docker run -it --init --volume $(pwd)/local-test-configuration/pusher-1:/app/config --network host --env-file ./local-test-configuration/pusher-1/.env --rm --memory=256m api3/pusher:latest +docker run -it --init --volume $(pwd)/local-test-configuration/airnode-feed-1:/app/config --network host --env-file ./local-test-configuration/airnode-feed-1/.env --rm --memory=256m api3/airnode-feed:latest ``` -- Start Pusher 2 (in a separate terminal): +- Start Airnode feed 2 (in a separate terminal): ```sh -docker run -it --init --volume $(pwd)/local-test-configuration/pusher-2:/app/config --network host --env-file ./local-test-configuration/pusher-2/.env --rm --memory=256m api3/pusher:latest +docker run -it --init --volume $(pwd)/local-test-configuration/airnode-feed-2:/app/config --network host --env-file ./local-test-configuration/airnode-feed-2/.env --rm --memory=256m api3/airnode-feed:latest ``` - Start Hardhat node (in a separate terminal): diff --git a/local-test-configuration/pusher-1/.env.example b/local-test-configuration/airnode-feed-1/.env.example similarity index 100% rename from local-test-configuration/pusher-1/.env.example rename to local-test-configuration/airnode-feed-1/.env.example diff --git a/local-test-configuration/pusher-1/pusher.json b/local-test-configuration/airnode-feed-1/airnode-feed.json similarity index 100% rename from local-test-configuration/pusher-1/pusher.json rename to local-test-configuration/airnode-feed-1/airnode-feed.json diff --git a/local-test-configuration/pusher-1/secrets.example.env b/local-test-configuration/airnode-feed-1/secrets.example.env similarity index 100% rename from local-test-configuration/pusher-1/secrets.example.env rename to local-test-configuration/airnode-feed-1/secrets.example.env diff --git a/local-test-configuration/pusher-2/.env.example b/local-test-configuration/airnode-feed-2/.env.example similarity index 100% rename from local-test-configuration/pusher-2/.env.example rename to local-test-configuration/airnode-feed-2/.env.example diff --git a/local-test-configuration/pusher-2/pusher.json b/local-test-configuration/airnode-feed-2/airnode-feed.json similarity index 100% rename from local-test-configuration/pusher-2/pusher.json rename to local-test-configuration/airnode-feed-2/airnode-feed.json diff --git a/local-test-configuration/pusher-2/secrets.example.env b/local-test-configuration/airnode-feed-2/secrets.example.env similarity index 100% rename from local-test-configuration/pusher-2/secrets.example.env rename to local-test-configuration/airnode-feed-2/secrets.example.env diff --git a/local-test-configuration/scripts/initialize-chain.ts b/local-test-configuration/scripts/initialize-chain.ts index 6a19c97b..71d18655 100644 --- a/local-test-configuration/scripts/initialize-chain.ts +++ b/local-test-configuration/scripts/initialize-chain.ts @@ -90,9 +90,9 @@ const joinUrl = (url: string, path: string) => { return new URL(path, url).href; }; -const loadPusherConfig = (pusherDir: 'pusher-1' | 'pusher-2') => { - const configPath = join(__dirname, `/../`, pusherDir); - const rawConfig = JSON.parse(readFileSync(join(configPath, 'pusher.json'), 'utf8')); +const loadAirnodeFeedConfig = (airnodeFeedDir: 'airnode-feed-1' | 'airnode-feed-2') => { + const configPath = join(__dirname, `/../`, airnodeFeedDir); + const rawConfig = JSON.parse(readFileSync(join(configPath, 'airnode-feed.json'), 'utf8')); const rawSecrets = dotenv.parse(readFileSync(join(configPath, 'secrets.env'), 'utf8')); const secrets = parseSecrets(rawSecrets); @@ -100,13 +100,13 @@ const loadPusherConfig = (pusherDir: 'pusher-1' | 'pusher-2') => { }; const getBeaconSetNames = () => { - const pusher = loadPusherConfig('pusher-1'); - const pusherWallet = ethers.Wallet.fromMnemonic(pusher.nodeSettings.airnodeWalletMnemonic); - const pusherBeacons = Object.values(pusher.templates).map((template: any) => { - return deriveBeaconData({ ...template, airnodeAddress: pusherWallet.address }); + const airnodeFeed = loadAirnodeFeedConfig('airnode-feed-1'); + const airnodeFeedWallet = ethers.Wallet.fromMnemonic(airnodeFeed.nodeSettings.airnodeWalletMnemonic); + const airnodeFeedBeacons = Object.values(airnodeFeed.templates).map((template: any) => { + return deriveBeaconData({ ...template, airnodeAddress: airnodeFeedWallet.address }); }); - return pusherBeacons.map((beacon) => beacon.parameters[0]!.value); + return airnodeFeedBeacons.map((beacon) => beacon.parameters[0]!.value); }; export const fundAirseekerSponsorWallet = async (funderWallet: ethers.Wallet) => { @@ -210,28 +210,32 @@ export const deploy = async (funderWallet: ethers.Wallet, provider: ethers.provi await tx.wait(); // Create templates - const pusher1 = loadPusherConfig('pusher-1'); - const pusher2 = loadPusherConfig('pusher-2'); - const pusher1Wallet = ethers.Wallet.fromMnemonic(pusher1.nodeSettings.airnodeWalletMnemonic).connect(provider); - const pusher2Wallet = ethers.Wallet.fromMnemonic(pusher2.nodeSettings.airnodeWalletMnemonic).connect(provider); - const pusher1Beacons = Object.values(pusher1.templates).map((template: any) => { - return deriveBeaconData({ ...template, airnodeAddress: pusher1Wallet.address }); + const airnodeFeed1 = loadAirnodeFeedConfig('airnode-feed-1'); + const airnodeFeed2 = loadAirnodeFeedConfig('airnode-feed-2'); + const airnodeFeed1Wallet = ethers.Wallet.fromMnemonic(airnodeFeed1.nodeSettings.airnodeWalletMnemonic).connect( + provider + ); + const airnodeFeed2Wallet = ethers.Wallet.fromMnemonic(airnodeFeed2.nodeSettings.airnodeWalletMnemonic).connect( + provider + ); + const airnodeFeed1Beacons = Object.values(airnodeFeed1.templates).map((template: any) => { + return deriveBeaconData({ ...template, airnodeAddress: airnodeFeed1Wallet.address }); }); - const pusher2Beacons = Object.values(pusher2.templates).map((template: any) => { - return deriveBeaconData({ ...template, airnodeAddress: pusher2Wallet.address }); + const airnodeFeed2Beacons = Object.values(airnodeFeed2.templates).map((template: any) => { + return deriveBeaconData({ ...template, airnodeAddress: airnodeFeed2Wallet.address }); }); // Derive beacon set IDs and names - const beaconSetIds = zip(pusher1Beacons, pusher2Beacons).map(([beacon1, beacon2]) => + const beaconSetIds = zip(airnodeFeed1Beacons, airnodeFeed2Beacons).map(([beacon1, beacon2]) => ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(['bytes32[]'], [[beacon1!.beaconId, beacon2!.beaconId]])) ); - const beaconSetNames = pusher1Beacons.map((beacon) => beacon.parameters[0]!.value); + const beaconSetNames = airnodeFeed1Beacons.map((beacon) => beacon.parameters[0]!.value); // Register merkle tree hashes const timestamp = Math.floor(Date.now() / 1000); const apiTreeValues = [ - [pusher1Wallet.address, joinUrl(pusher1.signedApis[0].url, 'default')], // NOTE: Pusher pushes to the "/" of the signed API, but we need to query it additional path. - [pusher2Wallet.address, joinUrl(pusher2.signedApis[0].url, 'default')], // NOTE: Pusher pushes to the "/" of the signed API, but we need to query it additional path. + [airnodeFeed1Wallet.address, joinUrl(airnodeFeed1.signedApis[0].url, 'default')], // NOTE: Airnode feed pushes to the "/" of the signed API, but we need to query it additional path. + [airnodeFeed2Wallet.address, joinUrl(airnodeFeed2.signedApis[0].url, 'default')], // NOTE: Airnode feed pushes to the "/" of the signed API, but we need to query it additional path. ] as const; const apiTree = StandardMerkleTree.of(apiTreeValues as any, ['address', 'string']); const apiHashType = ethers.utils.solidityKeccak256(['string'], ['Signed API URL Merkle tree root']); @@ -288,10 +292,10 @@ export const deploy = async (funderWallet: ethers.Wallet, provider: ethers.provi .registerAirnodeSignedApiUrl(airnode, url, apiTreeRoot, apiTreeProof); await tx.wait(); } - const dapiInfos = zip(pusher1Beacons, pusher2Beacons).map(([pusher1Beacon, pusher2Beacon], i) => { + const dapiInfos = zip(airnodeFeed1Beacons, airnodeFeed2Beacons).map(([airnodeFeed1Beacon, airnodeFeed2Beacon], i) => { return { - airnodes: [pusher1Beacon!.airnodeAddress, pusher2Beacon!.airnodeAddress], - templateIds: [pusher1Beacon!.templateId, pusher1Beacon!.templateId], + airnodes: [airnodeFeed1Beacon!.airnodeAddress, airnodeFeed2Beacon!.airnodeAddress], + templateIds: [airnodeFeed1Beacon!.templateId, airnodeFeed1Beacon!.templateId], dapiTreeValue: dapiTreeValues[i]!, }; }); @@ -329,11 +333,11 @@ export const deploy = async (funderWallet: ethers.Wallet, provider: ethers.provi api3ServerV1, dapiDataRegistry, - pusher1Wallet, - pusher2Wallet, + airnodeFeed1Wallet, + airnodeFeed2Wallet, - pusher1Beacons, - pusher2Beacons, + airnodeFeed1Beacons, + airnodeFeed2Beacons, beaconSetNames, }; };