Skip to content

Commit

Permalink
ecs for other liquidator bots and fixed all the other errors includin…
Browse files Browse the repository at this point in the history
…g upstack err
  • Loading branch information
amish kohli authored and amish kohli committed Nov 13, 2024
1 parent 720f428 commit 641cd2c
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 36 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/deploy-bots.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ jobs:

- name: Build, tag, and push docker image to Amazon ECR Public
run: |
docker build --build-arg UPTIME_PYTH_UPDATER_API=${{ secrets.UPTIME_PYTH_UPDATER_API }} -f docker/pyth-updater/Dockerfile -t $REGISTRY/$REPOSITORY:$IMAGE_TAG -t ghcr.io/ionicprotocol/$REPOSITORY:$IMAGE_TAG .
docker build --build-arg UPTIME_PYTH_UPDATER_API=${{ secrets.UPTIME_PYTH_UPDATER_API }} -f docker/pyth-updater-ecs/Dockerfile -t $REGISTRY/$REPOSITORY:$IMAGE_TAG -t ghcr.io/ionicprotocol/$REPOSITORY:$IMAGE_TAG .
docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
docker push ghcr.io/ionicprotocol/$REPOSITORY:$IMAGE_TAG
Expand Down Expand Up @@ -336,6 +336,7 @@ jobs:
UPTIME_PYTH_UPDATER_API: ${{ secrets.UPTIME_PYTH_UPDATER_API }}
MODE_MAINNET_RPC_URLS: ${{ secrets.MODE_MAINNET_RPC_URLS }}
BASE_MAINNET_RPC_URLS: ${{ secrets.BASE_MAINNET_RPC_URLS }}
OPTIMISM_MAINNET_RPC_URLS: ${{ secrets.OPTIMISM_MAINNET_RPC_URLS }}

steps:
- name: Checkout repository
Expand Down Expand Up @@ -392,6 +393,7 @@ jobs:
SENDGRID_EMAIL_TO: ${{ secrets.SENDGRID_EMAIL_TO}}
MODE_MAINNET_RPC_URLS: ${{ secrets.MODE_MAINNET_RPC_URLS }}
BASE_MAINNET_RPC_URLS: ${{ secrets.BASE_MAINNET_RPC_URLS }}
OPTIMISM_MAINNET_RPC_URLS: ${{ secrets.OPTIMISM_MAINNET_RPC_URLS }}
steps:
- name: Checkout
uses: actions/checkout@master
Expand Down
56 changes: 56 additions & 0 deletions docker/pyth-updater-ecs/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Base image: Use a standard Node.js image for ECS instead of Lambda-specific
FROM node:20 as build

# Install dependencies
RUN apt-get update && apt-get install -y git

# Enable Yarn and set the stable version
RUN corepack enable
RUN yarn set version stable

ENV HOME=/tmp/build \
PATH=/tmp/build/node_modules/.bin:./node_modules/.bin:${PATH}

WORKDIR /tmp/build

ARG TEMP_DEPS_DIR

ARG UPTIME_PYTH_UPDATER_API
ENV UPTIME_PYTH_UPDATER_API=$UPTIME_PYTH_UPDATER_API

# Copy necessary files to leverage Docker cache
COPY .yarn /tmp/build/.yarn/
COPY .yarnrc.yml /tmp/build/

COPY package.json /tmp/build/
COPY packages/sdk/package.json /tmp/build/packages/sdk/
COPY packages/types/package.json /tmp/build/packages/types/
COPY packages/chains/package.json /tmp/build/packages/chains/
COPY packages/bots/pyth-updater/package.json /tmp/build/packages/bots/pyth-updater/
COPY yarn.lock /tmp/build/

# Install dependencies
RUN yarn install --inline-builds --mode=skip-build

# Copy source code
COPY packages/sdk /tmp/build/packages/sdk
COPY packages/types /tmp/build/packages/types
COPY packages/chains /tmp/build/packages/chains
COPY packages/bots/pyth-updater /tmp/build/packages/bots/pyth-updater

# Build the project
RUN yarn build:deploy:pyth-updater

# Production stage
FROM node:20 as runtime

ENV NODE_ENV=production

# Set the working directory
WORKDIR /usr/src/app

# Copy the build from the previous stage
COPY --from=build /tmp/build /usr/src/app

# Command to run your bot in ECS
CMD ["node", "packages/bots/pyth-updater/build/src/run.js"]
2 changes: 2 additions & 0 deletions ops/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ prod-plan:
export TF_VAR_per_discord_webhook_url=${PER_DISCORD_WEBHOOK_URL} && \
export TF_VAR_discord_failure_webhook_url=${DISCORD_FAILURE_WEBHOOK_URL} && \
export TF_VAR_discord_success_webhook_url=${DISCORD_SUCCESS_WEBHOOK_URL} && \
export TF_VAR_optimism_mainnet_rpcs=${OPTIMISM_MAINNET_RPC_URLS} && \
export TF_VAR_lifi_api_key=${LIFIAPIKEY} && \
export TF_VAR_pyth_updater_discord_webhook_url=${PYTH_UPDATER_DISCORD_WEBHOOK_URL} && \
export TF_VAR_infura_api_key=${INFURA_API_KEY} && \
Expand All @@ -97,6 +98,7 @@ prod-deploy:
export TF_VAR_per_discord_webhook_url=${PER_DISCORD_WEBHOOK_URL} && \
export TF_VAR_discord_failure_webhook_url=${DISCORD_FAILURE_WEBHOOK_URL} && \
export TF_VAR_discord_success_webhook_url=${DISCORD_SUCCESS_WEBHOOK_URL} && \
export TF_VAR_optimism_mainnet_rpcs=${OPTIMISM_MAINNET_RPC_URLS} && \
export TF_VAR_lifi_api_key=${LIFIAPIKEY} && \
export TF_VAR_liquidation_sendgrid_api_key=${SENDGRID_API_KEY} && \
export TF_VAR_liquidation_sendgrid_email_to=${SENDGRID_EMAIL_TO} && \
Expand Down
25 changes: 24 additions & 1 deletion ops/prod/base.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ locals {



module "base_mainnet_liquidation_rpc_0" {
/*module "base_mainnet_liquidation_rpc_0" {
source = "../modules/lambda"
ecr_repository_name = local.liquidator_ecr_repository_name
docker_image_tag = var.bots_image_tag
Expand All @@ -20,4 +20,27 @@ module "base_mainnet_liquidation_rpc_0" {
schedule_expression = "rate(5 minutes)"
timeout = 700
memory_size = 512
}*/

module "base_mainnet_liquidator_ecs" {
source = "../modules/bot"

cluster_name = var.liquidator_cluster_name
task_definition_family = "${var.task_definition_family}-base"
ecr_repository_url = "${local.liquidator_ecr_repository_name}:${var.bots_image_tag}"
bots_image_tag = var.bots_image_tag
web3_http_provider_urls = local.base_mainnet_rpcs
target_chain_id = local.base_mainnet_chain_id
ethereum_admin_account = var.ethereum_admin_account
ethereum_admin_private_key = var.ethereum_admin_private_key
ecs_service_name = "${var.liquidator_service_name}-base"
desired_count = var.desired_count
liquidation_discord_webhook_url = var.liquidation_discord_webhook_url
discord_success_webhook_url = var.discord_success_webhook_url
discord_failure_webhook_url = var.discord_failure_webhook_url
lifi_api_key = var.lifi_api_key
subnet_ids = ["subnet-0cd439d262800846e"]
security_group_ids = ["sg-0a3996557af867ad0"]
region = var.region
liquidator_container_name = "${var.liquidator_container_name}-base"
}
2 changes: 1 addition & 1 deletion ops/prod/mode.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module "mode_mainnet_liquidator_ecs" {
source = "../modules/bot"

cluster_name = var.liquidator_cluster_name
task_definition_family = var.task_definition_family
task_definition_family = var.task_definition_family_mode
ecr_repository_url = "${local.liquidator_ecr_repository_name}:${var.bots_image_tag}"
bots_image_tag = var.bots_image_tag
web3_http_provider_urls = local.mode_mainnet_rpcs
Expand Down
26 changes: 24 additions & 2 deletions ops/prod/optimism.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
locals {
optimism_mainnet_rpc_0 = "https://mainnet.optimism.io"
optimism_mainnet_rpc_0 = var.optimism_mainnet_rpcs
optimism_mainnet_chain_id = "10"
}


module "optimism_mainnet_liquidation_rpc_0" {
/*module "optimism_mainnet_liquidation_rpc_0" {
source = "../modules/lambda"
ecr_repository_name = local.liquidator_ecr_repository_name
docker_image_tag = var.bots_image_tag
Expand All @@ -18,4 +18,26 @@ module "optimism_mainnet_liquidation_rpc_0" {
schedule_expression = "rate(5 minutes)"
timeout = 700
memory_size = 512
}*/
module "optimism_mainnet_liquidator_ecs" {
source = "../modules/bot"

cluster_name = var.liquidator_cluster_name
task_definition_family = "${var.task_definition_family}-optimism"
ecr_repository_url = "${local.liquidator_ecr_repository_name}:${var.bots_image_tag}"
bots_image_tag = var.bots_image_tag
web3_http_provider_urls = local.optimism_mainnet_rpc_0
target_chain_id = local.optimism_mainnet_chain_id
ethereum_admin_account = var.ethereum_admin_account
ethereum_admin_private_key = var.ethereum_admin_private_key
ecs_service_name = "${var.liquidator_service_name}-optimism"
desired_count = var.desired_count
liquidation_discord_webhook_url = var.liquidation_discord_webhook_url
discord_success_webhook_url = var.discord_success_webhook_url
discord_failure_webhook_url = var.discord_failure_webhook_url
lifi_api_key = var.lifi_api_key
subnet_ids = ["subnet-0cd439d262800846e"]
security_group_ids = ["sg-0a3996557af867ad0"]
region = var.region
liquidator_container_name = "${var.liquidator_container_name}-optimism"
}
10 changes: 6 additions & 4 deletions ops/prod/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
# output "mode-mainnet-liquidation" {
# value = module.mode_mainnet_liquidation_rpc_0.lambda_cron_service_name
# }
output "base-mainnet-liquidation" {
value = module.base_mainnet_liquidation_rpc_0.lambda_cron_service_name
# Add ECS outputs if needed
output "base_mainnet_liquidator_ecs_service" {
value = module.base_mainnet_liquidator_ecs.task_definition_arn
}
output "optimism-mainnet-liquidation" {
value = module.optimism_mainnet_liquidation_rpc_0.lambda_cron_service_name

output "optimism_mainnet_liquidator_ecs_service" {
value = module.optimism_mainnet_liquidator_ecs.task_definition_arn
}
output "ecs_cluster_id" {
value = aws_ecs_cluster.my_cluster1.id
Expand Down
5 changes: 4 additions & 1 deletion ops/prod/terraform.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ desired_count = 1
ecr_repository_name = "liquidator-pyth"
ecs_service_name = "opportunity_bot_service"

liquidator_service_name = "liquidator-service"
liquidator_service_name = "liquidator-service"
task_definition_family_optimism = "liquidator-optimism"
task_definition_family_base = "liquidator-base"
task_definition_family_mode = "liquidator-mode"
18 changes: 18 additions & 0 deletions ops/prod/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ variable "per_discord_webhook_url" {
variable "liquidation_sendgrid_api_key" {
type = string
}
variable "optimism_mainnet_rpcs" {
type = string
}

variable "liquidation_sendgrid_email_to" {
type = string
Expand All @@ -75,7 +78,22 @@ variable "uptime_liquidator_api" {
variable "uptime_pyth_updater_api" {
type = string
}
// ... existing variables ...

variable "task_definition_family_optimism" {
description = "Family name for the Optimism task definition"
type = string
}

variable "task_definition_family_base" {
description = "Family name for the Base task definition"
type = string
}

variable "task_definition_family_mode" {
description = "Family name for the Mode task definition"
type = string
}



Expand Down
46 changes: 37 additions & 9 deletions packages/bots/liquidator/src/run.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { createPublicClient, createWalletClient, fallback, Hex, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { BotType } from "@ionicprotocol/sdk";
import axios from "axios";

import config from "./config";
import { liquidatePositions } from "./liquidatePositions";
import { setUpSdk } from "./utils";
import { logger } from "./logger";
import { setUpSdk } from "./utils";

// Add heartbeat URL check
const HEARTBEAT_API_URL = process.env.UPTIME_LIQUIDATOR_API;

if (typeof HEARTBEAT_API_URL === "undefined") {
logger.error("Error: UPTIME_LIQUIDATOR_API environment variable is undefined");
} else if (typeof HEARTBEAT_API_URL !== "string") {
logger.error("Error: UPTIME_LIQUIDATOR_API environment variable is not a string");
} else {
logger.info(`UPTIME_LIQUIDATOR_API is set to: ${HEARTBEAT_API_URL}`);
}

export const account = privateKeyToAccount(config.adminPrivateKey as Hex);

Expand All @@ -19,14 +31,30 @@ export const walletClient = createWalletClient({
transport: fallback(config.rpcUrls.map((url) => http(url))),
});

export const sdk = setUpSdk(config.chainId, client as any, walletClient);
export const sdk = setUpSdk(config.chainId, client, walletClient);

export const run = async (): Promise<void> => {
try {
// Trigger heartbeat
if (HEARTBEAT_API_URL) {
await axios.get(HEARTBEAT_API_URL);
logger.info("Heartbeat successfully sent");
}

const run = async () => {
logger.info(`Starting liquidation bot on chain: ${config.chainId}`);
logger.info(
`Config for bot: ${JSON.stringify({ ...sdk.chainLiquidationConfig, ...config, adminPrivateKey: "***********" })}`
);
await liquidatePositions(BotType.Standard);
sdk.logger.info(`Starting liquidation bot on chain: ${config.chainId}`);
sdk.logger.info(`Config for bot: ${JSON.stringify({ ...sdk.chainLiquidationConfig, ...config })}`);

Check failure on line 46 in packages/bots/liquidator/src/run.ts

View workflow job for this annotation

GitHub Actions / lint-bots

Delete `····`
await liquidatePositions(BotType.Standard);
} catch (error) {
logger.error(`Error in run: ${error}`);
throw error;
}
};

run();
// Execute if this file is run directly
if (require.main === module) {
run().catch((error) => {
logger.error(`Fatal error: ${error}`);
process.exit(1);
});
}

Check failure on line 60 in packages/bots/liquidator/src/run.ts

View workflow job for this annotation

GitHub Actions / lint-bots

Insert `⏎`
16 changes: 1 addition & 15 deletions packages/bots/pyth-updater/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { APIGatewayEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import axios from 'axios';
import { createPublicClient, createWalletClient, fallback, Hex, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mode } from 'viem/chains';
Expand All @@ -10,16 +9,6 @@ import { logger } from './logger';
import { Updater } from './services';
import { setUpSdk } from './utils';

const HEARTBEAT_API_URL: any = process.env.UPTIME_PYTH_UPDATER_API;

if (typeof HEARTBEAT_API_URL === 'undefined') {
logger.error('Error: UPTIME_PYTH_UPDATER_API environment variable is undefined');
} else if (typeof HEARTBEAT_API_URL !== 'string') {
logger.error('Error: UPTIME_PYTH_UPDATER_API environment variable is not a string');
} else {
logger.info(`UPTIME_PYTH_UPDATER_API is set to: ${HEARTBEAT_API_URL}`);
}
logger.info(`UPTIME_PYTH_UPDATER_API is set to: ${HEARTBEAT_API_URL}`);
export const handler = async (
event: APIGatewayEvent,
context: Context,
Expand All @@ -46,9 +35,6 @@ export const handler = async (
const updater = await new Updater(sdk).init(assetConfig);

sdk.logger.info(`Starting update loop bot on chain: ${config.chainId}`);
sdk.logger.info(`Config for bot: ${JSON.stringify(config)}`);
await axios.get(HEARTBEAT_API_URL);
logger.info(`Heartbeat successfully sent`);
await updater.updateFeeds();

return {
Expand All @@ -57,4 +43,4 @@ export const handler = async (
message: 'hello world',
}),
};
};
};
26 changes: 24 additions & 2 deletions packages/bots/pyth-updater/src/run.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { createPublicClient, createWalletClient, fallback, Hex, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mode } from 'viem/chains';
import axios from 'axios';

import { chainIdToConfig } from './config';
import config from './config/service';
import { Updater } from './services';
import { setUpSdk } from './utils';
import { logger } from './logger';

const HEARTBEAT_API_URL: any = process.env.UPTIME_PYTH_UPDATER_API;

if (typeof HEARTBEAT_API_URL === 'undefined') {
logger.error('Error: UPTIME_PYTH_UPDATER_API environment variable is undefined');
} else if (typeof HEARTBEAT_API_URL !== 'string') {
logger.error('Error: UPTIME_PYTH_UPDATER_API environment variable is not a string');
} else {
logger.info(`UPTIME_PYTH_UPDATER_API is set to: ${HEARTBEAT_API_URL}`);
}

export const run = async (): Promise<void> => {
const account = privateKeyToAccount(config.adminPrivateKey as Hex);
Expand All @@ -27,8 +39,18 @@ export const run = async (): Promise<void> => {

sdk.logger.info(`Starting update loop bot on chain: ${config.chainId}`);
sdk.logger.info(`Config for bot: ${JSON.stringify({ ...config, adminPrivateKey: '*****' })}`);

try {
await axios.get(HEARTBEAT_API_URL);
logger.info(`Heartbeat successfully sent`);
} catch (error) {
logger.error(`Failed to send heartbeat: ${error}`);
}

await updater.updateFeeds();
// await updater.forceUpdateFeeds(assetConfig);
};

run();
run().catch((error) => {
logger.error(`Error in main loop: ${error}`);
process.exit(1);
});

0 comments on commit 641cd2c

Please sign in to comment.