From a071f199595e9e6817505f29d57bba75e7d3f343 Mon Sep 17 00:00:00 2001 From: LayneHaber Date: Thu, 20 Aug 2020 15:00:24 -0600 Subject: [PATCH 1/5] remove unused --- modules/node/src/appInstance/appInstance.entity.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/node/src/appInstance/appInstance.entity.ts b/modules/node/src/appInstance/appInstance.entity.ts index 32d6096eea..b0d3788847 100644 --- a/modules/node/src/appInstance/appInstance.entity.ts +++ b/modules/node/src/appInstance/appInstance.entity.ts @@ -8,7 +8,7 @@ import { MultiAssetMultiPartyCoinTransferInterpreterParamsJson, SingleAssetTwoPartyCoinTransferInterpreterParamsJson, } from "@connext/types"; -import { BigNumber, constants } from "ethers"; +import { BigNumber } from "ethers"; import { Column, CreateDateColumn, From 81fdd6a309397c71c5d7917ad39178003cb338e3 Mon Sep 17 00:00:00 2001 From: LayneHaber Date: Thu, 20 Aug 2020 15:00:32 -0600 Subject: [PATCH 2/5] update remove_app_instance --- .../1597957131361-store-latest-action.ts | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 modules/node/migrations/1597957131361-store-latest-action.ts diff --git a/modules/node/migrations/1597957131361-store-latest-action.ts b/modules/node/migrations/1597957131361-store-latest-action.ts new file mode 100644 index 0000000000..8833e6f43c --- /dev/null +++ b/modules/node/migrations/1597957131361-store-latest-action.ts @@ -0,0 +1,154 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class removeAppCommitments1595210814094 implements MigrationInterface { + name = "removeAppCommitments1595210814094"; + + public async up(queryRunner: QueryRunner): Promise { + // Update remove app instance to set the latest state of the app + await queryRunner.query( + `DROP FUNCTION IF EXISTS remove_app_instance(jsonb,jsonb,jsonb);`, + undefined, + ); + + await queryRunner.query( + ` + CREATE OR REPLACE FUNCTION remove_app_instance( + removed_app JSONB, + free_balance_app_instance JSONB, + signed_free_balance_update JSONB + ) RETURNS TEXT AS $$ + DECLARE + remove_app_result TEXT; + remove_set_state_result TEXT; + remove_conditional_result TEXT; + update_free_balance_result TEXT; + update_set_state_result TEXT; + BEGIN + UPDATE "app_instance" SET + "type" = 'UNINSTALLED', + "channelMultisigAddress" = NULL, + "updatedAt" = CURRENT_TIMESTAMP, + "latestState" = removed_app->'latestState', + "latestAction" = removed_app->'latestAction', + "stateTimeout" = removed_app->>'stateTimeout', + "latestVersionNumber" = (removed_app->>'latestVersionNumber')::INTEGER + WHERE "identityHash" = removed_app->>'identityHash' + RETURNING "identityHash" INTO remove_app_result; + + DELETE FROM "set_state_commitment" + WHERE "appIdentityHash" = removed_app->>'identityHash'; + + DELETE FROM "conditional_transaction_commitment" + WHERE "appIdentityHash" = removed_app->>'identityHash'; + + UPDATE "app_instance" SET + "latestState" = free_balance_app_instance->'latestState', + "stateTimeout" = free_balance_app_instance->>'stateTimeout', + "latestVersionNumber" = (free_balance_app_instance->>'latestVersionNumber')::INTEGER, + "updatedAt" = CURRENT_TIMESTAMP + WHERE "identityHash" = free_balance_app_instance->>'identityHash' + RETURNING "identityHash" INTO update_free_balance_result; + + UPDATE "set_state_commitment" SET + "appIdentity" = signed_free_balance_update->'appIdentity', + "appStateHash" = signed_free_balance_update->>'appStateHash', + "challengeRegistryAddress" = signed_free_balance_update->>'challengeRegistryAddress', + "signatures" = signed_free_balance_update->'signatures', + "stateTimeout" = signed_free_balance_update->>'stateTimeout', + "versionNumber" = (signed_free_balance_update->>'versionNumber')::INTEGER, + "transactionData" = signed_free_balance_update->>'transactionData', + "updatedAt" = CURRENT_TIMESTAMP + WHERE "appIdentityHash" = free_balance_app_instance->>'identityHash' + RETURNING "appIdentityHash" INTO update_set_state_result; + + IF remove_app_result IS NULL OR update_free_balance_result IS NULL OR update_set_state_result IS NULL + THEN + RAISE EXCEPTION + 'Operation could not be completed: remove_app_result -> %, update_free_balance_result -> %, update_set_state_result -> %', + remove_app_result, + update_free_balance_result, + update_set_state_result; + END IF; + + RETURN remove_app_result; + END; + $$ LANGUAGE plpgsql; + `, + undefined, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + // Return procedure to previous migration (remove-app-commitments) + await queryRunner.query( + `DROP FUNCTION IF EXISTS remove_app_instance(jsonb,jsonb,jsonb);`, + undefined, + ); + + await queryRunner.query( + ` + CREATE OR REPLACE FUNCTION remove_app_instance( + removed_app JSONB, + free_balance_app_instance JSONB, + signed_free_balance_update JSONB + ) RETURNS TEXT AS $$ + DECLARE + remove_app_result TEXT; + remove_set_state_result TEXT; + remove_conditional_result TEXT; + update_free_balance_result TEXT; + update_set_state_result TEXT; + BEGIN + UPDATE "app_instance" SET + "type" = 'UNINSTALLED', + "channelMultisigAddress" = NULL, + "updatedAt" = CURRENT_TIMESTAMP, + "latestState" = removed_app->'latestState', + "stateTimeout" = removed_app->>'stateTimeout', + "latestVersionNumber" = (removed_app->>'latestVersionNumber')::INTEGER + WHERE "identityHash" = removed_app->>'identityHash' + RETURNING "identityHash" INTO remove_app_result; + + DELETE FROM "set_state_commitment" + WHERE "appIdentityHash" = removed_app->>'identityHash'; + + DELETE FROM "conditional_transaction_commitment" + WHERE "appIdentityHash" = removed_app->>'identityHash'; + + UPDATE "app_instance" SET + "latestState" = free_balance_app_instance->'latestState', + "stateTimeout" = free_balance_app_instance->>'stateTimeout', + "latestVersionNumber" = (free_balance_app_instance->>'latestVersionNumber')::INTEGER, + "updatedAt" = CURRENT_TIMESTAMP + WHERE "identityHash" = free_balance_app_instance->>'identityHash' + RETURNING "identityHash" INTO update_free_balance_result; + + UPDATE "set_state_commitment" SET + "appIdentity" = signed_free_balance_update->'appIdentity', + "appStateHash" = signed_free_balance_update->>'appStateHash', + "challengeRegistryAddress" = signed_free_balance_update->>'challengeRegistryAddress', + "signatures" = signed_free_balance_update->'signatures', + "stateTimeout" = signed_free_balance_update->>'stateTimeout', + "versionNumber" = (signed_free_balance_update->>'versionNumber')::INTEGER, + "transactionData" = signed_free_balance_update->>'transactionData', + "updatedAt" = CURRENT_TIMESTAMP + WHERE "appIdentityHash" = free_balance_app_instance->>'identityHash' + RETURNING "appIdentityHash" INTO update_set_state_result; + + IF remove_app_result IS NULL OR update_free_balance_result IS NULL OR update_set_state_result IS NULL + THEN + RAISE EXCEPTION + 'Operation could not be completed: remove_app_result -> %, update_free_balance_result -> %, update_set_state_result -> %', + remove_app_result, + update_free_balance_result, + update_set_state_result; + END IF; + + RETURN remove_app_result; + END; + $$ LANGUAGE plpgsql; + `, + undefined, + ); + } +} From ccb34d4f53bf91dd42716100144eb424166f0e69 Mon Sep 17 00:00:00 2001 From: LayneHaber Date: Thu, 20 Aug 2020 15:22:53 -0600 Subject: [PATCH 3/5] fix name --- modules/node/migrations/1597957131361-store-latest-action.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/node/migrations/1597957131361-store-latest-action.ts b/modules/node/migrations/1597957131361-store-latest-action.ts index 8833e6f43c..7a0d480be8 100644 --- a/modules/node/migrations/1597957131361-store-latest-action.ts +++ b/modules/node/migrations/1597957131361-store-latest-action.ts @@ -1,7 +1,7 @@ import { MigrationInterface, QueryRunner } from "typeorm"; -export class removeAppCommitments1595210814094 implements MigrationInterface { - name = "removeAppCommitments1595210814094"; +export class storeLatestAction1597957131361 implements MigrationInterface { + name = "storeLatestAction1597957131361"; public async up(queryRunner: QueryRunner): Promise { // Update remove app instance to set the latest state of the app From 52151e6742c003cd3d15f6e34424c131350781bd Mon Sep 17 00:00:00 2001 From: LayneHaber Date: Thu, 20 Aug 2020 15:22:59 -0600 Subject: [PATCH 4/5] add migration --- modules/node/src/database/database.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/node/src/database/database.service.ts b/modules/node/src/database/database.service.ts index 43e5a1b7cd..eeb180014a 100644 --- a/modules/node/src/database/database.service.ts +++ b/modules/node/src/database/database.service.ts @@ -70,6 +70,7 @@ import { removeAppCommitments1595210814094 } from "../../migrations/159521081409 import { updateTxEnum1595439120210 } from "../../migrations/1595439120210-update-tx-enum"; import { addAppIdTx1596488084652 } from "../../migrations/1596488084652-add-app-id-tx"; import { transactionAppFlag1596924706697 } from "../../migrations/1596924706697-transaction-app-flag"; +import { storeLatestAction1597957131361 } from "../../migrations/1597957131361-store-latest-action"; export const entities = [ AppInstance, @@ -139,6 +140,7 @@ export const migrations = [ updateTxEnum1595439120210, addAppIdTx1596488084652, transactionAppFlag1596924706697, + storeLatestAction1597957131361, ]; @Injectable() From e348c8dbd49f121992bed93446bdc1fe2e334e41 Mon Sep 17 00:00:00 2001 From: LayneHaber Date: Thu, 20 Aug 2020 15:23:20 -0600 Subject: [PATCH 5/5] add test --- modules/node/src/cfCore/cfCore.store.spec.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/node/src/cfCore/cfCore.store.spec.ts b/modules/node/src/cfCore/cfCore.store.spec.ts index 48cc20de15..3c421c0bfd 100644 --- a/modules/node/src/cfCore/cfCore.store.spec.ts +++ b/modules/node/src/cfCore/cfCore.store.spec.ts @@ -1,5 +1,5 @@ import { AppInstanceJson } from "@connext/types"; -import { toBN, toBNJson } from "@connext/utils"; +import { toBN, toBNJson, getRandomBytes32 } from "@connext/utils"; import { Test } from "@nestjs/testing"; import { TypeOrmModule } from "@nestjs/typeorm"; import { getConnection } from "typeorm"; @@ -33,11 +33,13 @@ import { CFCoreStore } from "./cfCore.store"; import { ChallengeRepository, ProcessedBlockRepository } from "../challenge/challenge.repository"; import { CacheModule } from "../caching/cache.module"; import { CacheService } from "../caching/cache.service"; +import { AppType } from "../appInstance/appInstance.entity"; describe("CFCoreStore", () => { let cfCoreStore: CFCoreStore; let configService: ConfigService; let channelRepository: ChannelRepository; + let appRepository: AppInstanceRepository; let cacheService: CacheService; let chainId: number; @@ -67,6 +69,7 @@ describe("CFCoreStore", () => { configService = moduleRef.get(ConfigService); cacheService = moduleRef.get(CacheService); channelRepository = moduleRef.get(ChannelRepository); + appRepository = moduleRef.get(AppInstanceRepository); chainId = configService.getSupportedChains()[0]; }); @@ -355,6 +358,8 @@ describe("CFCoreStore", () => { appIdentityHash: channelJson.freeBalanceAppInstance!.identityHash, versionNumber: toBNJson(chainId), }); + const action = { preImage: getRandomBytes32() }; + appInstance.latestAction = action; for (let index = 0; index < 3; index++) { await cfCoreStore.removeAppInstance( @@ -383,6 +388,12 @@ describe("CFCoreStore", () => { freeBalanceAppInstance: updatedFreeBalance, monotonicNumProposedApps: 2, }); + const app = await appRepository.findByIdentityHash(appInstance.identityHash); + expect(app.type).to.be.eq(AppType.UNINSTALLED); + expect(app.latestAction).to.containSubset(action); + expect(app.latestState).to.containSubset(appInstance.latestState); + expect(app.stateTimeout).to.be.eq(appInstance.stateTimeout); + expect(app.latestVersionNumber).to.be.eq(appInstance.latestVersionNumber); } }); });