From 4975240eec0b9dca7bb1852b61d8ebcdecbaf732 Mon Sep 17 00:00:00 2001 From: cgeek <cem.moreau@gmail.com> Date: Thu, 9 Jan 2020 19:33:56 +0100 Subject: [PATCH] [enh] add `search [pattern]` command --- app/modules/dump.ts | 114 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 3 deletions(-) diff --git a/app/modules/dump.ts b/app/modules/dump.ts index 95148fd22..7e15e7d5c 100644 --- a/app/modules/dump.ts +++ b/app/modules/dump.ts @@ -11,11 +11,12 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. +import {exec} from "child_process" import {ConfDTO} from "../lib/dto/ConfDTO" import {Server} from "../../server" import {moment} from "../lib/common-libs/moment" import {DBBlock} from "../lib/db/DBBlock" -import {SindexEntry} from "../lib/indexer" +import {FullIindexEntry, SindexEntry} from "../lib/indexer" import {BlockDTO} from "../lib/dto/BlockDTO" import {Underscore} from "../lib/common-libs/underscore" import {dumpWotWizard} from "./dump/wotwizard/wotwizard.dump" @@ -23,6 +24,11 @@ import {OtherConstants} from "../lib/other_constants" import {Querable, querablep} from "../lib/common-libs/querable" import {dumpBlocks, dumpForks} from "./dump/blocks/dump.blocks" import {newResolveTimeoutPromise} from "../lib/common-libs/timeout-promise" +import {readFileSync} from "fs" +import {IdentityDTO} from "../lib/dto/IdentityDTO" +import {CertificationDTO, ShortCertificationDTO} from "../lib/dto/CertificationDTO" +import {MembershipDTO} from "../lib/dto/MembershipDTO" +import {RevocationDTO, ShortRevocation} from "../lib/dto/RevocationDTO" const Table = require('cli-table') @@ -111,6 +117,57 @@ module.exports = { // Save DB await server.disconnect(); } + }, { + name: 'search [pattern]', + desc: 'Dumps data of the blockchain matching given pattern.', + logs: false, + preventIfRunning: true, + + onDatabaseExecute: async (server:Server, conf:ConfDTO, program:any, params:any) => { + const pattern: string = params[0] || '' + + try { + + const files: string[] = await new Promise((res, rej) => exec(`grep -r ${pattern} ${server.home}/${server.conf.currency} -l`, (err, stdout) => { + if (err) return rej(err) + console.log(stdout) + res(stdout.split('\n').filter(l => l)) + })) + + const blocks = Underscore.sortBy(await findBlocksMatching(pattern, files), b => b.number) + + const events: { b: BlockDTO, event: (IdentityDTO|ShortCertificationDTO|MembershipDTO|ShortRevocation) }[] = [] + for (const b of blocks) { + b.identities.filter(i => i.includes(pattern)).forEach(i => { + events.push({ b, event: IdentityDTO.fromInline(i) }) + }) + b.certifications.filter(c => c.includes(pattern)).forEach(c => { + events.push({ b, event: CertificationDTO.fromInline(c) }) + }) + b.joiners.concat(b.actives).concat(b.leavers).filter(m => m.includes(pattern)).forEach(m => { + events.push({ b, event: MembershipDTO.fromInline(m) }) + }) + b.revoked.filter(m => m.includes(pattern)).forEach(r => { + events.push({ b, event: RevocationDTO.fromInline(r) }) + }) + } + + for (const e of events) { + if ((e.event as IdentityDTO).uid) { + const date = await getDateForBlock(e.b) + const idty = e.event as IdentityDTO + console.log('%s: new identity %s (created on %s)', date, idty.uid, await getDateFor(server, idty.buid as string)) + } + } + + console.log(events.map(e => e.event)) + + } catch (e) { + console.error(e) + } + // Save DB + await server.disconnect(); + } }, { name: 'dump-ww', desc: 'Dumps WotWizard export.', @@ -121,6 +178,21 @@ module.exports = { } } +async function findBlocksMatching(pattern: string, files: string[]) { + const matchingBlocks: BlockDTO[] = [] + for (const f of files) { + const blocks: any[] = JSON.parse(await readFileSync(f, 'utf8')).blocks + for (const jsonBlock of blocks) { + const b = BlockDTO.fromJSONObject(jsonBlock) + const raw = b.getRawSigned() + if (raw.includes(pattern)) { + matchingBlocks.push(b) + } + } + } + return matchingBlocks +} + async function dumpCurrent(server: Server) { const current = await server.dal.getCurrentBlockOrNull() if (!current) { @@ -229,8 +301,9 @@ function dump(rows: any[], columns: string[]) { } async function dumpHistory(server: Server, pub: string) { - const irows = await server.dal.iindexDAL.findRawWithOrder({ pub }, [['writtenOn', false]]) - const mrows = await server.dal.mindexDAL.findRawWithOrder({ pub }, [['writtenOn', false]]) + const irows = (await server.dal.iindexDAL.findRawWithOrder({ pub }, [['writtenOn', false]])).filter(r => pub ? r.pub === pub : true) + const mrows = (await server.dal.mindexDAL.findRawWithOrder({ pub }, [['writtenOn', false]])).filter(r => pub ? r.pub === pub : true) + const crows = (await server.dal.cindexDAL.findRawWithOrder({ pub }, [['writtenOn', false]])).filter(r => pub ? r.issuer === pub || r.receiver === pub: true) console.log('----- IDENTITY -----') for (const e of irows) { const date = await getDateFor(server, e.written_on) @@ -259,6 +332,28 @@ async function dumpHistory(server: Server, pub: string) { console.log('Non displayable MINDEX entry') } } + console.log('----- CERTIFICATION -----') + crows.forEach(crow => { + console.log(JSON.stringify(crow)) + }) + for (const e of crows) { + const dateW = await getDateFor(server, e.written_on) + const dateC = await getDateForBlockNumber(server, e.created_on) + if (e.receiver === pub) { + const issuer = await server.dal.getWrittenIdtyByPubkey(e.issuer) as FullIindexEntry + if (e.op === 'UPDATE') { + console.log('%s : %s: from %s (update)', dateC, dateW, issuer.uid) + } + else { + console.log('%s : %s: from %s', dateC, dateW, issuer.uid) + } + // } else if (e.issuer === pub) { + // const receiver = await server.dal.getWrittenIdtyByPubkey(e.receiver) as FullIindexEntry + // console.log('%s: to ', date, receiver.uid) + } else { + // console.log('Non displayable CINDEX entry') + } + } } async function dumpWot(server: Server) { @@ -274,6 +369,19 @@ async function getDateFor(server: Server, blockstamp: string) { return formatTimestamp(b.medianTime) + ' (#' + bnumberPadded + ')' } +async function getDateForBlockNumber(server: Server, number: number) { + const b = (await server.dal.getBlock(number)) as DBBlock + const s = " " + b.number + const bnumberPadded = s.substr(s.length - 6) + return formatTimestamp(b.medianTime) + ' (#' + bnumberPadded + ')' +} + +async function getDateForBlock(b: BlockDTO) { + const s = " " + b.number + const bnumberPadded = s.substr(s.length - 6) + return formatTimestamp(b.medianTime) + ' (#' + bnumberPadded + ')' +} + function formatTimestamp(ts: number) { return moment(ts * 1000).format('YYYY-MM-DD hh:mm:ss') } -- GitLab