Skip to content
This repository has been archived by the owner on May 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #1399 from connext/store-action
Browse files Browse the repository at this point in the history
Store action
  • Loading branch information
ArjunBhuptani authored Aug 20, 2020
2 parents 6692175 + e348c8d commit 71c5afa
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 2 deletions.
154 changes: 154 additions & 0 deletions modules/node/migrations/1597957131361-store-latest-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class storeLatestAction1597957131361 implements MigrationInterface {
name = "storeLatestAction1597957131361";

public async up(queryRunner: QueryRunner): Promise<void> {
// 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<void> {
// 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,
);
}
}
2 changes: 1 addition & 1 deletion modules/node/src/appInstance/appInstance.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
MultiAssetMultiPartyCoinTransferInterpreterParamsJson,
SingleAssetTwoPartyCoinTransferInterpreterParamsJson,
} from "@connext/types";
import { BigNumber, constants } from "ethers";
import { BigNumber } from "ethers";
import {
Column,
CreateDateColumn,
Expand Down
13 changes: 12 additions & 1 deletion modules/node/src/cfCore/cfCore.store.spec.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -67,6 +69,7 @@ describe("CFCoreStore", () => {
configService = moduleRef.get<ConfigService>(ConfigService);
cacheService = moduleRef.get<CacheService>(CacheService);
channelRepository = moduleRef.get<ChannelRepository>(ChannelRepository);
appRepository = moduleRef.get<AppInstanceRepository>(AppInstanceRepository);
chainId = configService.getSupportedChains()[0];
});

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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);
}
});
});
Expand Down
2 changes: 2 additions & 0 deletions modules/node/src/database/database.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -139,6 +140,7 @@ export const migrations = [
updateTxEnum1595439120210,
addAppIdTx1596488084652,
transactionAppFlag1596924706697,
storeLatestAction1597957131361,
];

@Injectable()
Expand Down

0 comments on commit 71c5afa

Please sign in to comment.