81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
import { IChain } from 'chain/allchain'
|
|
import { retryEthBlockNumber } from 'chain/chain.api'
|
|
import { IScriptionCfg } from 'interface/IScriptionCfg'
|
|
import logger from 'logger/logger'
|
|
import { RedisClient } from 'redis/RedisClient'
|
|
import { getPastBlocksIter } from 'utils/block.util'
|
|
import { formatDate } from 'utils/date.util'
|
|
|
|
export class BlockSyncSvr {
|
|
chainCfg: IChain
|
|
scriptionCfgs: IScriptionCfg[] = []
|
|
fromBlock: number = Number.MAX_SAFE_INTEGER
|
|
batchCount: number = 0
|
|
redisKey = ''
|
|
rpc = ''
|
|
constructor(_chainCfg: IChain, _scriptionCfgs: IScriptionCfg[]) {
|
|
this.chainCfg = _chainCfg
|
|
this.scriptionCfgs = _scriptionCfgs
|
|
this.rpc = _chainCfg.rpc.split('|')[0]
|
|
for (let cfg of _scriptionCfgs) {
|
|
this.fromBlock = Math.min(this.fromBlock, cfg.fromBlock)
|
|
if (cfg.rpc) {
|
|
this.rpc = cfg.rpc
|
|
}
|
|
}
|
|
this.redisKey = `blocknum_${this.chainCfg.id}`
|
|
}
|
|
|
|
async execute() {
|
|
let currentBlock = await retryEthBlockNumber(this.rpc)
|
|
let blockStr = await new RedisClient().get(this.redisKey)
|
|
if (blockStr) {
|
|
this.fromBlock = Math.max(parseInt(blockStr), this.fromBlock)
|
|
}
|
|
this.batchCount = parseInt(currentBlock.result, 16) - this.fromBlock
|
|
if (this.batchCount <= 0) {
|
|
return
|
|
}
|
|
let blocks = getPastBlocksIter({
|
|
chainId: this.chainCfg.id,
|
|
rpc: this.rpc,
|
|
fromBlock: this.fromBlock,
|
|
amount: this.batchCount,
|
|
})
|
|
await this.processBlockDatas(blocks)
|
|
}
|
|
|
|
async processBlockDatas(iterator: any) {
|
|
let count = 0
|
|
for (const getPastBlockPromise of iterator) {
|
|
const blocks = await getPastBlockPromise
|
|
for (const block of blocks) {
|
|
// await BlockData.saveBlock(block)
|
|
count++
|
|
if (!block.transactions || block.transactions.length === 0) {
|
|
continue
|
|
}
|
|
for (let i = 0; i < block.transactions.length; i++) {
|
|
const tx = block.transactions[i]
|
|
if (block.timestamp) {
|
|
tx.blockTime = parseInt(block.timestamp, 16)
|
|
tx.dateTag = formatDate(new Date(tx.blockTime * 1000))
|
|
}
|
|
for (let j = 0; j < this.scriptionCfgs.length; j++) {
|
|
const cfg = this.scriptionCfgs[j]
|
|
|
|
if (cfg.filter && cfg.filter(tx)) {
|
|
try {
|
|
await cfg.process(tx)
|
|
} catch (err) {
|
|
logger.error('process tx error: ', err.message || err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
}
|