From 956a8954679fccf4b080c1ea864662cb7552acf3 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:02:30 +0100 Subject: [PATCH 01/23] docker-compose setup --- README.md | 9 +++------ docker-compose.yml | 9 ++++++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 828d6e766..f638248cd 100644 --- a/README.md +++ b/README.md @@ -47,14 +47,11 @@ userInitStakedBalances ### Setup database & Prisma from backup Retrieve the current pg_dump file under `https://api-db-dump.s3.eu-central-1.amazonaws.com/canary/api-dump.YYYYMMDD`. -Database dumps are kept for the previous 7 days, replace YYYYMMDD in the URL above (ie: 20230317) to download a db dump. +Database dumps are kept for the previous 7 days, replace YYYYMMDD in the URL above (ie: 20230317) to download a db dump. Run `docker-compose up -d` to start the database via docker compose. -Retrieve the docker container ID through `docker ps`. - -Run `docker exec -i /bin/bash -c "PGPASSWORD=let-me-in psql --username backend database" < /path/on/your/machine/dump` -with the container-ID from the step before. +Run `docker exec -i $(docker ps -qf "name=balancer-backend") /bin/bash -c "PGPASSWORD=let-me-in psql --username backend database" < /path/on/your/machine/dump` The output at the very end saying `ERROR: role "rdsadmin" does not exist` is normal and can be ignored. @@ -90,4 +87,4 @@ To contribute, branch from `v2-canary` (which is our development branch) and ope ### Database Updates -If you make any changes to the database schema be sure to run `yarn prisma migrate dev --name ` which will create a new file in `prisma/migrations` that contains all the database changes you've made as an SQL update script. \ No newline at end of file +If you make any changes to the database schema be sure to run `yarn prisma migrate dev --name ` which will create a new file in `prisma/migrations` that contains all the database changes you've made as an SQL update script. diff --git a/docker-compose.yml b/docker-compose.yml index 91766dccb..05ae87ada 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,10 +2,17 @@ version: '3' services: postgres: - image: postgres + container_name: balancer-backend + image: postgres:14-alpine ports: - '5431:5432' environment: POSTGRES_USER: backend POSTGRES_PASSWORD: let-me-in POSTGRES_DB: database + networks: + - balancer + +networks: + balancer: + name: balancer From dcfd0d206027accbb2e63eb44b4d8b0a28f24a78 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:12:18 +0100 Subject: [PATCH 02/23] more tests --- package.json | 1 + test/factories/index.ts | 2 ++ test/factories/pool.factory.ts | 50 ++++++++++++++++++++++++++++ test/factories/pool_token.factory.ts | 17 ++++++++++ yarn.lock | 12 +++++++ 5 files changed, 82 insertions(+) create mode 100644 test/factories/index.ts create mode 100644 test/factories/pool.factory.ts create mode 100644 test/factories/pool_token.factory.ts diff --git a/package.json b/package.json index ce3785b5f..8165f0df3 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "@types/uuid": "^8.0.0", "concurrently": "^6.4.0", "execa": "^4.1.0", + "fishery": "^2.2.2", "jest": "^28.1.3", "jest-watch-typeahead": "^1.0.0", "msw": "^0.47.3", diff --git a/test/factories/index.ts b/test/factories/index.ts new file mode 100644 index 000000000..6706ad5bc --- /dev/null +++ b/test/factories/index.ts @@ -0,0 +1,2 @@ +export * from './pool.factory'; +export * from './pool_token.factory'; diff --git a/test/factories/pool.factory.ts b/test/factories/pool.factory.ts new file mode 100644 index 000000000..a64270533 --- /dev/null +++ b/test/factories/pool.factory.ts @@ -0,0 +1,50 @@ +import { Factory } from 'fishery'; +import { BalancerPoolFragment } from '../../modules/subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; + +export const poolFactory = Factory.define(() => ({ + id: '123', + poolType: 'A', + address: '0x123456789', + swapFee: '0.01', + totalSwapVolume: '1000', + totalSwapFee: '10', + totalLiquidity: '10000', + totalShares: '100', + swapsCount: '5', + holdersCount: '10', + createTime: 1234567890, // Add createTime property as a number + swapEnabled: true, // Add swapEnabled property + tokensList: ['token1', 'token2'], // Add tokensList property + tokens: [ + { + id: 'token1', + symbol: 'T1', + name: 'Token 1', + decimals: 18, + address: 'token1', + balance: '100', + weight: '0.5', + priceRate: '1', + index: 0, + token: { + // token properties... + }, + }, + { + id: 'token2', + symbol: 'T2', + name: 'Token 2', + decimals: 18, + address: 'token2', + balance: '200', + weight: '0.5', + priceRate: '1', + index: 1, + token: { + // token properties... + }, + }, + ], + + // Add other required properties... +})); diff --git a/test/factories/pool_token.factory.ts b/test/factories/pool_token.factory.ts new file mode 100644 index 000000000..50c03cc75 --- /dev/null +++ b/test/factories/pool_token.factory.ts @@ -0,0 +1,17 @@ +import { Factory } from 'fishery'; +import { BalancerPoolTokenFragment } from '../../modules/subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; + +export const poolTokenFactory = Factory.define(() => ({ + id: 'token1', + symbol: 'T1', + name: 'Token 1', + decimals: 18, + address: 'token1', + balance: '100', + weight: '0.5', + priceRate: '1', + index: 0, + token: { + // token properties... + }, +})); diff --git a/yarn.lock b/yarn.lock index 1f593b651..830c56f46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7280,6 +7280,13 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +fishery@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/fishery/-/fishery-2.2.2.tgz#94d3d9380295dd3ce555021e9353c5348b8beb77" + integrity sha512-jeU0nDhPHJkupmjX+r9niKgVMTBDB8X+U/pktoGHAiWOSyNlMd0HhmqnjrpjUOCDPJYaSSu4Ze16h6dZOKSp2w== + dependencies: + lodash.mergewith "^4.6.2" + follow-redirects@^1.0.0: version "1.15.3" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" @@ -9263,6 +9270,11 @@ lodash.memoize@4.x: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= +lodash.mergewith@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" From ee6e0e71bc1d46b3a283a6f165476de1e4361593 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:36:18 +0100 Subject: [PATCH 03/23] allow deleting pools with associations --- modules/pool/pool.prisma | 36 ++--- modules/user/user.prisma | 6 +- modules/vebal/vebal.prisma | 2 +- .../migration.sql | 131 ++++++++++++++++++ prisma/schema.prisma | 44 +++--- 5 files changed, 175 insertions(+), 44 deletions(-) create mode 100644 prisma/migrations/20231221153955_allow_deleting_pools_with_associations/migration.sql diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma index 9b16b15c2..a152af46b 100644 --- a/modules/pool/pool.prisma +++ b/modules/pool/pool.prisma @@ -65,7 +65,7 @@ model PrismaPoolLinearData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain mainIndex Int @@ -78,7 +78,7 @@ model PrismaPoolElementData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain unitSeconds String @@ -92,7 +92,7 @@ model PrismaPoolGyroData{ id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain alpha String @@ -120,7 +120,7 @@ model PrismaPoolDynamicData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain blockNumber Int updatedAt DateTime @updatedAt @@ -174,7 +174,7 @@ model PrismaPoolStableDynamicData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain blockNumber Int updatedAt DateTime @updatedAt @@ -188,7 +188,7 @@ model PrismaPoolLinearDynamicData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain blockNumber Int updatedAt DateTime @updatedAt @@ -202,7 +202,7 @@ model PrismaPoolToken { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain address String @@ -224,7 +224,7 @@ model PrismaPoolTokenDynamicData { id String poolTokenId String - poolToken PrismaPoolToken @relation(fields:[poolTokenId, chain], references: [id, chain]) + poolToken PrismaPoolToken @relation(fields:[poolTokenId, chain], references: [id, chain], onDelete: Cascade) chain Chain blockNumber Int updatedAt DateTime @updatedAt @@ -241,7 +241,7 @@ model PrismaPoolSwap { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain userAddress String @@ -284,7 +284,7 @@ model PrismaPoolAprItem { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain title String apr Float @@ -301,7 +301,7 @@ model PrismaPoolAprRange { id String chain Chain aprItemId String - aprItem PrismaPoolAprItem @relation(fields:[aprItemId, chain], references: [id, chain]) + aprItem PrismaPoolAprItem @relation(fields:[aprItemId, chain], references: [id, chain], onDelete: Cascade) min Float max Float } @@ -355,11 +355,11 @@ model PrismaPoolExpandedTokens { tokenAddress String token PrismaToken @relation(fields:[tokenAddress, chain], references: [address, chain]) poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain nestedPoolId String? - nestedPool PrismaPool? @relation(name: "NestedPoolForAllToken", fields:[nestedPoolId, chain], references: [id, chain]) + nestedPool PrismaPool? @relation(name: "NestedPoolForAllToken", fields:[nestedPoolId, chain], references: [id, chain], onDelete: Cascade) } @@ -381,7 +381,7 @@ model PrismaPoolFilterMap { filterId String filter PrismaPoolFilter @relation(fields:[filterId, chain], references: [id, chain]) poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) } model PrismaPoolStaking { @@ -389,7 +389,7 @@ model PrismaPoolStaking { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain type PrismaPoolStakingType address String @@ -439,7 +439,7 @@ model PrismaPoolStakingGauge { id String stakingId String - staking PrismaPoolStaking @relation(fields:[stakingId, chain], references: [id, chain]) + staking PrismaPoolStaking @relation(fields:[stakingId, chain], references: [id, chain], onDelete: Cascade) chain Chain gaugeAddress String @@ -463,7 +463,7 @@ model PrismaPoolStakingGaugeReward{ id String gaugeId String - gauge PrismaPoolStakingGauge @relation(fields:[gaugeId, chain], references: [id, chain]) + gauge PrismaPoolStakingGauge @relation(fields:[gaugeId, chain], references: [id, chain], onDelete: Cascade) chain Chain tokenAddress String @@ -510,7 +510,7 @@ model PrismaPoolSnapshot { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain timestamp Int diff --git a/modules/user/user.prisma b/modules/user/user.prisma index 69746e651..11cdd6c6e 100644 --- a/modules/user/user.prisma +++ b/modules/user/user.prisma @@ -26,7 +26,7 @@ model PrismaUserWalletBalance { user PrismaUser @relation(fields:[userAddress], references: [address]) poolId String? - pool PrismaPool? @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool? @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) tokenAddress String token PrismaToken @relation(fields:[tokenAddress, chain], references: [address, chain]) @@ -46,13 +46,13 @@ model PrismaUserStakedBalance { user PrismaUser @relation(fields:[userAddress], references: [address]) poolId String? - pool PrismaPool? @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool? @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) tokenAddress String token PrismaToken @relation(fields:[tokenAddress, chain], references: [address, chain]) stakingId String - staking PrismaPoolStaking @relation(fields:[stakingId, chain], references: [id, chain]) + staking PrismaPoolStaking @relation(fields:[stakingId, chain], references: [id, chain], onDelete: Cascade) } model PrismaUserBalanceSyncStatus { diff --git a/modules/vebal/vebal.prisma b/modules/vebal/vebal.prisma index df28431b5..3ea981dc9 100644 --- a/modules/vebal/vebal.prisma +++ b/modules/vebal/vebal.prisma @@ -31,7 +31,7 @@ model PrismaVotingGauge { id String chain Chain - stakingGauge PrismaPoolStakingGauge? @relation(fields: [stakingGaugeId, chain], references: [id, chain]) + stakingGauge PrismaPoolStakingGauge? @relation(fields: [stakingGaugeId, chain], references: [id, chain], onDelete: Cascade) status PrismaVotingGaugeStatus @default(ACTIVE) gaugeAddress String stakingGaugeId String? diff --git a/prisma/migrations/20231221153955_allow_deleting_pools_with_associations/migration.sql b/prisma/migrations/20231221153955_allow_deleting_pools_with_associations/migration.sql new file mode 100644 index 000000000..7160564a4 --- /dev/null +++ b/prisma/migrations/20231221153955_allow_deleting_pools_with_associations/migration.sql @@ -0,0 +1,131 @@ +-- DropForeignKey +ALTER TABLE "PrismaPoolAprItem" DROP CONSTRAINT "PrismaPoolAprItem_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolAprRange" DROP CONSTRAINT "PrismaPoolAprRange_aprItemId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolDynamicData" DROP CONSTRAINT "PrismaPoolDynamicData_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolElementData" DROP CONSTRAINT "PrismaPoolElementData_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolExpandedTokens" DROP CONSTRAINT "PrismaPoolExpandedTokens_nestedPoolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolExpandedTokens" DROP CONSTRAINT "PrismaPoolExpandedTokens_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolFilterMap" DROP CONSTRAINT "PrismaPoolFilterMap_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolGyroData" DROP CONSTRAINT "PrismaPoolGyroData_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolLinearData" DROP CONSTRAINT "PrismaPoolLinearData_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolLinearDynamicData" DROP CONSTRAINT "PrismaPoolLinearDynamicData_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolSnapshot" DROP CONSTRAINT "PrismaPoolSnapshot_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolStableDynamicData" DROP CONSTRAINT "PrismaPoolStableDynamicData_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolStaking" DROP CONSTRAINT "PrismaPoolStaking_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolStakingGauge" DROP CONSTRAINT "PrismaPoolStakingGauge_stakingId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolStakingGaugeReward" DROP CONSTRAINT "PrismaPoolStakingGaugeReward_gaugeId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolSwap" DROP CONSTRAINT "PrismaPoolSwap_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolToken" DROP CONSTRAINT "PrismaPoolToken_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaPoolTokenDynamicData" DROP CONSTRAINT "PrismaPoolTokenDynamicData_poolTokenId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaUserStakedBalance" DROP CONSTRAINT "PrismaUserStakedBalance_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaUserStakedBalance" DROP CONSTRAINT "PrismaUserStakedBalance_stakingId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaUserWalletBalance" DROP CONSTRAINT "PrismaUserWalletBalance_poolId_chain_fkey"; + +-- DropForeignKey +ALTER TABLE "PrismaVotingGauge" DROP CONSTRAINT "PrismaVotingGauge_stakingGaugeId_chain_fkey"; + +-- AddForeignKey +ALTER TABLE "PrismaPoolLinearData" ADD CONSTRAINT "PrismaPoolLinearData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolElementData" ADD CONSTRAINT "PrismaPoolElementData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolGyroData" ADD CONSTRAINT "PrismaPoolGyroData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolDynamicData" ADD CONSTRAINT "PrismaPoolDynamicData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolStableDynamicData" ADD CONSTRAINT "PrismaPoolStableDynamicData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolLinearDynamicData" ADD CONSTRAINT "PrismaPoolLinearDynamicData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolToken" ADD CONSTRAINT "PrismaPoolToken_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolTokenDynamicData" ADD CONSTRAINT "PrismaPoolTokenDynamicData_poolTokenId_chain_fkey" FOREIGN KEY ("poolTokenId", "chain") REFERENCES "PrismaPoolToken"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolSwap" ADD CONSTRAINT "PrismaPoolSwap_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolAprItem" ADD CONSTRAINT "PrismaPoolAprItem_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolAprRange" ADD CONSTRAINT "PrismaPoolAprRange_aprItemId_chain_fkey" FOREIGN KEY ("aprItemId", "chain") REFERENCES "PrismaPoolAprItem"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolExpandedTokens" ADD CONSTRAINT "PrismaPoolExpandedTokens_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolExpandedTokens" ADD CONSTRAINT "PrismaPoolExpandedTokens_nestedPoolId_chain_fkey" FOREIGN KEY ("nestedPoolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolFilterMap" ADD CONSTRAINT "PrismaPoolFilterMap_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolStaking" ADD CONSTRAINT "PrismaPoolStaking_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolStakingGauge" ADD CONSTRAINT "PrismaPoolStakingGauge_stakingId_chain_fkey" FOREIGN KEY ("stakingId", "chain") REFERENCES "PrismaPoolStaking"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolStakingGaugeReward" ADD CONSTRAINT "PrismaPoolStakingGaugeReward_gaugeId_chain_fkey" FOREIGN KEY ("gaugeId", "chain") REFERENCES "PrismaPoolStakingGauge"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaPoolSnapshot" ADD CONSTRAINT "PrismaPoolSnapshot_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaUserWalletBalance" ADD CONSTRAINT "PrismaUserWalletBalance_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaUserStakedBalance" ADD CONSTRAINT "PrismaUserStakedBalance_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaUserStakedBalance" ADD CONSTRAINT "PrismaUserStakedBalance_stakingId_chain_fkey" FOREIGN KEY ("stakingId", "chain") REFERENCES "PrismaPoolStaking"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PrismaVotingGauge" ADD CONSTRAINT "PrismaVotingGauge_stakingGaugeId_chain_fkey" FOREIGN KEY ("stakingGaugeId", "chain") REFERENCES "PrismaPoolStakingGauge"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 186f5c992..4868e2afd 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -111,7 +111,7 @@ model PrismaPoolLinearData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain mainIndex Int @@ -124,7 +124,7 @@ model PrismaPoolElementData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain unitSeconds String @@ -138,7 +138,7 @@ model PrismaPoolGyroData{ id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain alpha String @@ -166,7 +166,7 @@ model PrismaPoolDynamicData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain blockNumber Int updatedAt DateTime @updatedAt @@ -220,7 +220,7 @@ model PrismaPoolStableDynamicData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain blockNumber Int updatedAt DateTime @updatedAt @@ -234,7 +234,7 @@ model PrismaPoolLinearDynamicData { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain blockNumber Int updatedAt DateTime @updatedAt @@ -248,7 +248,7 @@ model PrismaPoolToken { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain address String @@ -270,7 +270,7 @@ model PrismaPoolTokenDynamicData { id String poolTokenId String - poolToken PrismaPoolToken @relation(fields:[poolTokenId, chain], references: [id, chain]) + poolToken PrismaPoolToken @relation(fields:[poolTokenId, chain], references: [id, chain], onDelete: Cascade) chain Chain blockNumber Int updatedAt DateTime @updatedAt @@ -287,7 +287,7 @@ model PrismaPoolSwap { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain userAddress String @@ -330,7 +330,7 @@ model PrismaPoolAprItem { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain title String apr Float @@ -347,7 +347,7 @@ model PrismaPoolAprRange { id String chain Chain aprItemId String - aprItem PrismaPoolAprItem @relation(fields:[aprItemId, chain], references: [id, chain]) + aprItem PrismaPoolAprItem @relation(fields:[aprItemId, chain], references: [id, chain], onDelete: Cascade) min Float max Float } @@ -401,11 +401,11 @@ model PrismaPoolExpandedTokens { tokenAddress String token PrismaToken @relation(fields:[tokenAddress, chain], references: [address, chain]) poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain nestedPoolId String? - nestedPool PrismaPool? @relation(name: "NestedPoolForAllToken", fields:[nestedPoolId, chain], references: [id, chain]) + nestedPool PrismaPool? @relation(name: "NestedPoolForAllToken", fields:[nestedPoolId, chain], references: [id, chain], onDelete: Cascade) } @@ -427,7 +427,7 @@ model PrismaPoolFilterMap { filterId String filter PrismaPoolFilter @relation(fields:[filterId, chain], references: [id, chain]) poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) } model PrismaPoolStaking { @@ -435,7 +435,7 @@ model PrismaPoolStaking { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain type PrismaPoolStakingType address String @@ -485,7 +485,7 @@ model PrismaPoolStakingGauge { id String stakingId String - staking PrismaPoolStaking @relation(fields:[stakingId, chain], references: [id, chain]) + staking PrismaPoolStaking @relation(fields:[stakingId, chain], references: [id, chain], onDelete: Cascade) chain Chain gaugeAddress String @@ -509,7 +509,7 @@ model PrismaPoolStakingGaugeReward{ id String gaugeId String - gauge PrismaPoolStakingGauge @relation(fields:[gaugeId, chain], references: [id, chain]) + gauge PrismaPoolStakingGauge @relation(fields:[gaugeId, chain], references: [id, chain], onDelete: Cascade) chain Chain tokenAddress String @@ -556,7 +556,7 @@ model PrismaPoolSnapshot { id String poolId String - pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) chain Chain timestamp Int @@ -787,7 +787,7 @@ model PrismaUserWalletBalance { user PrismaUser @relation(fields:[userAddress], references: [address]) poolId String? - pool PrismaPool? @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool? @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) tokenAddress String token PrismaToken @relation(fields:[tokenAddress, chain], references: [address, chain]) @@ -807,13 +807,13 @@ model PrismaUserStakedBalance { user PrismaUser @relation(fields:[userAddress], references: [address]) poolId String? - pool PrismaPool? @relation(fields:[poolId, chain], references: [id, chain]) + pool PrismaPool? @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade) tokenAddress String token PrismaToken @relation(fields:[tokenAddress, chain], references: [address, chain]) stakingId String - staking PrismaPoolStaking @relation(fields:[stakingId, chain], references: [id, chain]) + staking PrismaPoolStaking @relation(fields:[stakingId, chain], references: [id, chain], onDelete: Cascade) } model PrismaUserBalanceSyncStatus { @@ -903,7 +903,7 @@ model PrismaVotingGauge { id String chain Chain - stakingGauge PrismaPoolStakingGauge? @relation(fields: [stakingGaugeId, chain], references: [id, chain]) + stakingGauge PrismaPoolStakingGauge? @relation(fields: [stakingGaugeId, chain], references: [id, chain], onDelete: Cascade) status PrismaVotingGaugeStatus @default(ACTIVE) gaugeAddress String stakingGaugeId String? From 001d1df90c0c617f6eaecf27e01314e3dac90a73 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:40:56 +0100 Subject: [PATCH 04/23] pool defaults for 24h volume and fees --- modules/pool/pool.prisma | 4 ++-- .../20231221154038_more_pool_defaults/migration.sql | 3 +++ prisma/schema.prisma | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 prisma/migrations/20231221154038_more_pool_defaults/migration.sql diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma index a152af46b..a3c234f40 100644 --- a/modules/pool/pool.prisma +++ b/modules/pool/pool.prisma @@ -133,8 +133,8 @@ model PrismaPoolDynamicData { totalShares String totalSharesNum Float @default(0) totalLiquidity Float - volume24h Float - fees24h Float + volume24h Float @default(0) + fees24h Float @default(0) yieldCapture24h Float @default(0) apr Float @default(0) volume48h Float @default(0) diff --git a/prisma/migrations/20231221154038_more_pool_defaults/migration.sql b/prisma/migrations/20231221154038_more_pool_defaults/migration.sql new file mode 100644 index 000000000..56c17b3ad --- /dev/null +++ b/prisma/migrations/20231221154038_more_pool_defaults/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "PrismaPoolDynamicData" ALTER COLUMN "volume24h" SET DEFAULT 0, +ALTER COLUMN "fees24h" SET DEFAULT 0; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 4868e2afd..425e860c7 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -179,8 +179,8 @@ model PrismaPoolDynamicData { totalShares String totalSharesNum Float @default(0) totalLiquidity Float - volume24h Float - fees24h Float + volume24h Float @default(0) + fees24h Float @default(0) yieldCapture24h Float @default(0) apr Float @default(0) volume48h Float @default(0) From 9d5c936100fa9e25318ff1a139e36b1265baf3d0 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:41:26 +0100 Subject: [PATCH 05/23] pools data json column --- modules/pool/pool.prisma | 1 + .../20231221154118_pools_data_json_column/migration.sql | 2 ++ prisma/schema.prisma | 1 + 3 files changed, 4 insertions(+) create mode 100644 prisma/migrations/20231221154118_pools_data_json_column/migration.sql diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma index a3c234f40..8bb8816ac 100644 --- a/modules/pool/pool.prisma +++ b/modules/pool/pool.prisma @@ -18,6 +18,7 @@ model PrismaPool { linearData PrismaPoolLinearData? elementData PrismaPoolElementData? gyroData PrismaPoolGyroData? + data Json @default("{}") tokens PrismaPoolToken[] diff --git a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql new file mode 100644 index 000000000..c08b112b7 --- /dev/null +++ b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "PrismaPool" ADD COLUMN "data" JSONB NOT NULL DEFAULT '{}'; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 425e860c7..ad5882758 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -64,6 +64,7 @@ model PrismaPool { linearData PrismaPoolLinearData? elementData PrismaPoolElementData? gyroData PrismaPoolGyroData? + data Json @default("{}") tokens PrismaPoolToken[] From b5af3e5f91f7fd3be4a3dca8e333ea53229c1435 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:07:44 +0100 Subject: [PATCH 06/23] add fx data to subgraph --- .../balancer-subgraph/balancer-subgraph-queries.graphql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql b/modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql index 5469dc094..faa6bd405 100644 --- a/modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql +++ b/modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql @@ -198,6 +198,9 @@ fragment BalancerPool on Pool { w z dSq + delta + epsilon + priceRateProviders { address token { From 827943ccd95e6e21341e4d81eb779cde4c01c16f Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:43:47 +0100 Subject: [PATCH 07/23] subgraph to DB mappers --- modules/pool/lib/pool-creator.service.ts | 132 +------------- modules/pool/pool-data/element.ts | 9 + modules/pool/pool-data/fx.ts | 11 ++ modules/pool/pool-data/gyro.ts | 23 +++ modules/pool/pool-data/index.ts | 5 + modules/pool/pool-data/linear.ts | 16 ++ modules/pool/pool-data/stable.ts | 8 + modules/pool/subgraph-mapper.test.ts | 91 ++++++++++ modules/pool/subgraph-mapper.ts | 221 +++++++++++++++++++++++ 9 files changed, 387 insertions(+), 129 deletions(-) create mode 100644 modules/pool/pool-data/element.ts create mode 100644 modules/pool/pool-data/fx.ts create mode 100644 modules/pool/pool-data/gyro.ts create mode 100644 modules/pool/pool-data/index.ts create mode 100644 modules/pool/pool-data/linear.ts create mode 100644 modules/pool/pool-data/stable.ts create mode 100644 modules/pool/subgraph-mapper.test.ts create mode 100644 modules/pool/subgraph-mapper.ts diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts index b138ea03b..ebe49f0dc 100644 --- a/modules/pool/lib/pool-creator.service.ts +++ b/modules/pool/lib/pool-creator.service.ts @@ -7,6 +7,7 @@ import { prismaPoolWithExpandedNesting } from '../../../prisma/prisma-types'; import { UserService } from '../../user/user.service'; import { prismaBulkExecuteOperations } from '../../../prisma/prisma-util'; import { networkContext } from '../../network/network-context.service'; +import { subgraphToPrisma } from '../subgraph-mapper'; export class PoolCreatorService { constructor(private readonly userService: UserService) {} @@ -224,136 +225,9 @@ export class PoolCreatorService { ], }); - // for the old phantom stable pool, we add it to the DB as type COMPOSABLE_STABLE with version 0 - let poolTypeVersion = pool.poolTypeVersion ? pool.poolTypeVersion : 1; - if (pool.poolType === 'StablePhantom') { - poolTypeVersion = 0; - } + const prismaPoolRecordWithAssociations = subgraphToPrisma(pool, this.chain, blockNumber, allNestedTypePools); - await prisma.prismaPool.create({ - data: { - id: pool.id, - chain: this.chain, - createTime: pool.createTime, - address: pool.address, - symbol: pool.symbol || '', - name: pool.name || '', - decimals: 18, - type: poolType, - version: poolTypeVersion, - owner: pool.owner || ZERO_ADDRESS, - factory: pool.factory, - tokens: { - createMany: { - data: poolTokens.map((token) => { - const nestedPool = allNestedTypePools.find((nestedPool) => { - return nestedPool.address === token.address; - }); - - let priceRateProvider; - if (pool.priceRateProviders) { - const data = pool.priceRateProviders.find( - (provider) => provider.token.address === token.address, - ); - priceRateProvider = data?.address; - } - - return { - id: token.id, - address: token.address, - priceRateProvider, - exemptFromProtocolYieldFee: token.isExemptFromYieldProtocolFee - ? token.isExemptFromYieldProtocolFee - : false, - nestedPoolId: nestedPool?.id, - index: token.index || pool.tokensList.findIndex((address) => address === token.address), - }; - }), - }, - }, - linearData: - poolType === 'LINEAR' - ? { - create: { - id: pool.id, - mainIndex: pool.mainIndex || 0, - wrappedIndex: pool.wrappedIndex || 0, - }, - } - : undefined, - linearDynamicData: - poolType === 'LINEAR' - ? { - create: { - id: pool.id, - upperTarget: pool.upperTarget || '', - lowerTarget: pool.lowerTarget || '', - blockNumber, - }, - } - : undefined, - elementData: - poolType === 'ELEMENT' - ? { - create: { - id: pool.id, - unitSeconds: pool.unitSeconds || '', - principalToken: pool.principalToken || '', - baseToken: pool.baseToken || '', - }, - } - : undefined, - gyroData: ['GYRO', 'GYRO3', 'GYROE'].includes(poolType) - ? { - create: { - id: pool.id, - alpha: pool.alpha || '', - beta: pool.beta || '', - sqrtAlpha: pool.sqrtAlpha || '', - sqrtBeta: pool.sqrtBeta || '', - root3Alpha: pool.root3Alpha || '', - c: pool.c || '', - s: pool.s || '', - lambda: pool.lambda || '', - tauAlphaX: pool.tauAlphaX || '', - tauAlphaY: pool.tauAlphaY || '', - tauBetaX: pool.tauBetaX || '', - tauBetaY: pool.tauBetaY || '', - u: pool.u || '', - v: pool.v || '', - w: pool.w || '', - z: pool.z || '', - dSq: pool.dSq || '', - }, - } - : undefined, - stableDynamicData: - poolType === 'STABLE' || poolType === 'COMPOSABLE_STABLE' || poolType === 'META_STABLE' - ? { - create: { - id: pool.id, - amp: pool.amp || '', - blockNumber, - }, - } - : undefined, - dynamicData: { - create: { - id: pool.id, - blockNumber, - swapFee: pool.swapFee, - swapEnabled: pool.swapEnabled, - totalShares: pool.totalShares, - totalSharesNum: parseFloat(pool.totalShares), - totalLiquidity: Math.max(parseFloat(pool.totalLiquidity), 0), - volume24h: 0, - fees24h: 0, - volume48h: 0, - fees48h: 0, - }, - }, - }, - }); + await prisma.prismaPool.create(prismaPoolRecordWithAssociations); await prisma.prismaPoolTokenDynamicData.createMany({ data: poolTokens.map((token) => ({ diff --git a/modules/pool/pool-data/element.ts b/modules/pool/pool-data/element.ts new file mode 100644 index 000000000..89c6af0ec --- /dev/null +++ b/modules/pool/pool-data/element.ts @@ -0,0 +1,9 @@ +import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; + +export const element = (pool: BalancerPoolFragment) => { + return { + unitSeconds: pool.unitSeconds || '', + principalToken: pool.principalToken || '', + baseToken: pool.baseToken || '', + }; +}; diff --git a/modules/pool/pool-data/fx.ts b/modules/pool/pool-data/fx.ts new file mode 100644 index 000000000..7b1edf745 --- /dev/null +++ b/modules/pool/pool-data/fx.ts @@ -0,0 +1,11 @@ +import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; + +export const fx = (pool: BalancerPoolFragment) => { + return { + alpha: pool.alpha, + beta: pool.beta, + delta: pool.delta, + epsilon: pool.epsilon, + lambda: pool.lambda, + }; +}; diff --git a/modules/pool/pool-data/gyro.ts b/modules/pool/pool-data/gyro.ts new file mode 100644 index 000000000..326a3c044 --- /dev/null +++ b/modules/pool/pool-data/gyro.ts @@ -0,0 +1,23 @@ +import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; + +export const gyro = (pool: BalancerPoolFragment) => { + return { + alpha: pool.alpha || '', + beta: pool.beta || '', + sqrtAlpha: pool.sqrtAlpha || '', + sqrtBeta: pool.sqrtBeta || '', + root3Alpha: pool.root3Alpha || '', + c: pool.c || '', + s: pool.s || '', + lambda: pool.lambda || '', + tauAlphaX: pool.tauAlphaX || '', + tauAlphaY: pool.tauAlphaY || '', + tauBetaX: pool.tauBetaX || '', + tauBetaY: pool.tauBetaY || '', + u: pool.u || '', + v: pool.v || '', + w: pool.w || '', + z: pool.z || '', + dSq: pool.dSq || '', + }; +}; diff --git a/modules/pool/pool-data/index.ts b/modules/pool/pool-data/index.ts new file mode 100644 index 000000000..52c0b91de --- /dev/null +++ b/modules/pool/pool-data/index.ts @@ -0,0 +1,5 @@ +export * from './element'; +export * from './fx'; +export * from './gyro'; +export * from './linear'; +export * from './stable'; diff --git a/modules/pool/pool-data/linear.ts b/modules/pool/pool-data/linear.ts new file mode 100644 index 000000000..becb29a4c --- /dev/null +++ b/modules/pool/pool-data/linear.ts @@ -0,0 +1,16 @@ +import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; + +export const linear = (pool: BalancerPoolFragment) => { + return { + mainIndex: pool.mainIndex || 0, + wrappedIndex: pool.wrappedIndex || 0, + }; +}; + +export const linearDynamic = (pool: BalancerPoolFragment, blockNumber: number) => { + return { + upperTarget: pool.upperTarget || '', + lowerTarget: pool.lowerTarget || '', + blockNumber, + }; +}; diff --git a/modules/pool/pool-data/stable.ts b/modules/pool/pool-data/stable.ts new file mode 100644 index 000000000..7ac8218d8 --- /dev/null +++ b/modules/pool/pool-data/stable.ts @@ -0,0 +1,8 @@ +import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; + +export const stableDynamic = (pool: BalancerPoolFragment, blockNumber: number) => { + return { + amp: pool.amp || '', + blockNumber, + }; +}; diff --git a/modules/pool/subgraph-mapper.test.ts b/modules/pool/subgraph-mapper.test.ts new file mode 100644 index 000000000..76a5fe62c --- /dev/null +++ b/modules/pool/subgraph-mapper.test.ts @@ -0,0 +1,91 @@ +import { subgraphToPrisma } from './subgraph-mapper'; +import { poolFactory, poolTokenFactory } from '../../test/factories'; + +describe('subgraphToPrisma', () => { + const weightedPool = poolFactory.build({ + poolType: 'Weighted', + }); + + const stablePool = poolFactory.build({ + poolType: 'ComposableStable', + amp: '0.1', + }); + + const linearPool = poolFactory.build({ + poolType: 'Linear', + wrappedIndex: 1, + upperTarget: '1', + }); + + const elementPool = poolFactory.build({ + poolType: 'Element', + principalToken: '0x123', + }); + + const gyroPool = poolFactory.build({ + poolType: 'GyroE', + alpha: '0.5', + tauAlphaX: '0.5', + }); + + const fxPool = poolFactory.build({ + poolType: 'FX', + alpha: '0.5', + }); + + it('should return correct object for weighted pool', () => { + const result = subgraphToPrisma(weightedPool, 'MAINNET', 1, []); + expect(result.data.type).toBe('WEIGHTED'); + }); + + it('should return correct object for stable pool', () => { + const result = subgraphToPrisma(stablePool, 'MAINNET', 1, []); + expect(result.data.type).toBe('COMPOSABLE_STABLE'); + expect(result.data.stableDynamicData?.create.amp).toBe(stablePool.amp); + }); + + it('should return correct object for linear pool', () => { + const result = subgraphToPrisma(linearPool, 'MAINNET', 1, []); + expect(result.data.type).toBe('LINEAR'); + expect(result.data.linearDynamicData?.create.upperTarget).toBe(linearPool.upperTarget); + expect(result.data.linearData?.create.wrappedIndex).toBe(linearPool.wrappedIndex); + }); + + it('should return correct object for element pool', () => { + const result = subgraphToPrisma(elementPool, 'MAINNET', 1, []); + expect(result.data.type).toBe('ELEMENT'); + expect(result.data.elementData?.create.principalToken).toBe(elementPool.principalToken); + }); + + it('should return correct object for gyro pool', () => { + const result = subgraphToPrisma(gyroPool, 'MAINNET', 1, []); + expect(result.data.type).toBe('GYROE'); + expect(result.data.gyroData?.create.alpha).toBe(gyroPool.alpha); + expect(result.data.gyroData?.create.tauAlphaX).toBe(gyroPool.tauAlphaX); + }); + + it('should return correct object for fx pool', () => { + const result = subgraphToPrisma(fxPool, 'MAINNET', 1, []); + expect(result.data.type).toBe('FX'); + expect(result.data.data['alpha']).toBe(gyroPool.alpha); + }); + + describe('nested pools', () => { + const nestedPools = [linearPool]; + const poolWithNestedPools = poolFactory.build({ + poolType: 'ComposableStable', + tokens: [ + poolTokenFactory.build({ + address: linearPool.address, + }), + poolTokenFactory.build({}), + ], + }); + + it('should recognise nested pools', () => { + const result = subgraphToPrisma(poolWithNestedPools, 'MAINNET', 1, nestedPools); + expect(result.data.type).toBe('COMPOSABLE_STABLE'); + expect(result.data.tokens.createMany.data[0].nestedPoolId).toBe(linearPool.id); + }); + }); +}); diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts new file mode 100644 index 000000000..38a451555 --- /dev/null +++ b/modules/pool/subgraph-mapper.ts @@ -0,0 +1,221 @@ +import { Chain, PrismaPoolType } from '@prisma/client'; +import { BalancerPoolFragment } from '../subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; +import { AddressZero } from '@ethersproject/constants'; +import * as dataMappers from './pool-data'; + +export const subgraphToPrisma = ( + pool: BalancerPoolFragment, + chain: Chain, + blockNumber: number, + nestedPools: { id: string; address: string }[], +) => { + const dbData = subgraphMapper(pool, chain, blockNumber, nestedPools); + + const prismaPoolRecordWithAssociations = { + data: { + ...dbData.base, + data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data. + tokens: { + createMany: { + data: dbData.tokens, + }, + }, + dynamicData: { + create: { + id: dbData.base.id, + ...dbData.dynamicData, + }, + }, + linearData: + dbData.base.type === 'LINEAR' + ? { + create: { + id: dbData.base.id, + ...(dbData.data as ReturnType), + }, + } + : undefined, + elementData: + dbData.base.type === 'ELEMENT' + ? { + create: { + id: dbData.base.id, + ...(dbData.data as ReturnType), + }, + } + : undefined, + gyroData: ['GYRO', 'GYRO3', 'GYROE'].includes(dbData.base.type) + ? { + create: { + id: dbData.base.id, + ...(dbData.data as ReturnType), + }, + } + : undefined, + linearDynamicData: + dbData.base.type === 'LINEAR' + ? { + create: { + id: dbData.base.id, + ...(dbData.dynamicTypeData as ReturnType), + }, + } + : undefined, + stableDynamicData: ['STABLE', 'COMPOSABLE_STABLE', 'META_STABLE'].includes(dbData.base.type) + ? { + create: { + id: dbData.base.id, + ...(dbData.dynamicTypeData as ReturnType), + }, + } + : undefined, + }, + }; + + return prismaPoolRecordWithAssociations; +}; + +const subgraphMapper = ( + pool: BalancerPoolFragment, + chain: Chain, + blockNumber: number, + nestedPools: { id: string; address: string }[], +) => { + const type = mapSubgraphPoolTypeToPoolType(pool.poolType!); + const version = mapPoolTypeVersion(type, pool.poolTypeVersion!); + + const base = { + id: pool.id, + chain: chain, + createTime: pool.createTime, + address: pool.address, + symbol: pool.symbol || '', + name: pool.name || '', + decimals: 18, + type: type, + version: version, + owner: pool.owner || AddressZero, + factory: pool.factory, + }; + + const dynamicData = { + blockNumber, + swapFee: pool.swapFee, + swapEnabled: pool.swapEnabled, + totalShares: pool.totalShares, + totalSharesNum: parseFloat(pool.totalShares), + totalLiquidity: Math.max(parseFloat(pool.totalLiquidity), 0), + }; + + const data: ReturnType | {} = Object.keys(dataMapper).includes(type) + ? dataMapper[type as keyof typeof dataMapper](pool) + : {}; + + const dynamicTypeData = Object.keys(dynamicMapper).includes(type) + ? dynamicMapper[type as keyof typeof dynamicMapper](pool, blockNumber) + : {}; + + const tokens = + pool.tokens?.map((token) => { + const nestedPool = nestedPools.find((nestedPool) => { + return nestedPool.address === token.address; + }); + + let priceRateProvider; + if (pool.priceRateProviders) { + const data = pool.priceRateProviders.find((provider) => provider.token.address === token.address); + priceRateProvider = data?.address; + } + + return { + id: token.id, + address: token.address, + priceRateProvider, + exemptFromProtocolYieldFee: token.isExemptFromYieldProtocolFee + ? token.isExemptFromYieldProtocolFee + : false, + nestedPoolId: nestedPool?.id, + index: token.index || pool.tokensList.findIndex((address) => address === token.address), + }; + }) ?? []; + + return { + base, + dynamicData, + tokens, + data, + dynamicTypeData, + }; +}; + +const mapSubgraphPoolTypeToPoolType = (poolType: string): PrismaPoolType => { + switch (poolType) { + case 'Weighted': + return 'WEIGHTED'; + case 'LiquidityBootstrapping': + return 'LIQUIDITY_BOOTSTRAPPING'; + case 'Stable': + return 'STABLE'; + case 'MetaStable': + return 'META_STABLE'; + // for the old phantom stable pool, we add it to the DB as type COMPOSABLE_STABLE with version 0 + case 'StablePhantom': + return 'COMPOSABLE_STABLE'; + case 'ComposableStable': + return 'COMPOSABLE_STABLE'; + case 'Linear': + return 'LINEAR'; + case 'Element': + return 'ELEMENT'; + case 'Investment': + return 'INVESTMENT'; + case 'Gyro2': + return 'GYRO'; + case 'Gyro3': + return 'GYRO3'; + case 'GyroE': + return 'GYROE'; + case 'FX': + return 'FX'; + } + + // balancer still uses AaveLinear, etc, so we account for that here + if (poolType.includes('Linear')) { + return 'LINEAR'; + } + + return 'UNKNOWN'; +}; + +const mapPoolTypeVersion = (poolType: string, poolTypeVersion: number): number => { + // for the old phantom stable pool, we add it to the DB as type COMPOSABLE_STABLE with version 0 + let version = poolTypeVersion ? poolTypeVersion : 1; + if (poolType === 'StablePhantom') { + version = 0; + } + + return version; +}; + +const dataMapper = { + ELEMENT: dataMappers.element, + FX: dataMappers.fx, + GYRO: dataMappers.gyro, + GYRO3: dataMappers.gyro, + GYROE: dataMappers.gyro, + LINEAR: dataMappers.linear, +}; + +const dynamicMapper = { + STABLE: dataMappers.stableDynamic, + COMPOSABLE_STABLE: dataMappers.stableDynamic, + META_STABLE: dataMappers.stableDynamic, + LINEAR: dataMappers.linearDynamic, +}; + +export type FxData = ReturnType; +export type GyroData = ReturnType; +export type LinearData = ReturnType; +export type ElementData = ReturnType; +export type StableDynamicData = ReturnType; +export type LinearDynamicData = ReturnType; From 7ab4104dd5904fe1b45f703d519be7974f7cb62b Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:44:22 +0100 Subject: [PATCH 08/23] FX pools parsing in SOR --- modules/sor/sorV2/sorV2.service.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/sor/sorV2/sorV2.service.ts b/modules/sor/sorV2/sorV2.service.ts index 279c65459..8ec3a59fb 100644 --- a/modules/sor/sorV2/sorV2.service.ts +++ b/modules/sor/sorV2/sorV2.service.ts @@ -13,6 +13,7 @@ import { RawGyro2Pool, RawGyro3Pool, RawGyroEPool, + RawFxPool, HumanAmount, SupportedRawPoolTypes, SingleSwap, @@ -44,6 +45,7 @@ import { poolsToIgnore } from '../constants'; import { AllNetworkConfigsKeyedOnChain, chainToIdMap } from '../../network/network-config'; import * as Sentry from '@sentry/node'; import { getToken } from '../utils'; +import { FxData } from '../../pool/subgraph-mapper'; const ALL_BASEPOOLS_CACHE_KEY = `basePools:all`; @@ -377,7 +379,6 @@ export class SorV2Service implements SwapService { 'ELEMENT', // not supported by b-sdk 'UNKNOWN', // not supported by b-sdk 'INVESTMENT', // not supported by b-sdk - 'FX', // needs more data ], }, AND: { @@ -428,6 +429,22 @@ export class SorV2Service implements SwapService { inRecoveryMode: !!prismaPool.dynamicData?.isInRecoveryMode, name: 'n/a', }; + if (['FX'].includes(rawPool.poolType)) { + const data = prismaPool.data as FxData; + rawPool = { + ...rawPool, + ...data, + tokens: rawPool.tokens.map((t, i) => { + return { + ...t, + token: { + latestFXPrice: prismaPool.tokens[i].dynamicData?.latestFxPrice?.toString(), + fxOracleDecimals: 18, + }, + }; + }), + } as RawFxPool; + } if (['Weighted', 'Investment', 'LiquidityBootstrapping'].includes(rawPool.poolType)) { rawPool = { ...rawPool, From 64d756bcbf878b3003f29c571aa2ed91c71341d5 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:45:06 +0100 Subject: [PATCH 09/23] FX pools in the graph schema --- modules/pool/lib/pool-gql-loader.service.ts | 24 +++++++++++++++++ modules/pool/pool.gql | 30 +++++++++++++++++++++ modules/pool/pool.resolvers.ts | 10 +++++++ modules/pool/pool.service.ts | 5 ++++ 4 files changed, 69 insertions(+) diff --git a/modules/pool/lib/pool-gql-loader.service.ts b/modules/pool/lib/pool-gql-loader.service.ts index fac3005a0..e910344af 100644 --- a/modules/pool/lib/pool-gql-loader.service.ts +++ b/modules/pool/lib/pool-gql-loader.service.ts @@ -32,6 +32,7 @@ import { GqlPoolWithdrawConfig, GqlPoolWithdrawOption, QueryPoolGetPoolsArgs, + GqlPoolFx, } from '../../../schema'; import { isSameAddress } from '@balancer-labs/sdk'; import _ from 'lodash'; @@ -47,6 +48,7 @@ import { BalancerChainIds, BeethovenChainIds, chainIdToChain, chainToIdMap } fro import { GithubContentService } from '../../content/github-content.service'; import { SanityContentService } from '../../content/sanity-content.service'; import { FeaturedPool } from '../../content/content-types'; +import { FxData } from '../subgraph-mapper'; export class PoolGqlLoaderService { public async getPool(id: string, chain: Chain, userAddress?: string): Promise { @@ -139,6 +141,16 @@ export class PoolGqlLoaderService { return pools.map((pool) => this.mapPoolToGqlPool(pool)) as GqlPoolGyro[]; } + public async getFxPools(chains: Chain[]): Promise { + const pools = await prisma.prismaPool.findMany({ + where: { type: { in: ['FX'] }, chain: { in: chains } }, + orderBy: { dynamicData: { totalLiquidity: 'desc' } }, + include: prismaPoolWithExpandedNesting.include, + }); + + return pools.map((pool) => this.mapPoolToGqlPool(pool)) as GqlPoolFx[]; + } + public mapToMinimalGqlPool( pool: PrismaPoolMinimal, userWalletbalances: PrismaUserWalletBalance[] = [], @@ -581,6 +593,18 @@ export class PoolGqlLoaderService { z: pool.gyroData?.z || '', dSq: pool.gyroData?.dSq || '', }; + case 'FX': + const data = pool.data as FxData; + return { + __typename: 'GqlPoolFx', + ...mappedData, + type: mappedData.type, + alpha: data.alpha || '', + beta: data.beta || '', + delta: data.delta || '', + epsilon: data.epsilon || '', + lambda: data.lambda || '', + }; } return { diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql index f1fa5ed92..91fac31fe 100644 --- a/modules/pool/pool.gql +++ b/modules/pool/pool.gql @@ -24,6 +24,7 @@ extend type Query { poolGetSnapshots(id: String!, chain: GqlChain, range: GqlPoolSnapshotDataRange!): [GqlPoolSnapshot!]! poolGetLinearPools(chains: [GqlChain!]): [GqlPoolLinear!]! poolGetGyroPools(chains: [GqlChain!]): [GqlPoolGyro!]! + poolGetFxPools(chains: [GqlChain!]): [GqlPoolFx!]! } extend type Mutation { @@ -282,6 +283,34 @@ type GqlPoolGyro implements GqlPoolBase { userBalance: GqlPoolUserBalance } +type GqlPoolFx implements GqlPoolBase { + alpha: String! + beta: String! + delta: String! + epsilon: String! + lambda: String! + + # Base pool + id: ID! + chain: GqlChain! + type: GqlPoolType! + version: Int! + name: String! + symbol: String! + address: Bytes! + decimals: Int! + owner: Bytes + factory: Bytes + createTime: Int! + investConfig: GqlPoolInvestConfig! + withdrawConfig: GqlPoolWithdrawConfig! + displayTokens: [GqlPoolTokenDisplay!]! + allTokens: [GqlPoolTokenExpanded!]! + dynamicData: GqlPoolDynamicData! + staking: GqlPoolStaking + userBalance: GqlPoolUserBalance +} + type GqlPoolLiquidityBootstrapping implements GqlPoolBase { id: ID! chain: GqlChain! @@ -495,6 +524,7 @@ union GqlPoolUnion = | GqlPoolElement | GqlPoolLiquidityBootstrapping | GqlPoolGyro + | GqlPoolFx union GqlPoolNestedUnion = GqlPoolLinearNested | GqlPoolComposableStableNested union GqlPoolTokenUnion = GqlPoolToken | GqlPoolTokenComposableStable | GqlPoolTokenLinear diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts index 9f2ff0d7e..2e3bd994e 100644 --- a/modules/pool/pool.resolvers.ts +++ b/modules/pool/pool.resolvers.ts @@ -94,6 +94,16 @@ const balancerResolvers: Resolvers = { poolGetGyroPools: async () => { return poolService.getGqlGyroPools(); }, + + poolGetFxPools: async (parent, { chains }) => { + const currentChain = headerChain(); + if (!chains && currentChain) { + chains = [currentChain]; + } else if (!chains) { + throw new Error('poolGetLinearPools error: Provide "chains" param'); + } + return poolService.getGqlFxPools(chains); + }, }, Mutation: { poolSyncAllPoolsFromSubgraph: async (parent, {}, context) => { diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts index 9461b541f..ba8e9d4de 100644 --- a/modules/pool/pool.service.ts +++ b/modules/pool/pool.service.ts @@ -8,6 +8,7 @@ import { GqlPoolBatchSwap, GqlPoolFeaturedPool, GqlPoolFeaturedPoolGroup, + GqlPoolFx, GqlPoolGyro, GqlPoolJoinExit, GqlPoolLinear, @@ -87,6 +88,10 @@ export class PoolService { return this.poolGqlLoaderService.getGyroPools(); } + public async getGqlFxPools(chains: Chain[]): Promise { + return this.poolGqlLoaderService.getFxPools(chains); + } + public async getPoolsCount(args: QueryPoolGetPoolsArgs): Promise { return this.poolGqlLoaderService.getPoolsCount(args); } From 5d63418f3c09cd1566d9fd6f8ffb3d24b971aa2c Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:58:52 +0100 Subject: [PATCH 10/23] subgraph pool to DB update --- modules/pool/lib/pool-creator.service.ts | 82 +++++++++++------------- modules/pool/subgraph-mapper.ts | 57 +++++++++++++++- 2 files changed, 92 insertions(+), 47 deletions(-) diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts index ebe49f0dc..6b7f0fef2 100644 --- a/modules/pool/lib/pool-creator.service.ts +++ b/modules/pool/lib/pool-creator.service.ts @@ -7,7 +7,7 @@ import { prismaPoolWithExpandedNesting } from '../../../prisma/prisma-types'; import { UserService } from '../../user/user.service'; import { prismaBulkExecuteOperations } from '../../../prisma/prisma-util'; import { networkContext } from '../../network/network-context.service'; -import { subgraphToPrisma } from '../subgraph-mapper'; +import { subgraphToPrismaCreate, subgraphToPrismaUpdate } from '../subgraph-mapper'; export class PoolCreatorService { constructor(private readonly userService: UserService) {} @@ -24,6 +24,13 @@ export class PoolCreatorService { const existingPools = await prisma.prismaPool.findMany({ where: { chain: this.chain } }); const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false); const sortedSubgraphPools = this.sortSubgraphPools(subgraphPools); + const allNestedTypePools = await prisma.prismaPool.findMany({ + where: { + chain: this.chain, + type: { in: [PrismaPoolType.LINEAR, PrismaPoolType.COMPOSABLE_STABLE] }, + }, + select: { id: true, address: true }, + }); const poolIds: string[] = []; @@ -34,42 +41,11 @@ export class PoolCreatorService { const existsInDb = !!existingPools.find((pool) => pool.id === subgraphPool.id); if (!existsInDb) { - await this.createPoolRecord(subgraphPool, blockNumber); + await this.createPoolRecord(subgraphPool, blockNumber, allNestedTypePools); poolIds.push(subgraphPool.id); - } else if (subgraphPool.poolType?.includes('Gyro')) { - await prisma.prismaPool.update({ - data: { - gyroData: { - update: { - id: subgraphPool.id, - alpha: subgraphPool.alpha || '', - beta: subgraphPool.beta || '', - sqrtAlpha: subgraphPool.sqrtAlpha || '', - sqrtBeta: subgraphPool.sqrtBeta || '', - root3Alpha: subgraphPool.root3Alpha || '', - c: subgraphPool.c || '', - s: subgraphPool.s || '', - lambda: subgraphPool.lambda || '', - tauAlphaX: subgraphPool.tauAlphaX || '', - tauAlphaY: subgraphPool.tauAlphaY || '', - tauBetaX: subgraphPool.tauBetaX || '', - tauBetaY: subgraphPool.tauBetaY || '', - u: subgraphPool.u || '', - v: subgraphPool.v || '', - w: subgraphPool.w || '', - z: subgraphPool.z || '', - dSq: subgraphPool.dSq || '', - }, - }, - }, - where: { - id_chain: { - id: subgraphPool.id, - chain: this.chain, - }, - }, - }); + } else { + await this.updatePoolRecord(subgraphPool, blockNumber, allNestedTypePools); } } @@ -193,18 +169,13 @@ export class PoolCreatorService { await prismaBulkExecuteOperations(operations); } - private async createPoolRecord(pool: BalancerPoolFragment, blockNumber: number) { - const poolType = this.mapSubgraphPoolTypeToPoolType(pool.poolType || ''); + private async createPoolRecord( + pool: BalancerPoolFragment, + blockNumber: number, + nestedPools: { id: string; address: string }[] = [], + ) { const poolTokens = pool.tokens || []; - const allNestedTypePools = await prisma.prismaPool.findMany({ - where: { - chain: this.chain, - type: { in: [PrismaPoolType.LINEAR, PrismaPoolType.COMPOSABLE_STABLE] }, - }, - select: { id: true, address: true }, - }); - await prisma.prismaToken.createMany({ skipDuplicates: true, data: [ @@ -225,7 +196,7 @@ export class PoolCreatorService { ], }); - const prismaPoolRecordWithAssociations = subgraphToPrisma(pool, this.chain, blockNumber, allNestedTypePools); + const prismaPoolRecordWithAssociations = subgraphToPrismaCreate(pool, this.chain, blockNumber, nestedPools); await prisma.prismaPool.create(prismaPoolRecordWithAssociations); @@ -246,6 +217,25 @@ export class PoolCreatorService { await this.userService.initWalletBalancesForPool(pool.id); } + private async updatePoolRecord( + pool: BalancerPoolFragment, + blockNumber: number, + nestedPools: { id: string; address: string }[] = [], + ) { + const prismaPoolRecordWithAssociations = subgraphToPrismaUpdate(pool, this.chain, blockNumber, nestedPools); + + // Update pool record and type specific data + await prisma.prismaPool.update({ + data: prismaPoolRecordWithAssociations, + where: { + id_chain: { + id: pool.id, + chain: this.chain, + }, + }, + }); + } + public async createAllTokensRelationshipForPool(poolId: string): Promise { const pool = await prisma.prismaPool.findUnique({ ...prismaPoolWithExpandedNesting, diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts index 38a451555..28e04c912 100644 --- a/modules/pool/subgraph-mapper.ts +++ b/modules/pool/subgraph-mapper.ts @@ -3,7 +3,7 @@ import { BalancerPoolFragment } from '../subgraphs/balancer-subgraph/generated/b import { AddressZero } from '@ethersproject/constants'; import * as dataMappers from './pool-data'; -export const subgraphToPrisma = ( +export const subgraphToPrismaCreate = ( pool: BalancerPoolFragment, chain: Chain, blockNumber: number, @@ -75,6 +75,61 @@ export const subgraphToPrisma = ( return prismaPoolRecordWithAssociations; }; +export const subgraphToPrismaUpdate = ( + pool: BalancerPoolFragment, + chain: Chain, + blockNumber: number, + nestedPools: { id: string; address: string }[], +) => { + const dbData = subgraphMapper(pool, chain, blockNumber, nestedPools); + const { id, ...baseWithoutId } = dbData.base; + + const prismaPoolRecordWithDataAssociations = { + ...baseWithoutId, + data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data. + linearData: + dbData.base.type === 'LINEAR' + ? { + update: { + ...(dbData.data as ReturnType), + }, + } + : undefined, + elementData: + dbData.base.type === 'ELEMENT' + ? { + update: { + ...(dbData.data as ReturnType), + }, + } + : undefined, + gyroData: ['GYRO', 'GYRO3', 'GYROE'].includes(dbData.base.type) + ? { + update: { + ...(dbData.data as ReturnType), + }, + } + : undefined, + linearDynamicData: + dbData.base.type === 'LINEAR' + ? { + update: { + ...(dbData.dynamicTypeData as ReturnType), + }, + } + : undefined, + stableDynamicData: ['STABLE', 'COMPOSABLE_STABLE', 'META_STABLE'].includes(dbData.base.type) + ? { + update: { + ...(dbData.dynamicTypeData as ReturnType), + }, + } + : undefined, + }; + + return prismaPoolRecordWithDataAssociations; +}; + const subgraphMapper = ( pool: BalancerPoolFragment, chain: Chain, From 65d9451c1c9f3a762c2ed3fb82efd6e0471eab63 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:59:23 +0100 Subject: [PATCH 11/23] obsolete poolSyncAllPoolTypesVersions --- modules/pool/lib/pool-creator.service.ts | 37 ------------------------ modules/pool/pool.gql | 1 - modules/pool/pool.resolvers.ts | 7 ----- modules/pool/pool.service.ts | 4 --- 4 files changed, 49 deletions(-) diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts index 6b7f0fef2..9ecb0ced4 100644 --- a/modules/pool/lib/pool-creator.service.ts +++ b/modules/pool/lib/pool-creator.service.ts @@ -1,6 +1,5 @@ import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; import { prisma } from '../../../prisma/prisma-client'; -import { ZERO_ADDRESS } from '@gnosis.pm/safe-core-sdk/dist/src/utils/constants'; import { PrismaPoolType } from '@prisma/client'; import _ from 'lodash'; import { prismaPoolWithExpandedNesting } from '../../../prisma/prisma-types'; @@ -294,42 +293,6 @@ export class PoolCreatorService { } } - public async updatePoolTypesAndVersionForAllPools() { - const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false); - - for (const subgraphPool of subgraphPools) { - // for the old phantom stable pool, we add it to the DB as type COMPOSABLE_STABLE with version 0 - let poolTypeVersion = subgraphPool.poolTypeVersion ? subgraphPool.poolTypeVersion : 1; - if (subgraphPool.poolType === 'StablePhantom') { - poolTypeVersion = 0; - } - - const poolType = this.mapSubgraphPoolTypeToPoolType(subgraphPool.poolType || ''); - - try { - await prisma.prismaPool.update({ - where: { id_chain: { chain: networkContext.chain, id: subgraphPool.id } }, - data: { - version: poolTypeVersion, - type: poolType, - }, - }); - } catch (e: any) { - // Some pools are filtered from the DB, like test pools, - // so we just ignore them without breaking the loop - const error = e.meta ? e.meta.cause : e; - console.error( - 'Error in updating pool versions: ', - error, - 'Network', - networkContext.chain, - 'Pool ID: ', - subgraphPool.id, - ); - } - } - } - private sortSubgraphPools(subgraphPools: BalancerPoolFragment[]) { return _.sortBy(subgraphPools, (pool) => { const poolType = this.mapSubgraphPoolTypeToPoolType(pool.poolType || ''); diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql index 91fac31fe..33172fd00 100644 --- a/modules/pool/pool.gql +++ b/modules/pool/pool.gql @@ -56,7 +56,6 @@ extend type Mutation { poolBlackListAddPool(poolId: String!): String! poolBlackListRemovePool(poolId: String!): String! poolDeletePool(poolId: String!): String! - poolSyncAllPoolTypesVersions: String! poolSyncPriceRateProviders: String! poolSyncProtocolYieldFeeExemptions: String! poolInitOnChainDataForAllPools: String! diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts index 2e3bd994e..416f2b04b 100644 --- a/modules/pool/pool.resolvers.ts +++ b/modules/pool/pool.resolvers.ts @@ -314,13 +314,6 @@ const balancerResolvers: Resolvers = { return 'success'; }, - poolSyncAllPoolTypesVersions: async (parent, {}, context) => { - isAdminRoute(context); - - await poolService.syncPoolTypeAndVersionForAllPools(); - - return 'success'; - }, poolSyncPriceRateProviders: async (parent, {}, context) => { isAdminRoute(context); diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts index ba8e9d4de..745a4e3c8 100644 --- a/modules/pool/pool.service.ts +++ b/modules/pool/pool.service.ts @@ -349,10 +349,6 @@ export class PoolService { await this.poolSyncService.setPoolsWithPreferredGaugesAsIncentivized(); } - public async syncPoolTypeAndVersionForAllPools() { - await this.poolCreatorService.updatePoolTypesAndVersionForAllPools(); - } - public async syncProtocolYieldFeeExemptionsForAllPools() { const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false); for (const subgraphPool of subgraphPools) { From 6aa8aac325567db7bc4332170106d9a7ca39cf56 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Tue, 9 Jan 2024 18:45:14 +0100 Subject: [PATCH 12/23] include pool tokens in subgraph sync --- modules/pool/subgraph-mapper.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts index 28e04c912..776ca57d5 100644 --- a/modules/pool/subgraph-mapper.ts +++ b/modules/pool/subgraph-mapper.ts @@ -87,6 +87,19 @@ export const subgraphToPrismaUpdate = ( const prismaPoolRecordWithDataAssociations = { ...baseWithoutId, data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data. + tokens: { + update: dbData.tokens.map((token) => ({ + where: { + id_chain: { + id: token.id, + chain: chain, + }, + }, + data: { + ...token, + }, + })), + }, linearData: dbData.base.type === 'LINEAR' ? { From 9c533b29b31cc6a72f3681575265249eed38b5c9 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Tue, 9 Jan 2024 19:09:17 +0100 Subject: [PATCH 13/23] obsolete poolReloadPoolTokenIndexes covered by syncAllPoolsFromSubgraph --- modules/pool/lib/pool-creator.service.ts | 21 --------------------- modules/pool/pool.gql | 1 - modules/pool/pool.resolvers.ts | 7 ------- modules/pool/pool.service.ts | 4 ---- 4 files changed, 33 deletions(-) diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts index 9ecb0ced4..435e905d9 100644 --- a/modules/pool/lib/pool-creator.service.ts +++ b/modules/pool/lib/pool-creator.service.ts @@ -272,27 +272,6 @@ export class PoolCreatorService { }); } - public async reloadPoolTokenIndexes(poolId: string): Promise { - const { pool: subgraphPool } = await this.balancerSubgraphService.getPool({ id: poolId }); - - if (!subgraphPool) { - throw new Error('Pool with id does not exist'); - } - - const poolTokens = subgraphPool.tokens || []; - - for (let i = 0; i < poolTokens.length; i++) { - const token = poolTokens[i]; - - await prisma.prismaPoolToken.update({ - where: { id_chain: { id: token.id, chain: this.chain } }, - data: { - index: token.index || subgraphPool.tokensList.findIndex((address) => address === token.address), - }, - }); - } - } - private sortSubgraphPools(subgraphPools: BalancerPoolFragment[]) { return _.sortBy(subgraphPools, (pool) => { const poolType = this.mapSubgraphPoolTypeToPoolType(pool.poolType || ''); diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql index 33172fd00..f249d880d 100644 --- a/modules/pool/pool.gql +++ b/modules/pool/pool.gql @@ -51,7 +51,6 @@ extend type Mutation { poolSyncPool(poolId: String!): String! poolReloadPoolNestedTokens(poolId: String!): String! poolReloadAllTokenNestedPoolIds: String! - poolReloadPoolTokenIndexes(poolId: String!): String! poolSetPoolsWithPreferredGaugesAsIncentivized: String! poolBlackListAddPool(poolId: String!): String! poolBlackListRemovePool(poolId: String!): String! diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts index 416f2b04b..6d14f760d 100644 --- a/modules/pool/pool.resolvers.ts +++ b/modules/pool/pool.resolvers.ts @@ -279,13 +279,6 @@ const balancerResolvers: Resolvers = { return 'success'; }, - poolReloadPoolTokenIndexes: async (parent, { poolId }, context) => { - isAdminRoute(context); - - await poolService.reloadPoolTokenIndexes(poolId); - - return 'success'; - }, poolSetPoolsWithPreferredGaugesAsIncentivized: async (parent, {}, context) => { isAdminRoute(context); diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts index 745a4e3c8..6bb48305d 100644 --- a/modules/pool/pool.service.ts +++ b/modules/pool/pool.service.ts @@ -341,10 +341,6 @@ export class PoolService { await this.poolCreatorService.reloadAllTokenNestedPoolIds(); } - public async reloadPoolTokenIndexes(poolId: string) { - await this.poolCreatorService.reloadPoolTokenIndexes(poolId); - } - public async setPoolsWithPreferredGaugesAsIncentivized() { await this.poolSyncService.setPoolsWithPreferredGaugesAsIncentivized(); } From 5497a1d4586a5d03ee2aa1c6f0d71f84e2b7ae1b Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Tue, 9 Jan 2024 19:44:04 +0100 Subject: [PATCH 14/23] obsolete poolReloadPoolNestedTokens covered by syncAllPoolsFromSubgraph --- modules/pool/lib/pool-creator.service.ts | 38 ++---------------------- modules/pool/pool.gql | 1 - modules/pool/pool.resolvers.ts | 7 ----- modules/pool/pool.service.ts | 4 --- 4 files changed, 2 insertions(+), 48 deletions(-) diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts index 435e905d9..a8bc5ca2b 100644 --- a/modules/pool/lib/pool-creator.service.ts +++ b/modules/pool/lib/pool-creator.service.ts @@ -81,42 +81,6 @@ export class PoolCreatorService { return Array.from(poolIds); } - public async reloadPoolNestedTokens(poolId: string): Promise { - const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false); - const poolToLoad = subgraphPools.find((pool) => pool.id === poolId); - - if (!poolToLoad) { - throw new Error('Pool with id does not exist'); - } - - const poolTokens = poolToLoad.tokens || []; - - for (let i = 0; i < poolTokens.length; i++) { - const token = poolTokens[i]; - - if (token.address === poolToLoad.address) { - continue; - } - - const nestedPool = subgraphPools.find((nestedPool) => { - const poolType = this.mapSubgraphPoolTypeToPoolType(nestedPool.poolType || ''); - - return ( - nestedPool.address === token.address && (poolType === 'LINEAR' || poolType === 'COMPOSABLE_STABLE') - ); - }); - - if (nestedPool) { - await prisma.prismaPoolToken.update({ - where: { id_chain: { id: token.id, chain: this.chain } }, - data: { nestedPoolId: nestedPool.id }, - }); - } - } - - await this.createAllTokensRelationshipForPool(poolId); - } - public async reloadAllTokenNestedPoolIds(): Promise { let operations: any[] = []; const pools = await prisma.prismaPool.findMany({ @@ -233,6 +197,8 @@ export class PoolCreatorService { }, }, }); + + await this.createAllTokensRelationshipForPool(pool.id); } public async createAllTokensRelationshipForPool(poolId: string): Promise { diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql index f249d880d..74ef66f6f 100644 --- a/modules/pool/pool.gql +++ b/modules/pool/pool.gql @@ -49,7 +49,6 @@ extend type Mutation { poolUpdateLifetimeValuesForAllPools: String! poolInitializeSnapshotsForPool(poolId: String!): String! poolSyncPool(poolId: String!): String! - poolReloadPoolNestedTokens(poolId: String!): String! poolReloadAllTokenNestedPoolIds: String! poolSetPoolsWithPreferredGaugesAsIncentivized: String! poolBlackListAddPool(poolId: String!): String! diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts index 6d14f760d..75262897c 100644 --- a/modules/pool/pool.resolvers.ts +++ b/modules/pool/pool.resolvers.ts @@ -265,13 +265,6 @@ const balancerResolvers: Resolvers = { return 'success'; }, - poolReloadPoolNestedTokens: async (parent, { poolId }, context) => { - isAdminRoute(context); - - await poolService.reloadPoolNestedTokens(poolId); - - return 'success'; - }, poolReloadAllTokenNestedPoolIds: async (parent, {}, context) => { isAdminRoute(context); diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts index 6bb48305d..9d5db753c 100644 --- a/modules/pool/pool.service.ts +++ b/modules/pool/pool.service.ts @@ -333,10 +333,6 @@ export class PoolService { await this.poolSnapshotService.createPoolSnapshotsForPoolsMissingSubgraphData(poolId); } - public async reloadPoolNestedTokens(poolId: string) { - await this.poolCreatorService.reloadPoolNestedTokens(poolId); - } - public async reloadAllTokenNestedPoolIds() { await this.poolCreatorService.reloadAllTokenNestedPoolIds(); } From d5fb8e848a7df9d98ad8f837ae7661e659b846e3 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Tue, 9 Jan 2024 20:12:12 +0100 Subject: [PATCH 15/23] obsolete poolSync mutations covered by syncAllPools --- modules/pool/pool.gql | 2 -- modules/pool/pool.resolvers.ts | 14 --------- modules/pool/pool.service.ts | 52 ---------------------------------- 3 files changed, 68 deletions(-) diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql index 74ef66f6f..db7656ce2 100644 --- a/modules/pool/pool.gql +++ b/modules/pool/pool.gql @@ -54,8 +54,6 @@ extend type Mutation { poolBlackListAddPool(poolId: String!): String! poolBlackListRemovePool(poolId: String!): String! poolDeletePool(poolId: String!): String! - poolSyncPriceRateProviders: String! - poolSyncProtocolYieldFeeExemptions: String! poolInitOnChainDataForAllPools: String! } diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts index 75262897c..bb8275e65 100644 --- a/modules/pool/pool.resolvers.ts +++ b/modules/pool/pool.resolvers.ts @@ -298,20 +298,6 @@ const balancerResolvers: Resolvers = { await poolService.deletePool(poolId); - return 'success'; - }, - poolSyncPriceRateProviders: async (parent, {}, context) => { - isAdminRoute(context); - - await poolService.syncPriceRateProvidersForAllPools(); - - return 'success'; - }, - poolSyncProtocolYieldFeeExemptions: async (parent, {}, context) => { - isAdminRoute(context); - - await poolService.syncProtocolYieldFeeExemptionsForAllPools(); - return 'success'; }, }, diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts index 9d5db753c..a697bcf10 100644 --- a/modules/pool/pool.service.ts +++ b/modules/pool/pool.service.ts @@ -341,58 +341,6 @@ export class PoolService { await this.poolSyncService.setPoolsWithPreferredGaugesAsIncentivized(); } - public async syncProtocolYieldFeeExemptionsForAllPools() { - const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false); - for (const subgraphPool of subgraphPools) { - const poolTokens = subgraphPool.tokens || []; - for (let i = 0; i < poolTokens.length; i++) { - const token = poolTokens[i]; - try { - await prisma.prismaPoolToken.update({ - where: { id_chain: { id: token.id, chain: networkContext.chain } }, - data: { - exemptFromProtocolYieldFee: token.isExemptFromYieldProtocolFee - ? token.isExemptFromYieldProtocolFee - : false, - }, - }); - } catch (e) { - console.error('Failed to update token ', token.id, ' error is: ', e); - } - } - } - } - - public async syncPriceRateProvidersForAllPools() { - const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false); - for (const subgraphPool of subgraphPools) { - if (!subgraphPool.priceRateProviders || !subgraphPool.priceRateProviders.length) continue; - - const poolTokens = subgraphPool.tokens || []; - for (let i = 0; i < poolTokens.length; i++) { - const token = poolTokens[i]; - - let priceRateProvider; - const data = subgraphPool.priceRateProviders.find( - (provider) => provider.token.address === token.address, - ); - priceRateProvider = data?.address; - if (!priceRateProvider) continue; - - try { - await prisma.prismaPoolToken.update({ - where: { id_chain: { id: token.id, chain: networkContext.chain } }, - data: { - priceRateProvider, - }, - }); - } catch (e) { - console.error('Failed to update token ', token.id, ' error is: ', e); - } - } - } - } - public async addToBlackList(poolId: string) { const category = await prisma.prismaPoolCategory.findFirst({ where: { poolId, chain: this.chain, category: 'BLACK_LISTED' }, From d6e71f0ff350bb6cb33647c1911486fed6b0b4c8 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 11 Jan 2024 18:01:27 +0100 Subject: [PATCH 16/23] fix pool type mapping for StablePhantom --- modules/pool/subgraph-mapper.test.ts | 30 +++++++++++++++++++--------- modules/pool/subgraph-mapper.ts | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/modules/pool/subgraph-mapper.test.ts b/modules/pool/subgraph-mapper.test.ts index 76a5fe62c..8f8ccb388 100644 --- a/modules/pool/subgraph-mapper.test.ts +++ b/modules/pool/subgraph-mapper.test.ts @@ -1,7 +1,7 @@ -import { subgraphToPrisma } from './subgraph-mapper'; +import { subgraphToPrismaCreate } from './subgraph-mapper'; import { poolFactory, poolTokenFactory } from '../../test/factories'; -describe('subgraphToPrisma', () => { +describe('subgraphToPrismaCreate', () => { const weightedPool = poolFactory.build({ poolType: 'Weighted', }); @@ -11,6 +11,11 @@ describe('subgraphToPrisma', () => { amp: '0.1', }); + const oldStablePool = poolFactory.build({ + poolType: 'StablePhantom', + amp: '0.1', + }); + const linearPool = poolFactory.build({ poolType: 'Linear', wrappedIndex: 1, @@ -34,38 +39,45 @@ describe('subgraphToPrisma', () => { }); it('should return correct object for weighted pool', () => { - const result = subgraphToPrisma(weightedPool, 'MAINNET', 1, []); + const result = subgraphToPrismaCreate(weightedPool, 'MAINNET', 1, []); expect(result.data.type).toBe('WEIGHTED'); }); it('should return correct object for stable pool', () => { - const result = subgraphToPrisma(stablePool, 'MAINNET', 1, []); + const result = subgraphToPrismaCreate(stablePool, 'MAINNET', 1, []); expect(result.data.type).toBe('COMPOSABLE_STABLE'); expect(result.data.stableDynamicData?.create.amp).toBe(stablePool.amp); }); + it('should return correct object for old stable pool', () => { + const result = subgraphToPrismaCreate(oldStablePool, 'MAINNET', 1, []); + expect(result.data.type).toBe('COMPOSABLE_STABLE'); + expect(result.data.version).toBe(0); + expect(result.data.stableDynamicData?.create.amp).toBe(oldStablePool.amp); + }); + it('should return correct object for linear pool', () => { - const result = subgraphToPrisma(linearPool, 'MAINNET', 1, []); + const result = subgraphToPrismaCreate(linearPool, 'MAINNET', 1, []); expect(result.data.type).toBe('LINEAR'); expect(result.data.linearDynamicData?.create.upperTarget).toBe(linearPool.upperTarget); expect(result.data.linearData?.create.wrappedIndex).toBe(linearPool.wrappedIndex); }); it('should return correct object for element pool', () => { - const result = subgraphToPrisma(elementPool, 'MAINNET', 1, []); + const result = subgraphToPrismaCreate(elementPool, 'MAINNET', 1, []); expect(result.data.type).toBe('ELEMENT'); expect(result.data.elementData?.create.principalToken).toBe(elementPool.principalToken); }); it('should return correct object for gyro pool', () => { - const result = subgraphToPrisma(gyroPool, 'MAINNET', 1, []); + const result = subgraphToPrismaCreate(gyroPool, 'MAINNET', 1, []); expect(result.data.type).toBe('GYROE'); expect(result.data.gyroData?.create.alpha).toBe(gyroPool.alpha); expect(result.data.gyroData?.create.tauAlphaX).toBe(gyroPool.tauAlphaX); }); it('should return correct object for fx pool', () => { - const result = subgraphToPrisma(fxPool, 'MAINNET', 1, []); + const result = subgraphToPrismaCreate(fxPool, 'MAINNET', 1, []); expect(result.data.type).toBe('FX'); expect(result.data.data['alpha']).toBe(gyroPool.alpha); }); @@ -83,7 +95,7 @@ describe('subgraphToPrisma', () => { }); it('should recognise nested pools', () => { - const result = subgraphToPrisma(poolWithNestedPools, 'MAINNET', 1, nestedPools); + const result = subgraphToPrismaCreate(poolWithNestedPools, 'MAINNET', 1, nestedPools); expect(result.data.type).toBe('COMPOSABLE_STABLE'); expect(result.data.tokens.createMany.data[0].nestedPoolId).toBe(linearPool.id); }); diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts index 776ca57d5..69b14381f 100644 --- a/modules/pool/subgraph-mapper.ts +++ b/modules/pool/subgraph-mapper.ts @@ -150,7 +150,7 @@ const subgraphMapper = ( nestedPools: { id: string; address: string }[], ) => { const type = mapSubgraphPoolTypeToPoolType(pool.poolType!); - const version = mapPoolTypeVersion(type, pool.poolTypeVersion!); + const version = mapPoolTypeVersion(pool.poolType!, pool.poolTypeVersion!); const base = { id: pool.id, From 63fd0b28fda394dd75a8eaebe308addde763a67e Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 11 Jan 2024 18:20:01 +0100 Subject: [PATCH 17/23] add nestedPool list when creating new pools --- modules/pool/lib/pool-creator.service.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts index a8bc5ca2b..d7d2eea66 100644 --- a/modules/pool/lib/pool-creator.service.ts +++ b/modules/pool/lib/pool-creator.service.ts @@ -68,11 +68,22 @@ export class PoolCreatorService { const sortedSubgraphPools = this.sortSubgraphPools(subgraphPools); const poolIds = new Set(); + const allNestedTypePools = [ + ...(await prisma.prismaPool.findMany({ + where: { + chain: this.chain, + type: { in: [PrismaPoolType.LINEAR, PrismaPoolType.COMPOSABLE_STABLE] }, + }, + select: { id: true, address: true }, + })), + ...sortedSubgraphPools.map((pool) => ({ id: pool.id, address: pool.address })), + ]; + for (const subgraphPool of sortedSubgraphPools) { const existsInDb = !!existingPools.find((pool) => pool.id === subgraphPool.id); if (!existsInDb) { - await this.createPoolRecord(subgraphPool, blockNumber); + await this.createPoolRecord(subgraphPool, blockNumber, allNestedTypePools); poolIds.add(subgraphPool.id); } @@ -135,7 +146,7 @@ export class PoolCreatorService { private async createPoolRecord( pool: BalancerPoolFragment, blockNumber: number, - nestedPools: { id: string; address: string }[] = [], + nestedPools: { id: string; address: string }[], ) { const poolTokens = pool.tokens || []; From 2dee404eadffebf75785c7582501e67f99e52642 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Fri, 12 Jan 2024 18:13:16 +0100 Subject: [PATCH 18/23] renaming pool.data to pool.poolTypeSpecificData --- modules/pool/lib/pool-creator.service.ts | 19 +++++++++++++++++-- modules/pool/lib/pool-gql-loader.service.ts | 2 +- modules/pool/pool.prisma | 2 +- modules/pool/subgraph-mapper.test.ts | 2 +- modules/pool/subgraph-mapper.ts | 4 ++-- modules/sor/sorV2/sorV2.service.ts | 2 +- .../migration.sql | 2 +- prisma/schema.prisma | 2 +- 8 files changed, 25 insertions(+), 10 deletions(-) diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts index d7d2eea66..26ef74e99 100644 --- a/modules/pool/lib/pool-creator.service.ts +++ b/modules/pool/lib/pool-creator.service.ts @@ -197,10 +197,25 @@ export class PoolCreatorService { nestedPools: { id: string; address: string }[] = [], ) { const prismaPoolRecordWithAssociations = subgraphToPrismaUpdate(pool, this.chain, blockNumber, nestedPools); + const { tokens, ...poolWithoutTokens } = prismaPoolRecordWithAssociations; + + // Make sure all tokens are there, for managed pools tokenlist can change + for (const token of tokens.update) { + await prisma.prismaPoolToken.upsert({ + where: token.where, + create: { + ...token.data, + poolId: pool.id, + chain: this.chain, + }, + update: { + ...token.data, + }, + }); + } - // Update pool record and type specific data await prisma.prismaPool.update({ - data: prismaPoolRecordWithAssociations, + data: poolWithoutTokens, where: { id_chain: { id: pool.id, diff --git a/modules/pool/lib/pool-gql-loader.service.ts b/modules/pool/lib/pool-gql-loader.service.ts index e910344af..4a108a781 100644 --- a/modules/pool/lib/pool-gql-loader.service.ts +++ b/modules/pool/lib/pool-gql-loader.service.ts @@ -594,7 +594,7 @@ export class PoolGqlLoaderService { dSq: pool.gyroData?.dSq || '', }; case 'FX': - const data = pool.data as FxData; + const data = pool.poolTypeSpecificData as FxData; return { __typename: 'GqlPoolFx', ...mappedData, diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma index 8bb8816ac..7fd90789f 100644 --- a/modules/pool/pool.prisma +++ b/modules/pool/pool.prisma @@ -18,7 +18,7 @@ model PrismaPool { linearData PrismaPoolLinearData? elementData PrismaPoolElementData? gyroData PrismaPoolGyroData? - data Json @default("{}") + poolTypeSpecificData Json @default("{}") tokens PrismaPoolToken[] diff --git a/modules/pool/subgraph-mapper.test.ts b/modules/pool/subgraph-mapper.test.ts index 8f8ccb388..0aa8889b0 100644 --- a/modules/pool/subgraph-mapper.test.ts +++ b/modules/pool/subgraph-mapper.test.ts @@ -79,7 +79,7 @@ describe('subgraphToPrismaCreate', () => { it('should return correct object for fx pool', () => { const result = subgraphToPrismaCreate(fxPool, 'MAINNET', 1, []); expect(result.data.type).toBe('FX'); - expect(result.data.data['alpha']).toBe(gyroPool.alpha); + expect(result.data.poolTypeSpecificData['alpha']).toBe(gyroPool.alpha); }); describe('nested pools', () => { diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts index 69b14381f..bf5dc0b02 100644 --- a/modules/pool/subgraph-mapper.ts +++ b/modules/pool/subgraph-mapper.ts @@ -14,7 +14,7 @@ export const subgraphToPrismaCreate = ( const prismaPoolRecordWithAssociations = { data: { ...dbData.base, - data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data. + poolTypeSpecificData: dbData.data, tokens: { createMany: { data: dbData.tokens, @@ -86,7 +86,7 @@ export const subgraphToPrismaUpdate = ( const prismaPoolRecordWithDataAssociations = { ...baseWithoutId, - data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data. + poolTypeSpecificData: dbData.data, tokens: { update: dbData.tokens.map((token) => ({ where: { diff --git a/modules/sor/sorV2/sorV2.service.ts b/modules/sor/sorV2/sorV2.service.ts index 8ec3a59fb..14f3e8509 100644 --- a/modules/sor/sorV2/sorV2.service.ts +++ b/modules/sor/sorV2/sorV2.service.ts @@ -430,7 +430,7 @@ export class SorV2Service implements SwapService { name: 'n/a', }; if (['FX'].includes(rawPool.poolType)) { - const data = prismaPool.data as FxData; + const data = prismaPool.poolTypeSpecificData as FxData; rawPool = { ...rawPool, ...data, diff --git a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql index c08b112b7..6032639db 100644 --- a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql +++ b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql @@ -1,2 +1,2 @@ -- AlterTable -ALTER TABLE "PrismaPool" ADD COLUMN "data" JSONB NOT NULL DEFAULT '{}'; +ALTER TABLE "PrismaPool" ADD COLUMN "poolTypeSpecificData" JSONB NOT NULL DEFAULT '{}'; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index ad5882758..fec2c4536 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -64,7 +64,7 @@ model PrismaPool { linearData PrismaPoolLinearData? elementData PrismaPoolElementData? gyroData PrismaPoolGyroData? - data Json @default("{}") + poolTypeSpecificData Json @default("{}") tokens PrismaPoolToken[] From 64ca22b49e9a87fd4bc71e14a88a322b066fdba9 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Fri, 12 Jan 2024 18:49:27 +0100 Subject: [PATCH 19/23] import all of the functions directly to have references in the header --- modules/pool/subgraph-mapper.ts | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts index bf5dc0b02..22026a3df 100644 --- a/modules/pool/subgraph-mapper.ts +++ b/modules/pool/subgraph-mapper.ts @@ -1,7 +1,7 @@ import { Chain, PrismaPoolType } from '@prisma/client'; import { BalancerPoolFragment } from '../subgraphs/balancer-subgraph/generated/balancer-subgraph-types'; import { AddressZero } from '@ethersproject/constants'; -import * as dataMappers from './pool-data'; +import { fx, gyro, linear, element, stableDynamic, linearDynamic } from './pool-data'; export const subgraphToPrismaCreate = ( pool: BalancerPoolFragment, @@ -266,24 +266,24 @@ const mapPoolTypeVersion = (poolType: string, poolTypeVersion: number): number = }; const dataMapper = { - ELEMENT: dataMappers.element, - FX: dataMappers.fx, - GYRO: dataMappers.gyro, - GYRO3: dataMappers.gyro, - GYROE: dataMappers.gyro, - LINEAR: dataMappers.linear, + ELEMENT: element, + FX: fx, + GYRO: gyro, + GYRO3: gyro, + GYROE: gyro, + LINEAR: linear, }; const dynamicMapper = { - STABLE: dataMappers.stableDynamic, - COMPOSABLE_STABLE: dataMappers.stableDynamic, - META_STABLE: dataMappers.stableDynamic, - LINEAR: dataMappers.linearDynamic, + STABLE: stableDynamic, + COMPOSABLE_STABLE: stableDynamic, + META_STABLE: stableDynamic, + LINEAR: linearDynamic, }; -export type FxData = ReturnType; -export type GyroData = ReturnType; -export type LinearData = ReturnType; -export type ElementData = ReturnType; -export type StableDynamicData = ReturnType; -export type LinearDynamicData = ReturnType; +export type FxData = ReturnType; +export type GyroData = ReturnType; +export type LinearData = ReturnType; +export type ElementData = ReturnType; +export type StableDynamicData = ReturnType; +export type LinearDynamicData = ReturnType; From 48c1f9082bf27d287115ce8021dbccd785e7c590 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Fri, 12 Jan 2024 19:01:28 +0100 Subject: [PATCH 20/23] delete cleanup based on constraints --- modules/pool/pool.service.ts | 45 ------------------------------------ 1 file changed, 45 deletions(-) diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts index a697bcf10..7cd8eb9ac 100644 --- a/modules/pool/pool.service.ts +++ b/modules/pool/pool.service.ts @@ -379,13 +379,8 @@ export class PoolService { where: { chain: this.chain, poolId: poolId }, }); - const poolTokenIds = poolTokens.map((poolToken) => poolToken.id); const poolTokenAddresses = poolTokens.map((poolToken) => poolToken.address); - await prisma.prismaPoolSnapshot.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - await prisma.prismaTokenType.deleteMany({ where: { chain: this.chain, tokenAddress: pool.address }, }); @@ -394,50 +389,10 @@ export class PoolService { where: { chain: this.chain, poolId: poolId }, }); - await prisma.prismaPoolTokenDynamicData.deleteMany({ - where: { chain: this.chain, poolTokenId: { in: poolTokenIds } }, - }); - await prisma.prismaTokenDynamicData.deleteMany({ where: { chain: this.chain, tokenAddress: { in: poolTokenAddresses } }, }); - await prisma.prismaPoolToken.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - - await prisma.prismaPoolDynamicData.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - - await prisma.prismaPoolToken.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - - await prisma.prismaPoolLinearData.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - - await prisma.prismaPoolGyroData.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - - await prisma.prismaPoolExpandedTokens.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - - await prisma.prismaPoolLinearDynamicData.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - - await prisma.prismaPoolAprItem.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - - await prisma.prismaPoolSwap.deleteMany({ - where: { chain: this.chain, poolId: poolId }, - }); - const poolStaking = await prisma.prismaPoolStaking.findMany({ where: { chain: this.chain, poolId: poolId }, }); From 00fd3e0de01f7d9ae284f3e09bd417769e69595c Mon Sep 17 00:00:00 2001 From: franz Date: Thu, 18 Jan 2024 13:54:26 +0100 Subject: [PATCH 21/23] renaming --- modules/pool/subgraph-mapper.ts | 40 +++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts index 22026a3df..7737baf58 100644 --- a/modules/pool/subgraph-mapper.ts +++ b/modules/pool/subgraph-mapper.ts @@ -14,7 +14,7 @@ export const subgraphToPrismaCreate = ( const prismaPoolRecordWithAssociations = { data: { ...dbData.base, - poolTypeSpecificData: dbData.data, + poolTypeSpecificData: dbData.staticTypeData, tokens: { createMany: { data: dbData.tokens, @@ -31,7 +31,7 @@ export const subgraphToPrismaCreate = ( ? { create: { id: dbData.base.id, - ...(dbData.data as ReturnType), + ...(dbData.staticTypeData as ReturnType), }, } : undefined, @@ -40,7 +40,7 @@ export const subgraphToPrismaCreate = ( ? { create: { id: dbData.base.id, - ...(dbData.data as ReturnType), + ...(dbData.staticTypeData as ReturnType), }, } : undefined, @@ -48,7 +48,7 @@ export const subgraphToPrismaCreate = ( ? { create: { id: dbData.base.id, - ...(dbData.data as ReturnType), + ...(dbData.staticTypeData as ReturnType), }, } : undefined, @@ -57,7 +57,7 @@ export const subgraphToPrismaCreate = ( ? { create: { id: dbData.base.id, - ...(dbData.dynamicTypeData as ReturnType), + ...(dbData.dynamicTypeData as ReturnType), }, } : undefined, @@ -65,7 +65,7 @@ export const subgraphToPrismaCreate = ( ? { create: { id: dbData.base.id, - ...(dbData.dynamicTypeData as ReturnType), + ...(dbData.dynamicTypeData as ReturnType), }, } : undefined, @@ -86,7 +86,7 @@ export const subgraphToPrismaUpdate = ( const prismaPoolRecordWithDataAssociations = { ...baseWithoutId, - poolTypeSpecificData: dbData.data, + poolTypeSpecificData: dbData.staticTypeData, tokens: { update: dbData.tokens.map((token) => ({ where: { @@ -104,7 +104,7 @@ export const subgraphToPrismaUpdate = ( dbData.base.type === 'LINEAR' ? { update: { - ...(dbData.data as ReturnType), + ...(dbData.staticTypeData as ReturnType), }, } : undefined, @@ -112,14 +112,14 @@ export const subgraphToPrismaUpdate = ( dbData.base.type === 'ELEMENT' ? { update: { - ...(dbData.data as ReturnType), + ...(dbData.staticTypeData as ReturnType), }, } : undefined, gyroData: ['GYRO', 'GYRO3', 'GYROE'].includes(dbData.base.type) ? { update: { - ...(dbData.data as ReturnType), + ...(dbData.staticTypeData as ReturnType), }, } : undefined, @@ -127,14 +127,14 @@ export const subgraphToPrismaUpdate = ( dbData.base.type === 'LINEAR' ? { update: { - ...(dbData.dynamicTypeData as ReturnType), + ...(dbData.dynamicTypeData as ReturnType), }, } : undefined, stableDynamicData: ['STABLE', 'COMPOSABLE_STABLE', 'META_STABLE'].includes(dbData.base.type) ? { update: { - ...(dbData.dynamicTypeData as ReturnType), + ...(dbData.dynamicTypeData as ReturnType), }, } : undefined, @@ -175,12 +175,14 @@ const subgraphMapper = ( totalLiquidity: Math.max(parseFloat(pool.totalLiquidity), 0), }; - const data: ReturnType | {} = Object.keys(dataMapper).includes(type) - ? dataMapper[type as keyof typeof dataMapper](pool) + const staticTypeData: ReturnType | {} = Object.keys( + staticTypeDataMapper, + ).includes(type) + ? staticTypeDataMapper[type as keyof typeof staticTypeDataMapper](pool) : {}; - const dynamicTypeData = Object.keys(dynamicMapper).includes(type) - ? dynamicMapper[type as keyof typeof dynamicMapper](pool, blockNumber) + const dynamicTypeData = Object.keys(dynamicTypeDataMapper).includes(type) + ? dynamicTypeDataMapper[type as keyof typeof dynamicTypeDataMapper](pool, blockNumber) : {}; const tokens = @@ -211,7 +213,7 @@ const subgraphMapper = ( base, dynamicData, tokens, - data, + staticTypeData, dynamicTypeData, }; }; @@ -265,7 +267,7 @@ const mapPoolTypeVersion = (poolType: string, poolTypeVersion: number): number = return version; }; -const dataMapper = { +const staticTypeDataMapper = { ELEMENT: element, FX: fx, GYRO: gyro, @@ -274,7 +276,7 @@ const dataMapper = { LINEAR: linear, }; -const dynamicMapper = { +const dynamicTypeDataMapper = { STABLE: stableDynamic, COMPOSABLE_STABLE: stableDynamic, META_STABLE: stableDynamic, From 8fb588af2340ca52ef3e96cd6e12b8529849a0e5 Mon Sep 17 00:00:00 2001 From: franz Date: Thu, 18 Jan 2024 14:51:32 +0100 Subject: [PATCH 22/23] rename column --- modules/pool/lib/pool-gql-loader.service.ts | 2 +- modules/pool/pool.prisma | 2 +- modules/pool/subgraph-mapper.ts | 4 ++-- modules/sor/sorV2/sorV2.service.ts | 2 +- .../20231221154118_pools_data_json_column/migration.sql | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/pool/lib/pool-gql-loader.service.ts b/modules/pool/lib/pool-gql-loader.service.ts index 4a108a781..de731f980 100644 --- a/modules/pool/lib/pool-gql-loader.service.ts +++ b/modules/pool/lib/pool-gql-loader.service.ts @@ -594,7 +594,7 @@ export class PoolGqlLoaderService { dSq: pool.gyroData?.dSq || '', }; case 'FX': - const data = pool.poolTypeSpecificData as FxData; + const data = pool.staticTypeData as FxData; return { __typename: 'GqlPoolFx', ...mappedData, diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma index 7fd90789f..e9189664e 100644 --- a/modules/pool/pool.prisma +++ b/modules/pool/pool.prisma @@ -18,7 +18,7 @@ model PrismaPool { linearData PrismaPoolLinearData? elementData PrismaPoolElementData? gyroData PrismaPoolGyroData? - poolTypeSpecificData Json @default("{}") + staticTypeData Json @default("{}") tokens PrismaPoolToken[] diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts index 7737baf58..9d09f0692 100644 --- a/modules/pool/subgraph-mapper.ts +++ b/modules/pool/subgraph-mapper.ts @@ -14,7 +14,7 @@ export const subgraphToPrismaCreate = ( const prismaPoolRecordWithAssociations = { data: { ...dbData.base, - poolTypeSpecificData: dbData.staticTypeData, + staticTypeData: dbData.staticTypeData, tokens: { createMany: { data: dbData.tokens, @@ -86,7 +86,7 @@ export const subgraphToPrismaUpdate = ( const prismaPoolRecordWithDataAssociations = { ...baseWithoutId, - poolTypeSpecificData: dbData.staticTypeData, + staticTypeData: dbData.staticTypeData, tokens: { update: dbData.tokens.map((token) => ({ where: { diff --git a/modules/sor/sorV2/sorV2.service.ts b/modules/sor/sorV2/sorV2.service.ts index 14f3e8509..55672579b 100644 --- a/modules/sor/sorV2/sorV2.service.ts +++ b/modules/sor/sorV2/sorV2.service.ts @@ -430,7 +430,7 @@ export class SorV2Service implements SwapService { name: 'n/a', }; if (['FX'].includes(rawPool.poolType)) { - const data = prismaPool.poolTypeSpecificData as FxData; + const data = prismaPool.staticTypeData as FxData; rawPool = { ...rawPool, ...data, diff --git a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql index 6032639db..873e5ef60 100644 --- a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql +++ b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql @@ -1,2 +1,2 @@ -- AlterTable -ALTER TABLE "PrismaPool" ADD COLUMN "poolTypeSpecificData" JSONB NOT NULL DEFAULT '{}'; +ALTER TABLE "PrismaPool" ADD COLUMN "staticTypeData" JSONB NOT NULL DEFAULT '{}'; From 9eb0ea204d9624a4e501461e70563478250a62de Mon Sep 17 00:00:00 2001 From: franz Date: Thu, 18 Jan 2024 15:02:29 +0100 Subject: [PATCH 23/23] prisma schema --- prisma/schema.prisma | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index fec2c4536..f3320019f 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -64,7 +64,7 @@ model PrismaPool { linearData PrismaPoolLinearData? elementData PrismaPoolElementData? gyroData PrismaPoolGyroData? - poolTypeSpecificData Json @default("{}") + staticTypeData Json @default("{}") tokens PrismaPoolToken[]