Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blockchainTriggerFilter & deploy url check #93

Merged
merged 4 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ainize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export default class Ainize {
if (!serviceUrl) {
serviceUrl = `https://${serviceName}.ainetwork.xyz`;
}
serviceUrl = serviceUrl.replace(/\/$/, '');
const servicePath = Path.app(serviceName).status();
await this.handler.subscribe(servicePath, resolve);
await this.appController.createApp({ appName: serviceName, serviceUrl, billingConfig });
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/serviceController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default class ServiceController {
}

async chargeCredit(serviceName: string, amount: number): Promise<string> {
this.checkRunning(serviceName);
await this.checkRunning(serviceName);
const transferKey = Date.now();
const userAddress = this.ain.getAddress();
const depositAddress = await this.getDepositAddress(serviceName);
Expand Down Expand Up @@ -78,7 +78,7 @@ export default class ServiceController {
}

async request(serviceName: string, requestData: any) : Promise<any> {
this.checkRunning(serviceName);
await this.checkRunning(serviceName);
const result = await new Promise(async (resolve, reject) => {
const requestKey = Date.now();
const requesterAddress = this.ain.getAddress();
Expand Down
23 changes: 3 additions & 20 deletions src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getChangeBalanceOp, getResponseOp, getWriteHistoryOp } from "./utils/op
import { HISTORY_TYPE, RESPONSE_STATUS, deposit, request, response } from "./types/type";
import { buildTxBody } from "./utils/builder";
import AinModule from "./ain";
import { extractDataFromDepositRequest, extractDataFromServiceRequest } from "./utils/extractor";

export default class Internal {
private ain = AinModule.getInstance();
Expand Down Expand Up @@ -35,28 +36,10 @@ export default class Internal {
}

getDataFromServiceRequest(req: Request) {
if(!req.body.valuePath[1] || !req.body.valuePath[3] || !req.body.valuePath[4] || !req.body.value) {
throw new Error("Not from service request");
}
const requestData: request = {
appName: req.body.valuePath[1],
requesterAddress: req.body.auth.addr,
requestKey: req.body.valuePath[4],
requestData: req.body.value,
}
return requestData;
return extractDataFromServiceRequest(req);
}

private getDataFromDepositRequest(req: Request) {
if(!req.body.valuePath[1] || !req.body.valuePath[4] || !req.body.value) {
throw new Error("Not from deposit request");
}
const depositData: deposit = {
transferKey: req.body.valuePath[4],
transferValue: req.body.value,
appName: req.body.valuePath[1],
requesterAddress: req.body.auth.addr,
}
return depositData;
return extractDataFromDepositRequest(req);
}
}
44 changes: 16 additions & 28 deletions src/middlewares/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,39 @@
import { Request, Response, NextFunction } from "express";
import NodeCache = require("node-cache");
import { extractTriggerDataFromRequest } from "../utils/extractor";
import AinModule from "../ain";
import _ from "lodash";

export default class Middleware {
cache: NodeCache;
constructor(cache: NodeCache,) {
private ain = AinModule.getInstance();
constructor(cache: NodeCache) {
this.cache = cache;
}

/**
* Middleware for AI Network trigger call. It will filter duplicated request triggered by same transaction.
* It will pass request which is not from AI Network trigger.
* It will reject requests which is not from AI Network trigger.
* @param {Request} request - Request data
* @param {Res} response - Response data
* @param {NextFunction} next - Next function
* @returns Null if if request is duplicated.
*/
triggerDuplicateFilter = (req: Request, res: Response, next: NextFunction) => {
if (req.body.transaction.hash === undefined){
next();
}
const txHash = req.body.transaction.hash;
blockchainTriggerFilter = async (req: Request, res: Response, next: NextFunction) => {
//check if request is from blockchain trigger
const { triggerPath, triggerValue, txHash } = extractTriggerDataFromRequest(req);
const result = await this.ain.getValue(triggerPath);
// if request is first reque st, set cache
if (this.cache.get(txHash) && this.cache.get(txHash) !== "error") {
res.send("duplicated");
return;
}
// if request is first request, set cache
this.cache.set(txHash, "in_progress", 500);
next();
_.isEqual(result, triggerValue) ? res.send("not from blockChain") : next();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result와 triggerValue 가 같으면 not from blockChain인가요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반대로 적은 것 같네요 수정하였습니다!

}
/**
* Middleware for AI Network trigger call. It will filter duplicated request triggered by same transaction.
* It will pass request which is not from AI Network trigger.
* You can set filter inside specific api.
* @param {Request} request - Request data
* @param {Res} response - Response data
* @returns Null if if request is duplicated.
/**
* DEPRECATED
* use blockchainTriggerFilter instead
*/
triggerFilter = (req: Request, res: Response) => {
if (req.body.fid || req.body.transaction){
res.send("not from trigger");
return;
}
const txHash = req.body.transaction.hash;
if (this.cache.get(txHash) && this.cache.get(txHash) !== "error") {
res.send("duplicated");
return;
}
this.cache.set(txHash, "in_progress", 500);
}
triggerDuplicateFilter = this.blockchainTriggerFilter;
}
45 changes: 45 additions & 0 deletions src/utils/extractor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Request } from "express";
import { deposit, request } from "../types/type";

export const extractDataFromServiceRequest = (req:Request) => {
if(!req.body.valuePath[1] || !req.body.valuePath[3] || !req.body.valuePath[4] || !req.body.value) {
throw new Error("Not from service request");
}
const requestData: request = {
appName: req.body.valuePath[1],
requesterAddress: req.body.auth.addr,
requestKey: req.body.valuePath[4],
requestData: req.body.value,
}
return requestData;
}

export const extractTriggerDataFromRequest = (req:Request) => {
if(req?.body?.valuePath === undefined) {
throw new Error("Not from trigger request");
}
let path = '';
req.body.valuePath.forEach((value:string) => {
path += value + '/';
}
);
const triggerData = {
triggerPath: path,
triggerValue: req.body.value,
txHash: req.body.txhash,
}
return triggerData
}

export const extractDataFromDepositRequest = (req:Request) => {
if(!req.body.valuePath[1] || !req.body.valuePath[4] || !req.body.value) {
throw new Error("Not from deposit request");
}
const depositData: deposit = {
transferKey: req.body.valuePath[4],
transferValue: req.body.value,
appName: req.body.valuePath[1],
requesterAddress: req.body.auth.addr,
}
return depositData;
}