Skip to content

Commit

Permalink
feat: horoscope handler (staging) (#567)
Browse files Browse the repository at this point in the history
* feat: add docs for horoscope handler

* feat: update doc

* feat: update doc

* feat: add horoscope handler service

* fix: remove doc horoscope handler

* fix: add order for query

* fix: group transaction and block into one by lodash

* fix: add empty array txs for block has no txs

* feat: add tx_msg_index to query event tx

* fix: split query event block (not in block query)

* fix: get block in resultGroupBy (return array)
  • Loading branch information
fibonacci998 authored Jan 2, 2024
1 parent ce5a19e commit 6a98152
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/common/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ export const SERVICE = {
key: 'CrawlIBCIcs20Service',
name: 'v1.CrawlIBCIcs20Service',
},
HoroscopeHandlerService: {
key: 'HoroscopeHandlerService',
path: 'v1.HoroscopeHandlerService',
getData: {
key: 'getData',
path: 'v1.HoroscopeHandlerService.getData',
},
},
},
};

Expand Down
7 changes: 7 additions & 0 deletions src/services/api-gateways/api_gateway.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import ApiGateway from 'moleculer-web';
import { ServiceBroker } from 'moleculer';
import { Service } from '@ourparentcenter/moleculer-decorators-extended';

import BaseService from '../../base/base.service';
import { bullBoardMixin } from '../../mixins/bullBoard/bullBoard.mixin';

Expand Down Expand Up @@ -40,6 +41,12 @@ import { bullBoardMixin } from '../../mixins/bullBoard/bullBoard.mixin';
'v1.job.redecode-tx',
],
},
{
path: '/auth',
autoAliases: true,
mappingPolicy: 'restrict',
whitelist: ['v1.horoscope-handler.getDataByChainId'],
},
],
// empty cors object will have moleculer to generate handler for preflight request and CORS header which allow all origin
cors: {},
Expand Down
48 changes: 48 additions & 0 deletions src/services/api-gateways/horoscope_handler.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Post, Service } from '@ourparentcenter/moleculer-decorators-extended';
import { Context, ServiceBroker } from 'moleculer';
import { SERVICE } from '../../common';
import BaseService from '../../base/base.service';
import networks from '../../../network.json' assert { type: 'json' };

@Service({
name: 'horoscope-handler',
version: 1,
})
export default class HoroscopeHandlerService extends BaseService {
public constructor(public broker: ServiceBroker) {
super(broker);
}

@Post('/getDataByChainId', {
name: 'getDataByChainId',
params: {
chainid: {
type: 'string',
optional: false,
enum: networks.map((network) => network.chainId),
},
startBlock: {
type: 'number',
optional: false,
},
endBlock: {
type: 'number',
optional: false,
},
},
})
async getDataByChainId(
ctx: Context<
{ chainid: string; startBlock: number; endBlock: number },
Record<string, unknown>
>
) {
const selectedChain = networks.find(
(network) => network.chainId === ctx.params.chainid
);
return this.broker.call(
`${SERVICE.V1.HoroscopeHandlerService.getData.path}@${selectedChain?.moleculerNamespace}`,
ctx.params
);
}
}
121 changes: 121 additions & 0 deletions src/services/horoscope-handler/handler.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import {
Action,
Service,
} from '@ourparentcenter/moleculer-decorators-extended';
import { Context, ServiceBroker } from 'moleculer';
import _ from 'lodash';
import BaseService from '../../base/base.service';
import { SERVICE } from '../../common';
import { Block, Transaction, Event } from '../../models';
import networks from '../../../network.json' assert { type: 'json' };

@Service({
name: SERVICE.V1.HoroscopeHandlerService.key,
version: 1,
})
export default class HoroscopeHandlerService extends BaseService {
public constructor(public broker: ServiceBroker) {
super(broker);
}

@Action({
name: SERVICE.V1.HoroscopeHandlerService.getData.key,
params: {
chainid: {
type: 'string',
optional: false,
enum: networks.map((network) => network.chainId),
},
startBlock: {
type: 'number',
optional: false,
},
endBlock: {
type: 'number',
optional: false,
},
},
})
public async getData(
ctx: Context<
{ chainid: string; startBlock: number; endBlock: number },
Record<string, unknown>
>
) {
// query to get data
const { startBlock, endBlock } = ctx.params;
const queryBlock = Block.query()
.select('height', 'hash', 'time')
.where('height', '>=', startBlock)
.andWhere('height', '<', endBlock)
.orderBy('height', 'asc');

const queryEventBlock = Event.query()
.select('type', 'source', 'block_height as height')
.withGraphFetched('attributes')
.modifyGraph('attributes', (builder) => {
builder.select('key', 'value');
})
.whereIn('source', [
Event.SOURCE.BEGIN_BLOCK_EVENT,
Event.SOURCE.END_BLOCK_EVENT,
])
.andWhere('block_height', '>=', startBlock)
.andWhere('block_height', '<', endBlock)
.orderBy('block_height')
.orderBy('id');

const queryTransaction = Transaction.query()
.select('height', 'hash', 'code', 'codespace', 'memo', 'index')
.withGraphFetched('messages')
.withGraphFetched('events.[attributes]')
.modifyGraph('messages', (builder) => {
builder
.select('type', 'sender', 'content', 'index')
.whereNull('parent_id');
})
.modifyGraph('events', (builder) => {
builder.select('type', 'source', 'tx_msg_index');
})
.modifyGraph('events.[attributes]', (builder) => {
builder.select('key', 'value');
})
.where('height', '>=', startBlock)
.andWhere('height', '<', endBlock)
.orderBy('height', 'asc')
.orderBy('index', 'asc');
const [listBlock, listTransaction, listEventBlock] = await Promise.all([
queryBlock,
queryTransaction,
queryEventBlock,
]);

const resultGroupBy = _.groupBy(
[...listBlock, ...listTransaction, ...listEventBlock],
'height'
);
const listData: any[] = [];
Object.keys(resultGroupBy).forEach((height) => {
if (resultGroupBy[height].length > 0) {
if (resultGroupBy[height][0] instanceof Block) {
const block: any = resultGroupBy[height].filter(
(e) => e instanceof Block
)[0];
const eventBlocks = resultGroupBy[height].filter(
(e) => e instanceof Event
);
const txs = resultGroupBy[height].filter(
(e) => e instanceof Transaction
);
block.events = eventBlocks.length === 0 ? [] : eventBlocks;
block.txs = txs.length === 0 ? [] : txs;
listData.push(block);
} else {
throw Error('Block not found');
}
}
});
// handler response
return listData;
}
}

0 comments on commit 6a98152

Please sign in to comment.