Skip to content

Commit

Permalink
add risk parser
Browse files Browse the repository at this point in the history
  • Loading branch information
doerfli committed Nov 19, 2024
1 parent 792d7e8 commit d574cdb
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 5 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"dev": "ts-node-dev src/main.ts",
"build": " tsc --project tsconfig.json",
"postinstall": "$npm_execpath run typechainGif",
"typechainGif": "D=./node_modules/@etherisc/gif-next/artifacts/contracts/ && typechain --target ethers-v6 --out-dir src/generated/contracts/gif $D/product/IApplicationService.sol/IApplicationService.json $D/product/IPolicyService.sol/IPolicyService.json $D/pool/IPoolService.sol/IPoolService.json $D/pool/IBundleService.sol/IBundleService.json $D/oracle/IOracleService.sol/IOracleService.json $D/registry/ChainNft.sol/ChainNft.json $D/registry/IRegistry.sol/IRegistry.json $D/instance/IInstance.sol/IInstance.json $D/instance/IInstanceService.sol/IInstanceService.json $D/instance/InstanceReader.sol/InstanceReader.json $D/instance/module/IPolicy.sol/IPolicy.json $D/instance/module/IRisk.sol/IRisk.json $D/shared/IComponentService.sol/IComponentService.json"
"typechainGif": "D=./node_modules/@etherisc/gif-next/artifacts/contracts/ && typechain --target ethers-v6 --out-dir src/generated/contracts/gif $D/product/IRiskService.sol/IRiskService.json $D/product/IApplicationService.sol/IApplicationService.json $D/product/IPolicyService.sol/IPolicyService.json $D/pool/IPoolService.sol/IPoolService.json $D/pool/IBundleService.sol/IBundleService.json $D/oracle/IOracleService.sol/IOracleService.json $D/registry/ChainNft.sol/ChainNft.json $D/registry/IRegistry.sol/IRegistry.json $D/instance/IInstance.sol/IInstance.json $D/instance/IInstanceService.sol/IInstanceService.json $D/instance/InstanceReader.sol/InstanceReader.json $D/instance/module/IPolicy.sol/IPolicy.json $D/instance/module/IRisk.sol/IRisk.json $D/shared/IComponentService.sol/IComponentService.json"
},
"author": "",
"license": "Apache-2.0",
Expand Down
17 changes: 17 additions & 0 deletions prisma/migrations/20241119154054_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- CreateTable
CREATE TABLE "Risk" (
"productNftId" BIGINT NOT NULL,
"riskId" TEXT NOT NULL,
"locked" BOOLEAN NOT NULL DEFAULT false,
"closed" BOOLEAN NOT NULL DEFAULT false,
"created_blockNumber" INTEGER NOT NULL,
"created_timestamp" BIGINT NOT NULL,
"created_txHash" TEXT NOT NULL,
"created_from" TEXT NOT NULL,
"modified_blockNumber" INTEGER NOT NULL,
"modified_timestamp" BIGINT NOT NULL,
"modified_txHash" TEXT NOT NULL,
"modified_from" TEXT NOT NULL,

CONSTRAINT "Risk_pkey" PRIMARY KEY ("productNftId","riskId")
);
18 changes: 18 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,21 @@ model Component {
modified_txHash String
modified_from String
}

model Risk {
productNftId BigInt
riskId String
locked Boolean @default(false)
closed Boolean @default(false)
created_blockNumber Int
created_timestamp BigInt
created_txHash String
created_from String
modified_blockNumber Int
modified_timestamp BigInt
modified_txHash String
modified_from String
// compound primary key
@@id([productNftId, riskId])
}
22 changes: 18 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import PolicyProcessor from './policy_processor';
import { Policy } from './types/policy';
import ComponentProcessor from './component_processor';
import { Component } from './types/component';
import RiskProcessor from './risk_processor';
import { Risk } from './types/risk';

dotenv.config();

Expand All @@ -29,23 +31,26 @@ class Main {
private instanceProcessor: InstanceProcessor;
private policyProcessor: PolicyProcessor;
private componentProcessor: ComponentProcessor;
private riskProcessor: RiskProcessor;

constructor(prisma: PrismaClient) {
this.dune = new DuneApi();
this.nftProcessor = new NftProcessor(prisma);
this.instanceProcessor = new InstanceProcessor(prisma);
this.componentProcessor = new ComponentProcessor(prisma);
this.policyProcessor = new PolicyProcessor(prisma);
this.riskProcessor = new RiskProcessor(prisma);
}

public async main(): Promise<void> {
const gifEvents = await this.dune.getLatestResult(DUNE_QUERY_ID_GIF_EVENTS, 0);
const { nfts, instances, policies, components } = await this.parseGifEvents(gifEvents);
const { nfts, instances, policies, components, risks } = await this.parseGifEvents(gifEvents);

await this.nftProcessor.persistNfts(Array.from(nfts.values()));
await this.instanceProcessor.persistInstances(Array.from(instances.values()));
await this.policyProcessor.persistPolicies(Array.from(policies.values()));
await this.componentProcessor.persistComponents(Array.from(components.values()));
await this.riskProcessor.persistRisks(Array.from(risks.values()));

for (const nft of nfts.values()) {
logger.info(`NFT: ${nft.nftId} - ${ObjectType[nft.objectType]} - ${nft.objectAddress} - ${nft.owner}`);
Expand All @@ -65,12 +70,14 @@ class Main {
nfts: Map<BigInt, Nft>,
instances: Map<BigInt, Instance>,
policies: Map<BigInt, Policy>,
components: Map<BigInt, Component>
components: Map<BigInt, Component>,
risks: Map<string, Risk>,
}>
{
const nfts = new Map<BigInt, Nft>();
const instances = new Map<BigInt, Instance>();
const components = new Map<BigInt, Component>();
const risks = new Map<string, Risk>();
const policies = new Map<BigInt, Policy>();

for (const event of gifEvents) {
Expand All @@ -88,7 +95,14 @@ class Main {
break;
case 'LogComponentServiceRegistered':
await this.componentProcessor.processComponentRegisteredEvent(event, components);
break;
break;
case 'LogRiskServiceRiskCreated':
await this.riskProcessor.processRiskCreatedEvent(event, risks);
break;
// TODO: LogRiskServiceRiskUpdated
// TODO: LogRiskServiceRiskLocked
// TODO: LogRiskServiceRiskUnlocked
// TODO: LogRiskServiceRiskClosed
case 'LogApplicationServiceApplicationCreated':
await this.policyProcessor.processApplicationCreatedEvent(event, policies);
break;
Expand All @@ -110,7 +124,7 @@ class Main {
}
}

return { nfts, instances, policies, components };
return { nfts, instances, policies, components, risks };
}
}

Expand Down
101 changes: 101 additions & 0 deletions src/risk_processor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { PrismaClient } from "@prisma/client";
import { IRiskService__factory } from "./generated/contracts/gif";
import { logger } from "./logger";
import { DecodedLogEntry } from "./types/logdata";
import { Risk } from "./types/risk";

export default class RiskProcessor {
private prisma: PrismaClient;

constructor(prisma: PrismaClient) {
this.prisma = prisma;
}

async persistRisks(risks: Risk[]): Promise<void> {
for (const risk of risks) {
await this.prisma.risk.upsert({
where: { productNftId_riskId: { productNftId: risk.productNftId as bigint, riskId: risk.riskId } },
update: {
locked: risk.locked,
closed: risk.closed,
modified_blockNumber: risk.modified.blockNumber,
modified_timestamp: risk.modified.timestamp as bigint,
modified_txHash: risk.modified.txHash,
modified_from: risk.modified.from
},
create: {
productNftId: risk.productNftId as bigint,
riskId: risk.riskId,
locked: risk.locked,
closed: risk.closed,
created_blockNumber: risk.created.blockNumber,
created_timestamp: risk.created.timestamp as bigint,
created_txHash: risk.created.txHash,
created_from: risk.created.from,
modified_blockNumber: risk.modified.blockNumber,
modified_timestamp: risk.modified.timestamp as bigint,
modified_txHash: risk.modified.txHash,
modified_from: risk.modified.from
}
});
}
}

async processRiskCreatedEvent(event: DecodedLogEntry, risks: Map<string, Risk>): Promise<Map<string, Risk>> {
if (event.event_name !== 'LogRiskServiceRiskCreated') {
throw new Error(`Invalid event type ${event.event_name}`);
}

logger.info(`Processing risk creation event ${event.tx_hash} - ${event.event_name} - ${event.data}`);
const data = this.decodeRiskServiceEvent(event);
if (data === null || data === undefined) {
logger.error(`Failed to decode event ${event.tx_hash} - ${event.event_name} - ${event.data}`);
return risks;
}
if (data.name !== 'LogRiskServiceRiskCreated') {
throw new Error(`Invalid event name ${data.name}`);
}

const productNftId = data.args[0] as BigInt;
const riskId = data.args[1] as string;
const key = `${productNftId}_${riskId}`;

const risk = {
productNftId,
riskId,
locked: false,
closed: false,
created: {
blockNumber: event.block_number,
timestamp:BigInt(new Date(event.block_time).getTime()),
txHash: event.tx_hash,
from: event.tx_from
},
modified: {
blockNumber: event.block_number,
timestamp:BigInt(new Date(event.block_time).getTime()),
txHash: event.tx_hash,
from: event.tx_from
}
} as Risk;
risks.set(key, risk);
return risks;
}

decodeRiskServiceEvent(event: DecodedLogEntry) {
const topic0 = event.topic0;
let topic1 = event.topic1;
if (topic1 === null || topic1 === undefined || topic1 === '') {
topic1 = '0x';
}
let topic2 = event.topic2;
if (topic2 === null || topic2 === undefined || topic2 === '') {
topic2 = '0x';
}
let topic3 = event.topic3;
if (topic3 === null || topic3 === undefined || topic3 === '') {
topic3 = '0x';
}
return IRiskService__factory.createInterface().parseLog({ topics: [topic0, topic1, topic2, topic3], data: event.data });
}
}
20 changes: 20 additions & 0 deletions src/types/risk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ObjectType } from "./objecttype";

export interface Risk {
productNftId: BigInt;
riskId: string;
locked: boolean;
closed: boolean;
created: {
blockNumber: number;
timestamp: BigInt;
txHash: string;
from: string;
}
modified: {
blockNumber: number;
timestamp: BigInt;
txHash: string;
from: string;
}
}

0 comments on commit d574cdb

Please sign in to comment.