From a7c3bab20e4b05a9539fb0947438626b6e84b596 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Fri, 14 Nov 2025 12:07:24 +0100 Subject: [PATCH] fix lint --- dlt-connector/src/bootstrap/init.ts | 2 +- .../client/GradidoNode/GradidoNodeProcess.ts | 23 ++- .../src/client/GradidoNode/communities.ts | 9 +- dlt-connector/src/client/hiero/HieroClient.ts | 22 ++- dlt-connector/src/config/schema.ts | 10 +- .../src/data/KeyPairIdentifier.logic.ts | 4 +- .../resolveKeyPair/ResolveKeyPair.context.ts | 2 +- .../RedeemDeferredTransferTransaction.role.ts | 11 +- .../sendToHiero/SendToHiero.context.ts | 15 +- .../db-v2.7.0_to_blockchain-v3.5/Context.ts | 27 ++- .../binaryExport.ts | 53 ++++-- .../blockchain.ts | 152 +++++++++++---- .../db-v2.7.0_to_blockchain-v3.5/bootstrap.ts | 24 +-- .../db-v2.7.0_to_blockchain-v3.5/convert.ts | 65 +++++-- .../db-v2.7.0_to_blockchain-v3.5/database.ts | 174 +++++++++++------- .../drizzle.schema.ts | 98 +++++----- .../db-v2.7.0_to_blockchain-v3.5/index.ts | 14 +- .../syncDbWithBlockchain/AbstractSync.role.ts | 17 +- .../DeletedTransactionLinksSync.role.ts | 4 +- .../TransactionLinksSync.role.ts | 7 +- .../TransactionsSync.role.ts | 23 ++- .../syncDbWithBlockchain/UsersSync.role.ts | 9 +- .../syncDbWithBlockchain.context.ts | 19 +- .../db-v2.7.0_to_blockchain-v3.5/keyPair.ts | 64 ++++--- .../db-v2.7.0_to_blockchain-v3.5/utils.ts | 2 +- .../valibot.schema.ts | 22 ++- .../src/schemas/typeConverter.schema.ts | 8 +- dlt-connector/src/utils/time.ts | 2 +- 28 files changed, 549 insertions(+), 333 deletions(-) diff --git a/dlt-connector/src/bootstrap/init.ts b/dlt-connector/src/bootstrap/init.ts index e0289db57..13b77783c 100644 --- a/dlt-connector/src/bootstrap/init.ts +++ b/dlt-connector/src/bootstrap/init.ts @@ -39,7 +39,7 @@ export async function checkHomeCommunity( // wait for backend server await isPortOpenRetry(backend.url) // ask backend for home community - let homeCommunity = await backend.getHomeCommunityDraft() + let homeCommunity = await backend.getHomeCommunityDraft() // on missing topicId, create one if (!homeCommunity.hieroTopicId) { const topicId = await hiero.createTopic(homeCommunity.name) diff --git a/dlt-connector/src/client/GradidoNode/GradidoNodeProcess.ts b/dlt-connector/src/client/GradidoNode/GradidoNodeProcess.ts index 3980bb9f2..0eae2f37e 100644 --- a/dlt-connector/src/client/GradidoNode/GradidoNodeProcess.ts +++ b/dlt-connector/src/client/GradidoNode/GradidoNodeProcess.ts @@ -1,3 +1,4 @@ +import { Mutex } from 'async-mutex' import { Subprocess, spawn } from 'bun' import { getLogger, Logger } from 'log4js' import { CONFIG } from '../../config' @@ -8,7 +9,6 @@ import { GRADIDO_NODE_RUNTIME_PATH, LOG4JS_BASE_CATEGORY, } from '../../config/const' -import { Mutex } from 'async-mutex' import { delay } from '../../utils/time' /** * A Singleton class defines the `getInstance` method that lets clients access @@ -94,11 +94,11 @@ export class GradidoNodeProcess { public async restart() { const release = await this.restartMutex.acquire() try { - if (this.proc) { - await this.exit() - this.exitCalled = false - this.start() - } + if (this.proc) { + await this.exit() + this.exitCalled = false + this.start() + } } finally { release() } @@ -111,8 +111,15 @@ export class GradidoNodeProcess { public async exit(): Promise { this.exitCalled = true if (this.proc) { - if (this.lastStarted && Date.now() - this.lastStarted.getTime() < GRADIDO_NODE_MIN_RUNTIME_BEFORE_EXIT_MILLISECONDS) { - await delay(GRADIDO_NODE_MIN_RUNTIME_BEFORE_EXIT_MILLISECONDS - Date.now() - this.lastStarted.getTime()) + if ( + this.lastStarted && + Date.now() - this.lastStarted.getTime() < GRADIDO_NODE_MIN_RUNTIME_BEFORE_EXIT_MILLISECONDS + ) { + await delay( + GRADIDO_NODE_MIN_RUNTIME_BEFORE_EXIT_MILLISECONDS - + Date.now() - + this.lastStarted.getTime(), + ) } this.proc.kill('SIGTERM') const timeout = setTimeout(() => { diff --git a/dlt-connector/src/client/GradidoNode/communities.ts b/dlt-connector/src/client/GradidoNode/communities.ts index 76384f847..a418255f7 100644 --- a/dlt-connector/src/client/GradidoNode/communities.ts +++ b/dlt-connector/src/client/GradidoNode/communities.ts @@ -66,7 +66,10 @@ export async function exportCommunities(homeFolder: string, client: BackendClien logger.info(`exported ${communitiesForDltNodeServer.length} communities to ${communitiesPath}`) } -export function checkCommunityAvailable(communityTopicIds: Set, homeFolder: string): boolean { +export function checkCommunityAvailable( + communityTopicIds: Set, + homeFolder: string, +): boolean { const communitiesPath = path.join(homeFolder, 'communities.json') if (!checkFileExist(communitiesPath)) { return false @@ -81,6 +84,8 @@ export function checkCommunityAvailable(communityTopicIds: Set, homeFol } } } - logger.debug(`community not found for topic ids: ${communityTopicIds}, communities: ${JSON.stringify(communities, null, 2)}`) + logger.debug( + `community not found for topic ids: ${communityTopicIds}, communities: ${JSON.stringify(communities, null, 2)}`, + ) return false } diff --git a/dlt-connector/src/client/hiero/HieroClient.ts b/dlt-connector/src/client/hiero/HieroClient.ts index f81da11c5..c32c4cbd7 100644 --- a/dlt-connector/src/client/hiero/HieroClient.ts +++ b/dlt-connector/src/client/hiero/HieroClient.ts @@ -21,10 +21,10 @@ import * as v from 'valibot' import { CONFIG } from '../../config' import { LOG4JS_BASE_CATEGORY } from '../../config/const' import { HieroId, hieroIdSchema } from '../../schemas/typeGuard.schema' -import { type TopicInfoOutput, topicInfoSchema } from './output.schema' +import { durationInMinutesFromDates, printTimeDuration } from '../../utils/time' import { GradidoNodeClient } from '../GradidoNode/GradidoNodeClient' import { GradidoNodeProcess } from '../GradidoNode/GradidoNodeProcess' -import { durationInMinutesFromDates, printTimeDuration } from '../../utils/time' +import { type TopicInfoOutput, topicInfoSchema } from './output.schema' // https://docs.hedera.com/hedera/sdks-and-apis/hedera-api/consensus/consensusupdatetopic export const MIN_AUTORENEW_PERIOD = 6999999 //seconds export const MAX_AUTORENEW_PERIOD = 8000001 // seconds @@ -109,9 +109,13 @@ export class HieroClient { const process = GradidoNodeProcess.getInstance() const lastStarted = process.getLastStarted() if (lastStarted) { - const serverRunTime = printTimeDuration(durationInMinutesFromDates(lastStarted, new Date())) - this.logger.error(`transaction not found, restart GradidoNode after ${serverRunTime}`) - await GradidoNodeProcess.getInstance().restart() + const serverRunTime = printTimeDuration( + durationInMinutesFromDates(lastStarted, new Date()), + ) + this.logger.error( + `transaction not found, restart GradidoNode after ${serverRunTime}`, + ) + await GradidoNodeProcess.getInstance().restart() } else { this.logger.error('transaction not found, GradidoNode not running, start it') GradidoNodeProcess.getInstance().start() @@ -126,9 +130,7 @@ export class HieroClient { // only for logging sendResponse.getRecordWithSigner(this.wallet).then((record) => { logger.info(`message sent, cost: ${record.transactionFee.toString()}`) - logger.info( - `HieroClient.sendMessage used time (full process): ${timeUsed.string()}`, - ) + logger.info(`HieroClient.sendMessage used time (full process): ${timeUsed.string()}`) }) } }) @@ -139,7 +141,9 @@ export class HieroClient { this.pendingPromises.splice(pendingPromiseIndex, 1) }), ) - logger.debug(`create transactionId: ${hieroTransaction.transactionId?.toString()}, used time: ${timeUsed.string()}`) + logger.debug( + `create transactionId: ${hieroTransaction.transactionId?.toString()}, used time: ${timeUsed.string()}`, + ) return hieroTransaction.transactionId } diff --git a/dlt-connector/src/config/schema.ts b/dlt-connector/src/config/schema.ts index 09eca49b2..45ef83831 100644 --- a/dlt-connector/src/config/schema.ts +++ b/dlt-connector/src/config/schema.ts @@ -99,10 +99,7 @@ export const configSchema = v.object({ ), '4000', ), - MYSQL_HOST: v.optional( - v.string('The host of the database'), - 'localhost', - ), + MYSQL_HOST: v.optional(v.string('The host of the database'), 'localhost'), MYSQL_PORT: v.optional( v.pipe( v.string('The port of the database'), @@ -136,8 +133,5 @@ export const configSchema = v.object({ ), '', ), - MYSQL_DATABASE: v.optional( - v.string('The name of the database'), - 'gradido_community', - ), + MYSQL_DATABASE: v.optional(v.string('The name of the database'), 'gradido_community'), }) diff --git a/dlt-connector/src/data/KeyPairIdentifier.logic.ts b/dlt-connector/src/data/KeyPairIdentifier.logic.ts index 61f4d3cfb..3b6b71c6e 100644 --- a/dlt-connector/src/data/KeyPairIdentifier.logic.ts +++ b/dlt-connector/src/data/KeyPairIdentifier.logic.ts @@ -107,7 +107,9 @@ export class KeyPairIdentifierLogic { ) } const resultString = - this.identifier.communityTopicId + this.identifier.account.userUuid.replace(/-/g, '') + accountNr.toString() + this.identifier.communityTopicId + + this.identifier.account.userUuid.replace(/-/g, '') + + accountNr.toString() return new MemoryBlock(resultString).calculateHash().convertToHex() } } diff --git a/dlt-connector/src/interactions/resolveKeyPair/ResolveKeyPair.context.ts b/dlt-connector/src/interactions/resolveKeyPair/ResolveKeyPair.context.ts index 21187602b..406463c4c 100644 --- a/dlt-connector/src/interactions/resolveKeyPair/ResolveKeyPair.context.ts +++ b/dlt-connector/src/interactions/resolveKeyPair/ResolveKeyPair.context.ts @@ -32,7 +32,7 @@ import { UserKeyPairRole } from './UserKeyPair.role' */ export async function ResolveKeyPair(input: KeyPairIdentifierLogic): Promise { const cache = KeyPairCacheManager.getInstance() - + return await cache.getKeyPair( input.getKey(), // function is called from cache manager, if key isn't currently cached diff --git a/dlt-connector/src/interactions/sendToHiero/RedeemDeferredTransferTransaction.role.ts b/dlt-connector/src/interactions/sendToHiero/RedeemDeferredTransferTransaction.role.ts index 2f51f8f21..4615a4707 100644 --- a/dlt-connector/src/interactions/sendToHiero/RedeemDeferredTransferTransaction.role.ts +++ b/dlt-connector/src/interactions/sendToHiero/RedeemDeferredTransferTransaction.role.ts @@ -1,4 +1,9 @@ -import { ConfirmedTransaction, GradidoTransactionBuilder, GradidoTransfer, TransferAmount } from 'gradido-blockchain-js' +import { + ConfirmedTransaction, + GradidoTransactionBuilder, + GradidoTransfer, + TransferAmount, +} from 'gradido-blockchain-js' import * as v from 'valibot' import { KeyPairIdentifierLogic } from '../../data/KeyPairIdentifier.logic' import { @@ -42,7 +47,9 @@ export class RedeemDeferredTransferTransactionRole extends AbstractTransactionRo if (!senderPublicKey) { throw new Error("redeem deferred transfer: couldn't calculate sender public key") } - const deferredTransferBody = this.parentDeferredTransaction.getGradidoTransaction()?.getTransactionBody() + const deferredTransferBody = this.parentDeferredTransaction + .getGradidoTransaction() + ?.getTransactionBody() if (!deferredTransferBody) { throw new Error( "redeem deferred transfer: couldn't deserialize deferred transfer from Gradido Node", diff --git a/dlt-connector/src/interactions/sendToHiero/SendToHiero.context.ts b/dlt-connector/src/interactions/sendToHiero/SendToHiero.context.ts index 269bccada..622addb28 100644 --- a/dlt-connector/src/interactions/sendToHiero/SendToHiero.context.ts +++ b/dlt-connector/src/interactions/sendToHiero/SendToHiero.context.ts @@ -6,9 +6,9 @@ import { ValidateType_SINGLE, } from 'gradido-blockchain-js' import { getLogger } from 'log4js' -import { GradidoNodeClient } from '../../client/GradidoNode/GradidoNodeClient' import * as v from 'valibot' import { ensureCommunitiesAvailable } from '../../client/GradidoNode/communities' +import { GradidoNodeClient } from '../../client/GradidoNode/GradidoNodeClient' import { HieroClient } from '../../client/hiero/HieroClient' import { LOG4JS_BASE_CATEGORY } from '../../config/const' import { InputTransactionType } from '../../data/InputTransactionType.enum' @@ -25,6 +25,7 @@ import { identifierSeedSchema, } from '../../schemas/typeGuard.schema' import { isTopicStillOpen } from '../../utils/hiero' +import { LinkedTransactionKeyPairRole } from '../resolveKeyPair/LinkedTransactionKeyPair.role' import { AbstractTransactionRole } from './AbstractTransaction.role' import { CommunityRootTransactionRole } from './CommunityRootTransaction.role' import { CreationTransactionRole } from './CreationTransaction.role' @@ -32,7 +33,6 @@ import { DeferredTransferTransactionRole } from './DeferredTransferTransaction.r import { RedeemDeferredTransferTransactionRole } from './RedeemDeferredTransferTransaction.role' import { RegisterAddressTransactionRole } from './RegisterAddressTransaction.role' import { TransferTransactionRole } from './TransferTransaction.role' -import { LinkedTransactionKeyPairRole } from '../resolveKeyPair/LinkedTransactionKeyPair.role' const logger = getLogger(`${LOG4JS_BASE_CATEGORY}.interactions.sendToHiero.SendToHieroContext`) @@ -146,9 +146,11 @@ async function chooseCorrectRole( return new RegisterAddressTransactionRole(transaction) case InputTransactionType.GRADIDO_DEFERRED_TRANSFER: return new DeferredTransferTransactionRole(transaction) - case InputTransactionType.GRADIDO_REDEEM_DEFERRED_TRANSFER: + case InputTransactionType.GRADIDO_REDEEM_DEFERRED_TRANSFER: { // load deferred transfer transaction from gradido node - const seedKeyPairRole = new LinkedTransactionKeyPairRole(v.parse(identifierSeedSchema, transaction.user.seed)) + const seedKeyPairRole = new LinkedTransactionKeyPairRole( + v.parse(identifierSeedSchema, transaction.user.seed), + ) const seedPublicKey = seedKeyPairRole.generateKeyPair().getPublicKey() if (!seedPublicKey) { throw new Error("redeem deferred transfer: couldn't generate seed public key") @@ -158,9 +160,12 @@ async function chooseCorrectRole( seedPublicKey.convertToHex(), ) if (!transactions || transactions.length !== 1) { - throw new Error("redeem deferred transfer: couldn't find exactly one deferred transfer on Gradido Node") + throw new Error( + "redeem deferred transfer: couldn't find exactly one deferred transfer on Gradido Node", + ) } return new RedeemDeferredTransferTransactionRole(transaction, transactions[0]) + } default: throw new Error('not supported transaction type: ' + transaction.type) } diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/Context.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/Context.ts index 9eb549a30..58400a615 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/Context.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/Context.ts @@ -1,17 +1,15 @@ +import { heapStats } from 'bun:jsc' import { drizzle, MySql2Database } from 'drizzle-orm/mysql2' -import mysql from 'mysql2/promise' import { Filter, Profiler, SearchDirection_ASC } from 'gradido-blockchain-js' import { getLogger, Logger } from 'log4js' - -import { Uuidv4 } from '../../schemas/typeGuard.schema' - -import { KeyPairCacheManager } from '../../cache/KeyPairCacheManager' +import mysql from 'mysql2/promise' import { loadConfig } from '../../bootstrap/init' +import { KeyPairCacheManager } from '../../cache/KeyPairCacheManager' import { CONFIG } from '../../config' import { LOG4JS_BASE_CATEGORY } from '../../config/const' -import { heapStats } from 'bun:jsc' -import { CommunityContext } from './valibot.schema' +import { Uuidv4 } from '../../schemas/typeGuard.schema' import { bytesToMbyte } from './utils' +import { CommunityContext } from './valibot.schema' export class Context { public logger: Logger @@ -36,12 +34,12 @@ export class Context { user: CONFIG.MYSQL_USER, password: CONFIG.MYSQL_PASSWORD, database: CONFIG.MYSQL_DATABASE, - port: CONFIG.MYSQL_PORT + port: CONFIG.MYSQL_PORT, }) return new Context( getLogger(`${LOG4JS_BASE_CATEGORY}.migrations.db-v2.7.0_to_blockchain-v3.5`), - drizzle({ client: connection }), - KeyPairCacheManager.getInstance() + drizzle({ client: connection }), + KeyPairCacheManager.getInstance(), ) } @@ -57,18 +55,18 @@ export class Context { this.logger.info(`${this.timeUsed.string()} for synchronizing to blockchain`) const runtimeStats = heapStats() this.logger.info( - `Memory Statistics: heap size: ${bytesToMbyte(runtimeStats.heapSize)} MByte, heap capacity: ${bytesToMbyte(runtimeStats.heapCapacity)} MByte, extra memory: ${bytesToMbyte(runtimeStats.extraMemorySize)} MByte` + `Memory Statistics: heap size: ${bytesToMbyte(runtimeStats.heapSize)} MByte, heap capacity: ${bytesToMbyte(runtimeStats.heapCapacity)} MByte, extra memory: ${bytesToMbyte(runtimeStats.extraMemorySize)} MByte`, ) } logBlogchain(communityUuid: Uuidv4) { const communityContext = this.getCommunityContextByUuid(communityUuid) - const f = new Filter() + const f = new Filter() f.pagination.size = 0 f.searchDirection = SearchDirection_ASC - + const transactions = communityContext.blockchain.findAll(f) - for(let i = 0; i < transactions.size(); i++) { + for (let i = 0; i < transactions.size(); i++) { const transaction = transactions.get(i) const confirmedTransaction = transaction?.getConfirmedTransaction() this.logger.info(confirmedTransaction?.toJson(true)) @@ -76,5 +74,4 @@ export class Context { } // TODO: move into utils - } diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/binaryExport.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/binaryExport.ts index 74181f34f..474df61b8 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/binaryExport.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/binaryExport.ts @@ -1,21 +1,30 @@ -import { ConfirmedTransaction, Filter, InteractionSerialize, Profiler, SearchDirection_ASC } from 'gradido-blockchain-js' -import path from 'node:path' -import { CONFIG } from '../../config' import fs from 'node:fs' -import { bytesToKbyte } from './utils' -import { calculateOneHashStep } from './utils' +import path from 'node:path' +import { + ConfirmedTransaction, + Filter, + InteractionSerialize, + Profiler, + SearchDirection_ASC, +} from 'gradido-blockchain-js' +import { CONFIG } from '../../config' import { Context } from './Context' +import { bytesToKbyte, calculateOneHashStep } from './utils' import { CommunityContext } from './valibot.schema' export function exportAllCommunities(context: Context, batchSize: number) { const timeUsed = new Profiler() - for(const communityContext of context.communities.values()) { + for (const communityContext of context.communities.values()) { exportCommunity(communityContext, context, batchSize) } context.logger.info(`time used for exporting communities to binary file: ${timeUsed.string()}`) } -export function exportCommunity(communityContext: CommunityContext, context: Context, batchSize: number) { +export function exportCommunity( + communityContext: CommunityContext, + context: Context, + batchSize: number, +) { // write as binary file for GradidoNode const f = new Filter() f.pagination.size = batchSize @@ -28,7 +37,7 @@ export function exportCommunity(communityContext: CommunityContext, context: Con do { const transactions = communityContext.blockchain.findAll(f) lastTransactionCount = transactions.size() - + for (let i = 0; i < lastTransactionCount; i++) { const confirmedTransaction = transactions.get(i)?.getConfirmedTransaction() const transactionNr = f.pagination.page * batchSize + i @@ -39,22 +48,30 @@ export function exportCommunity(communityContext: CommunityContext, context: Con } f.pagination.page++ } while (lastTransactionCount === batchSize) - + fs.appendFileSync(binFilePath, hash!) - context.logger.info(`binary file for community ${communityContext.communityId} written to ${binFilePath}`) context.logger.info( - `transactions count: ${(f.pagination.page - 1) * batchSize + lastTransactionCount}, size: ${bytesToKbyte(fs.statSync(binFilePath).size)} KByte` + `binary file for community ${communityContext.communityId} written to ${binFilePath}`, + ) + context.logger.info( + `transactions count: ${(f.pagination.page - 1) * batchSize + lastTransactionCount}, size: ${bytesToKbyte(fs.statSync(binFilePath).size)} KByte`, ) } -function exportTransaction(confirmedTransaction: ConfirmedTransaction, hash: Buffer, binFilePath: string): Buffer { - const sizeBuffer = Buffer.alloc(2) +function exportTransaction( + confirmedTransaction: ConfirmedTransaction, + hash: Buffer, + binFilePath: string, +): Buffer { + const sizeBuffer = Buffer.alloc(2) const interactionSerialize = new InteractionSerialize(confirmedTransaction) const binBlock = interactionSerialize.run() if (!binBlock) { - throw new Error(`invalid TransactionEntry at index: ${confirmedTransaction.getId()}, serialize into protobuf format failed`) + throw new Error( + `invalid TransactionEntry at index: ${confirmedTransaction.getId()}, serialize into protobuf format failed`, + ) } - + hash = calculateOneHashStep(hash, binBlock.data()) sizeBuffer.writeUInt16LE(binBlock.size(), 0) fs.appendFileSync(binFilePath, sizeBuffer) @@ -64,13 +81,13 @@ function exportTransaction(confirmedTransaction: ConfirmedTransaction, hash: Buf function prepareFolder(communityContext: CommunityContext): string { const binFileFolder = path.join( - CONFIG.DLT_GRADIDO_NODE_SERVER_HOME_FOLDER, + CONFIG.DLT_GRADIDO_NODE_SERVER_HOME_FOLDER, '.gradido', communityContext.folder, ) const binFilePath = path.join(binFileFolder, 'blk00000001.dat') // make sure we work with a clean folder, rm beforehand with all content fs.rmSync(binFileFolder, { recursive: true }) - fs.mkdirSync(binFileFolder, { recursive: true }) + fs.mkdirSync(binFileFolder, { recursive: true }) return binFilePath -} \ No newline at end of file +} diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/blockchain.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/blockchain.ts index 273451e14..fd89d5ea0 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/blockchain.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/blockchain.ts @@ -1,37 +1,47 @@ -import { - InMemoryBlockchain, - GradidoTransactionBuilder, - Timestamp, - HieroTransactionId, - HieroAccountId, - InteractionSerialize, +import { Filter, + GradidoTransactionBuilder, + HieroAccountId, + HieroTransactionId, + InMemoryBlockchain, + InteractionSerialize, + Timestamp, } from 'gradido-blockchain-js' import { getLogger } from 'log4js' -import { RegisterAddressTransactionRole } from '../../interactions/sendToHiero/RegisterAddressTransaction.role' -import { CommunityRootTransactionRole } from '../../interactions/sendToHiero/CommunityRootTransaction.role' -import { CreationTransactionRole } from '../../interactions/sendToHiero/CreationTransaction.role' +import * as v from 'valibot' import { LOG4JS_BASE_CATEGORY } from '../../config/const' -import { Community, Transaction } from '../../schemas/transaction.schema' -import { TransferTransactionRole } from '../../interactions/sendToHiero/TransferTransaction.role' -import { DeferredTransferTransactionRole } from '../../interactions/sendToHiero/DeferredTransferTransaction.role' -import { RedeemDeferredTransferTransactionRole } from '../../interactions/sendToHiero/RedeemDeferredTransferTransaction.role' import { InputTransactionType } from '../../data/InputTransactionType.enum' import { LinkedTransactionKeyPairRole } from '../../interactions/resolveKeyPair/LinkedTransactionKeyPair.role' +import { CommunityRootTransactionRole } from '../../interactions/sendToHiero/CommunityRootTransaction.role' +import { CreationTransactionRole } from '../../interactions/sendToHiero/CreationTransaction.role' +import { DeferredTransferTransactionRole } from '../../interactions/sendToHiero/DeferredTransferTransaction.role' +import { RedeemDeferredTransferTransactionRole } from '../../interactions/sendToHiero/RedeemDeferredTransferTransaction.role' +import { RegisterAddressTransactionRole } from '../../interactions/sendToHiero/RegisterAddressTransaction.role' +import { TransferTransactionRole } from '../../interactions/sendToHiero/TransferTransaction.role' +import { Community, Transaction } from '../../schemas/transaction.schema' import { identifierSeedSchema } from '../../schemas/typeGuard.schema' -import * as v from 'valibot' -const logger = getLogger(`${LOG4JS_BASE_CATEGORY}.migrations.db-v2.7.0_to_blockchain-v3.6.blockchain`) +const logger = getLogger( + `${LOG4JS_BASE_CATEGORY}.migrations.db-v2.7.0_to_blockchain-v3.6.blockchain`, +) export const defaultHieroAccount = new HieroAccountId(0, 0, 2) -function addToBlockchain(builder: GradidoTransactionBuilder, blockchain: InMemoryBlockchain, createdAtTimestamp: Timestamp): boolean { +function addToBlockchain( + builder: GradidoTransactionBuilder, + blockchain: InMemoryBlockchain, + createdAtTimestamp: Timestamp, +): boolean { const transaction = builder.build() // TOD: use actual transaction id if exist in dlt_transactions table const transactionId = new HieroTransactionId(createdAtTimestamp, defaultHieroAccount) const interactionSerialize = new InteractionSerialize(transactionId) try { - const result = blockchain.createAndAddConfirmedTransaction(transaction, interactionSerialize.run(), createdAtTimestamp) + const result = blockchain.createAndAddConfirmedTransaction( + transaction, + interactionSerialize.run(), + createdAtTimestamp, + ) return result } catch (error) { logger.error(`Transaction ${transaction.toJson(true)} not added: ${error}`) @@ -39,68 +49,130 @@ function addToBlockchain(builder: GradidoTransactionBuilder, blockchain: InMemor } } -export async function addCommunityRootTransaction(blockchain: InMemoryBlockchain, community: Community): Promise { +export async function addCommunityRootTransaction( + blockchain: InMemoryBlockchain, + community: Community, +): Promise { const communityRootTransactionRole = new CommunityRootTransactionRole(community) - if(addToBlockchain(await communityRootTransactionRole.getGradidoTransactionBuilder(), blockchain, new Timestamp(community.creationDate))) { + if ( + addToBlockchain( + await communityRootTransactionRole.getGradidoTransactionBuilder(), + blockchain, + new Timestamp(community.creationDate), + ) + ) { logger.info(`Community Root Transaction added`) } else { throw new Error(`Community Root Transaction not added`) } } -export async function addRegisterAddressTransaction(blockchain: InMemoryBlockchain, transaction: Transaction): Promise { +export async function addRegisterAddressTransaction( + blockchain: InMemoryBlockchain, + transaction: Transaction, +): Promise { const registerAddressRole = new RegisterAddressTransactionRole(transaction) - if(addToBlockchain(await registerAddressRole.getGradidoTransactionBuilder(), blockchain, new Timestamp(transaction.createdAt))) { - logger.debug(`Register Address Transaction added for user ${transaction.user.account!.userUuid}`) + if ( + addToBlockchain( + await registerAddressRole.getGradidoTransactionBuilder(), + blockchain, + new Timestamp(transaction.createdAt), + ) + ) { + logger.debug( + `Register Address Transaction added for user ${transaction.user.account!.userUuid}`, + ) } else { - throw new Error(`Register Address Transaction not added for user ${transaction.user.account!.userUuid}`) + throw new Error( + `Register Address Transaction not added for user ${transaction.user.account!.userUuid}`, + ) } } export async function addTransaction( senderBlockchain: InMemoryBlockchain, _recipientBlockchain: InMemoryBlockchain, - transaction: Transaction + transaction: Transaction, ): Promise { const createdAtTimestamp = new Timestamp(transaction.createdAt) if (transaction.type === InputTransactionType.GRADIDO_CREATION) { const creationTransactionRole = new CreationTransactionRole(transaction) - if(addToBlockchain(await creationTransactionRole.getGradidoTransactionBuilder(), senderBlockchain, createdAtTimestamp)) { + if ( + addToBlockchain( + await creationTransactionRole.getGradidoTransactionBuilder(), + senderBlockchain, + createdAtTimestamp, + ) + ) { logger.debug(`Creation Transaction added for user ${transaction.user.account!.userUuid}`) } else { - throw new Error(`Creation Transaction not added for user ${transaction.user.account!.userUuid}`) - } + throw new Error( + `Creation Transaction not added for user ${transaction.user.account!.userUuid}`, + ) + } } else if (transaction.type === InputTransactionType.GRADIDO_TRANSFER) { const transferTransactionRole = new TransferTransactionRole(transaction) // will crash with cross group transaction - if(addToBlockchain(await transferTransactionRole.getGradidoTransactionBuilder(), senderBlockchain, createdAtTimestamp)) { + if ( + addToBlockchain( + await transferTransactionRole.getGradidoTransactionBuilder(), + senderBlockchain, + createdAtTimestamp, + ) + ) { logger.debug(`Transfer Transaction added for user ${transaction.user.account!.userUuid}`) } else { - throw new Error(`Transfer Transaction not added for user ${transaction.user.account!.userUuid}`) + throw new Error( + `Transfer Transaction not added for user ${transaction.user.account!.userUuid}`, + ) } } else if (transaction.type === InputTransactionType.GRADIDO_DEFERRED_TRANSFER) { const transferTransactionRole = new DeferredTransferTransactionRole(transaction) - if(addToBlockchain(await transferTransactionRole.getGradidoTransactionBuilder(), senderBlockchain, createdAtTimestamp)) { - logger.debug(`Deferred Transfer Transaction added for user ${transaction.user.account!.userUuid}`) + if ( + addToBlockchain( + await transferTransactionRole.getGradidoTransactionBuilder(), + senderBlockchain, + createdAtTimestamp, + ) + ) { + logger.debug( + `Deferred Transfer Transaction added for user ${transaction.user.account!.userUuid}`, + ) } else { - - throw new Error(`Deferred Transfer Transaction not added for user ${transaction.user.account!.userUuid}`) + throw new Error( + `Deferred Transfer Transaction not added for user ${transaction.user.account!.userUuid}`, + ) } } else if (transaction.type === InputTransactionType.GRADIDO_REDEEM_DEFERRED_TRANSFER) { - const seedKeyPairRole = new LinkedTransactionKeyPairRole(v.parse(identifierSeedSchema, transaction.user.seed)) + const seedKeyPairRole = new LinkedTransactionKeyPairRole( + v.parse(identifierSeedSchema, transaction.user.seed), + ) const f = new Filter() f.involvedPublicKey = seedKeyPairRole.generateKeyPair().getPublicKey() const deferredTransaction = senderBlockchain.findOne(f) if (!deferredTransaction) { - throw new Error(`redeem deferred transfer: couldn't find parent deferred transfer on Gradido Node for ${JSON.stringify(transaction, null, 2)} and public key from seed: ${f.involvedPublicKey?.convertToHex()}`) + throw new Error( + `redeem deferred transfer: couldn't find parent deferred transfer on Gradido Node for ${JSON.stringify(transaction, null, 2)} and public key from seed: ${f.involvedPublicKey?.convertToHex()}`, + ) } const confirmedDeferredTransaction = deferredTransaction.getConfirmedTransaction() if (!confirmedDeferredTransaction) { - throw new Error("redeem deferred transfer: invalid TransactionEntry") + throw new Error('redeem deferred transfer: invalid TransactionEntry') } - const redeemTransactionRole = new RedeemDeferredTransferTransactionRole(transaction, confirmedDeferredTransaction) - const involvedUser = transaction.user.account ? transaction.user.account.userUuid : transaction.linkedUser?.account?.userUuid - if(addToBlockchain(await redeemTransactionRole.getGradidoTransactionBuilder(), senderBlockchain, createdAtTimestamp)) { + const redeemTransactionRole = new RedeemDeferredTransferTransactionRole( + transaction, + confirmedDeferredTransaction, + ) + const involvedUser = transaction.user.account + ? transaction.user.account.userUuid + : transaction.linkedUser?.account?.userUuid + if ( + addToBlockchain( + await redeemTransactionRole.getGradidoTransactionBuilder(), + senderBlockchain, + createdAtTimestamp, + ) + ) { logger.debug(`Redeem Deferred Transfer Transaction added for user ${involvedUser}`) } else { throw new Error(`Redeem Deferred Transfer Transaction not added for user ${involvedUser}`) diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/bootstrap.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/bootstrap.ts index ef792e8d6..c613eb655 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/bootstrap.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/bootstrap.ts @@ -1,11 +1,11 @@ -import { Context } from './Context' -import { loadCommunities } from './database' -import { HieroId, hieroIdSchema } from '../../schemas/typeGuard.schema' -import * as v from 'valibot' import { InMemoryBlockchainProvider } from 'gradido-blockchain-js' -import { generateKeyPairCommunity } from './keyPair' -import { communityDbToCommunity } from './convert' +import * as v from 'valibot' +import { HieroId, hieroIdSchema } from '../../schemas/typeGuard.schema' import { addCommunityRootTransaction } from './blockchain' +import { Context } from './Context' +import { communityDbToCommunity } from './convert' +import { loadCommunities } from './database' +import { generateKeyPairCommunity } from './keyPair' import { CommunityContext } from './valibot.schema' export async function bootstrap(): Promise { @@ -18,18 +18,20 @@ async function bootstrapCommunities(context: Context): Promise() const communitiesDb = await loadCommunities(context.db) const topicIds = new Set() - + for (const communityDb of communitiesDb) { - const blockchain = InMemoryBlockchainProvider.getInstance().findBlockchain(communityDb.uniqueAlias) + const blockchain = InMemoryBlockchainProvider.getInstance().findBlockchain( + communityDb.uniqueAlias, + ) if (!blockchain) { throw new Error(`Couldn't create Blockchain for community ${communityDb.communityUuid}`) } context.logger.info(`Blockchain for community '${communityDb.uniqueAlias}' created`) // make sure topic id is unique - let topicId: HieroId + let topicId: HieroId do { topicId = v.parse(hieroIdSchema, '0.0.' + Math.floor(Math.random() * 10000)) - } while(topicIds.has(topicId)) + } while (topicIds.has(topicId)) topicIds.add(topicId) communities.set(communityDb.communityUuid, { @@ -38,7 +40,7 @@ async function bootstrapCommunities(context: Context): Promise { - const result = await db.select({ - foreign: communitiesTable.foreign, - communityUuid: communitiesTable.communityUuid, - name: communitiesTable.name, - creationDate: communitiesTable.creationDate, - userMinCreatedAt: sql`MIN(${usersTable.createdAt})`, - }) - .from(communitiesTable) - .leftJoin(usersTable, eq(communitiesTable.communityUuid, usersTable.communityUuid)) - .where(isNotNull(communitiesTable.communityUuid)) - .groupBy(communitiesTable.communityUuid) + const result = await db + .select({ + foreign: communitiesTable.foreign, + communityUuid: communitiesTable.communityUuid, + name: communitiesTable.name, + creationDate: communitiesTable.creationDate, + userMinCreatedAt: sql`MIN(${usersTable.createdAt})`, + }) + .from(communitiesTable) + .leftJoin(usersTable, eq(communitiesTable.communityUuid, usersTable.communityUuid)) + .where(isNotNull(communitiesTable.communityUuid)) + .groupBy(communitiesTable.communityUuid) const communityNames = new Set() return result.map((row: any) => { @@ -49,33 +57,50 @@ export async function loadCommunities(db: MySql2Database): Promise { - const result = await db.select() - .from(usersTable) - .orderBy(asc(usersTable.createdAt)) - .limit(count).offset(offset) +export async function loadUsers( + db: MySql2Database, + offset: number, + count: number, +): Promise { + const result = await db + .select() + .from(usersTable) + .orderBy(asc(usersTable.createdAt)) + .limit(count) + .offset(offset) return result.map((row: any) => { return v.parse(createdUserDbSchema, row) }) } -export async function loadTransactions(db: MySql2Database, offset: number, count: number): Promise { +export async function loadTransactions( + db: MySql2Database, + offset: number, + count: number, +): Promise { const linkedUsers = alias(usersTable, 'linkedUser') - - const result = await db.select({ - transaction: transactionsTable, - user: usersTable, - linkedUser: linkedUsers, - transactionLink: transactionLinksTable, - }) - .from(transactionsTable) - .where(inArray(transactionsTable.typeId, [TransactionTypeId.CREATION, TransactionTypeId.RECEIVE])) - .leftJoin(usersTable, eq(transactionsTable.userId, usersTable.id)) - .leftJoin(linkedUsers, eq(transactionsTable.linkedUserId, linkedUsers.id)) - .leftJoin(transactionLinksTable, eq(transactionsTable.transactionLinkId, transactionLinksTable.id)) - .orderBy(asc(transactionsTable.balanceDate)) - .limit(count).offset(offset) + + const result = await db + .select({ + transaction: transactionsTable, + user: usersTable, + linkedUser: linkedUsers, + transactionLink: transactionLinksTable, + }) + .from(transactionsTable) + .where( + inArray(transactionsTable.typeId, [TransactionTypeId.CREATION, TransactionTypeId.RECEIVE]), + ) + .leftJoin(usersTable, eq(transactionsTable.userId, usersTable.id)) + .leftJoin(linkedUsers, eq(transactionsTable.linkedUserId, linkedUsers.id)) + .leftJoin( + transactionLinksTable, + eq(transactionsTable.transactionLinkId, transactionLinksTable.id), + ) + .orderBy(asc(transactionsTable.balanceDate)) + .limit(count) + .offset(offset) return result.map((row: any) => { // console.log(row) @@ -83,13 +108,14 @@ export async function loadTransactions(db: MySql2Database, offset: number, count const userCreatedAt = new Date(row.user.createdAt) const linkedUserCreatedAd = new Date(row.linkedUser.createdAt) const balanceDate = new Date(row.transaction.balanceDate) - if (userCreatedAt.getTime() > balanceDate.getTime() || - linkedUserCreatedAd.getTime() > balanceDate.getTime() - ){ + if ( + userCreatedAt.getTime() > balanceDate.getTime() || + linkedUserCreatedAd.getTime() > balanceDate.getTime() + ) { logger.error(`table row: `, row) throw new Error('at least one user was created after transaction balance date, logic error!') } - + let amount = GradidoUnit.fromString(row.transaction.amount) if (row.transaction.typeId === TransactionTypeId.SEND) { amount = amount.mul(new GradidoUnit(-1)) @@ -111,12 +137,18 @@ export async function loadTransactions(db: MySql2Database, offset: number, count }) } -export async function loadTransactionLinks(db: MySql2Database, offset: number, count: number): Promise { - const result = await db.select() - .from(transactionLinksTable) - .leftJoin(usersTable, eq(transactionLinksTable.userId, usersTable.id)) - .orderBy(asc(transactionLinksTable.createdAt)) - .limit(count).offset(offset) +export async function loadTransactionLinks( + db: MySql2Database, + offset: number, + count: number, +): Promise { + const result = await db + .select() + .from(transactionLinksTable) + .leftJoin(usersTable, eq(transactionLinksTable.userId, usersTable.id)) + .orderBy(asc(transactionLinksTable.createdAt)) + .limit(count) + .offset(offset) return result.map((row: any) => { return v.parse(transactionLinkDbSchema, { @@ -126,23 +158,29 @@ export async function loadTransactionLinks(db: MySql2Database, offset: number, c }) } -export async function loadDeletedTransactionLinks(db: MySql2Database, offset: number, count: number): Promise { - const result = await db.select() - .from(transactionLinksTable) - .leftJoin(usersTable, eq(transactionLinksTable.userId, usersTable.id)) - .where(isNotNull(transactionLinksTable.deletedAt)) - .orderBy(asc(transactionLinksTable.deletedAt)) - .limit(count).offset(offset) +export async function loadDeletedTransactionLinks( + db: MySql2Database, + offset: number, + count: number, +): Promise { + const result = await db + .select() + .from(transactionLinksTable) + .leftJoin(usersTable, eq(transactionLinksTable.userId, usersTable.id)) + .where(isNotNull(transactionLinksTable.deletedAt)) + .orderBy(asc(transactionLinksTable.deletedAt)) + .limit(count) + .offset(offset) return result.map((row: any) => { return v.parse(transactionDbSchema, { typeId: TransactionTypeId.RECEIVE, - amount: row.transaction_links.amount, + amount: row.transaction_links.amount, balanceDate: new Date(row.transaction_links.deletedAt), memo: row.transaction_links.memo, transactionLinkCode: row.transaction_links.code, user: row.users, - linkedUser: row.users + linkedUser: row.users, }) }) -} \ No newline at end of file +} diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/drizzle.schema.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/drizzle.schema.ts index f96b71bfe..59cc6573c 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/drizzle.schema.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/drizzle.schema.ts @@ -1,50 +1,66 @@ - -import { mysqlTable, unique, int, varchar, char, datetime, tinyint, decimal, index } from 'drizzle-orm/mysql-core' import { sql } from 'drizzle-orm' +import { + char, + datetime, + decimal, + index, + int, + mysqlTable, + tinyint, + unique, + varchar, +} from 'drizzle-orm/mysql-core' // use only fields needed in the migration, after update the rest of the project, import database instead -export const communitiesTable = mysqlTable('communities', { - foreign: tinyint().default(1).notNull(), - communityUuid: char('community_uuid', { length: 36 }).default(sql`NULL`), - name: varchar({ length: 40 }).default(sql`NULL`), - creationDate: datetime('creation_date', { mode: 'string', fsp: 3 }).default(sql`NULL`), -}, -(table) => [ - unique('uuid_key').on(table.communityUuid), -]) +export const communitiesTable = mysqlTable( + 'communities', + { + foreign: tinyint().default(1).notNull(), + communityUuid: char('community_uuid', { length: 36 }).default(sql`NULL`), + name: varchar({ length: 40 }).default(sql`NULL`), + creationDate: datetime('creation_date', { mode: 'string', fsp: 3 }).default(sql`NULL`), + }, + (table) => [unique('uuid_key').on(table.communityUuid)], +) -export const usersTable = mysqlTable('users', { - id: int().autoincrement().notNull(), - gradidoId: char('gradido_id', { length: 36 }).notNull(), - communityUuid: varchar('community_uuid', { length: 36 }).default(sql`NULL`), - createdAt: datetime('created_at', { mode: 'string', fsp: 3 }).default(sql`current_timestamp(3)`).notNull(), -}, -(table) => [ - unique('uuid_key').on(table.gradidoId, table.communityUuid), -]) +export const usersTable = mysqlTable( + 'users', + { + id: int().autoincrement().notNull(), + gradidoId: char('gradido_id', { length: 36 }).notNull(), + communityUuid: varchar('community_uuid', { length: 36 }).default(sql`NULL`), + createdAt: datetime('created_at', { mode: 'string', fsp: 3 }) + .default(sql`current_timestamp(3)`) + .notNull(), + }, + (table) => [unique('uuid_key').on(table.gradidoId, table.communityUuid)], +) -export const transactionsTable = mysqlTable('transactions', { - id: int().autoincrement().notNull(), - typeId: int('type_id').default(sql`NULL`), - transactionLinkId: int('transaction_link_id').default(sql`NULL`), - amount: decimal({ precision: 40, scale: 20 }).default(sql`NULL`), - balanceDate: datetime('balance_date', { mode: 'string', fsp: 3 }).default(sql`current_timestamp(3)`).notNull(), - memo: varchar({ length: 255 }).notNull(), - creationDate: datetime('creation_date', { mode: 'string', fsp: 3 }).default(sql`NULL`), - userId: int('user_id').notNull(), - linkedUserId: int('linked_user_id').default(sql`NULL`), -}, -(table) => [ - index('user_id').on(table.userId), -]) +export const transactionsTable = mysqlTable( + 'transactions', + { + id: int().autoincrement().notNull(), + typeId: int('type_id').default(sql`NULL`), + transactionLinkId: int('transaction_link_id').default(sql`NULL`), + amount: decimal({ precision: 40, scale: 20 }).default(sql`NULL`), + balanceDate: datetime('balance_date', { mode: 'string', fsp: 3 }) + .default(sql`current_timestamp(3)`) + .notNull(), + memo: varchar({ length: 255 }).notNull(), + creationDate: datetime('creation_date', { mode: 'string', fsp: 3 }).default(sql`NULL`), + userId: int('user_id').notNull(), + linkedUserId: int('linked_user_id').default(sql`NULL`), + }, + (table) => [index('user_id').on(table.userId)], +) export const transactionLinksTable = mysqlTable('transaction_links', { - id: int().autoincrement().notNull(), + id: int().autoincrement().notNull(), userId: int().notNull(), - amount: decimal({ precision: 40, scale: 20 }).notNull(), - memo: varchar({ length: 255 }).notNull(), - code: varchar({ length: 24 }).notNull(), - createdAt: datetime({ mode: 'string'}).notNull(), - deletedAt: datetime({ mode: 'string'}).default(sql`NULL`), - validUntil: datetime({ mode: 'string'}).notNull(), + amount: decimal({ precision: 40, scale: 20 }).notNull(), + memo: varchar({ length: 255 }).notNull(), + code: varchar({ length: 24 }).notNull(), + createdAt: datetime({ mode: 'string' }).notNull(), + deletedAt: datetime({ mode: 'string' }).default(sql`NULL`), + validUntil: datetime({ mode: 'string' }).notNull(), }) diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/index.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/index.ts index 5bae06fee..875c59eba 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/index.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/index.ts @@ -1,8 +1,8 @@ -import { bootstrap } from './bootstrap' -import { onShutdown } from '../../../../shared/src/helper/onShutdown' -import { syncDbWithBlockchainContext } from './interaction/syncDbWithBlockchain/syncDbWithBlockchain.context' -import { exportAllCommunities } from './binaryExport' import { Filter } from 'gradido-blockchain-js' +import { onShutdown } from '../../../../shared/src/helper/onShutdown' +import { exportAllCommunities } from './binaryExport' +import { bootstrap } from './bootstrap' +import { syncDbWithBlockchainContext } from './interaction/syncDbWithBlockchain/syncDbWithBlockchain.context' const BATCH_SIZE = 100 @@ -11,11 +11,11 @@ async function main() { const context = await bootstrap() onShutdown(async (reason, error) => { context.logger.info(`shutdown reason: ${reason}`) - if(error) { + if (error) { context.logger.error(error) } }) - + // synchronize to in memory blockchain await syncDbWithBlockchainContext(context, BATCH_SIZE) @@ -33,4 +33,4 @@ main().catch((e) => { // biome-ignore lint/suspicious/noConsole: maybe logger isn't initialized here console.error(e) process.exit(1) -}) \ No newline at end of file +}) diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/AbstractSync.role.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/AbstractSync.role.ts index 44fd0b471..90523fa1b 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/AbstractSync.role.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/AbstractSync.role.ts @@ -1,7 +1,7 @@ -import { Context } from '../../Context' +import { Profiler } from 'gradido-blockchain-js' import { getLogger, Logger } from 'log4js' import { LOG4JS_BASE_CATEGORY } from '../../../../config/const' -import { Profiler } from 'gradido-blockchain-js' +import { Context } from '../../Context' export abstract class AbstractSyncRole { private items: T[] = [] @@ -9,17 +9,18 @@ export abstract class AbstractSyncRole { protected logger: Logger constructor(protected readonly context: Context) { - this.logger = getLogger(`${LOG4JS_BASE_CATEGORY}.migrations.db-v2.7.0_to_blockchain-v3.5.interaction.syncDbWithBlockchain`) + this.logger = getLogger( + `${LOG4JS_BASE_CATEGORY}.migrations.db-v2.7.0_to_blockchain-v3.5.interaction.syncDbWithBlockchain`, + ) } abstract getDate(): Date abstract loadFromDb(offset: number, count: number): Promise abstract pushToBlockchain(item: T): Promise abstract itemTypeName(): string - + // return count of new loaded items - async ensureFilled(batchSize: number): Promise - { + async ensureFilled(batchSize: number): Promise { if (this.items.length === 0) { let timeUsed: Profiler | undefined if (this.logger.isDebugEnabled()) { @@ -28,7 +29,9 @@ export abstract class AbstractSyncRole { this.items = await this.loadFromDb(this.offset, batchSize) this.offset += this.items.length if (timeUsed && this.items.length) { - this.logger.debug(`${timeUsed.string()} for loading ${this.items.length} ${this.itemTypeName()} from db`) + this.logger.debug( + `${timeUsed.string()} for loading ${this.items.length} ${this.itemTypeName()} from db`, + ) } return this.items.length } diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/DeletedTransactionLinksSync.role.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/DeletedTransactionLinksSync.role.ts index 2ff3961b1..fd1ae225f 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/DeletedTransactionLinksSync.role.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/DeletedTransactionLinksSync.role.ts @@ -1,6 +1,6 @@ import { loadDeletedTransactionLinks } from '../../database' -import { TransactionsSyncRole } from './TransactionsSync.role' import { TransactionDb } from '../../valibot.schema' +import { TransactionsSyncRole } from './TransactionsSync.role' export class DeletedTransactionLinksSyncRole extends TransactionsSyncRole { itemTypeName(): string { @@ -10,4 +10,4 @@ export class DeletedTransactionLinksSyncRole extends TransactionsSyncRole { async loadFromDb(offset: number, count: number): Promise { return await loadDeletedTransactionLinks(this.context.db, offset, count) } -} \ No newline at end of file +} diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/TransactionLinksSync.role.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/TransactionLinksSync.role.ts index 30706dba3..847be89ba 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/TransactionLinksSync.role.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/TransactionLinksSync.role.ts @@ -1,7 +1,7 @@ -import { TransactionLinkDb } from '../../valibot.schema' -import { loadTransactionLinks } from '../../database' -import { transactionLinkDbToTransaction } from '../../convert' import { addTransaction } from '../../blockchain' +import { transactionLinkDbToTransaction } from '../../convert' +import { loadTransactionLinks } from '../../database' +import { TransactionLinkDb } from '../../valibot.schema' import { AbstractSyncRole } from './AbstractSync.role' export class TransactionLinksSyncRole extends AbstractSyncRole { @@ -23,4 +23,3 @@ export class TransactionLinksSyncRole extends AbstractSyncRole { @@ -19,10 +19,19 @@ export class TransactionsSyncRole extends AbstractSyncRole { async pushToBlockchain(item: TransactionDb): Promise { const senderCommunityContext = this.context.getCommunityContextByUuid(item.user.communityUuid) - const recipientCommunityContext = this.context.getCommunityContextByUuid(item.linkedUser.communityUuid) + const recipientCommunityContext = this.context.getCommunityContextByUuid( + item.linkedUser.communityUuid, + ) this.context.cache.setHomeCommunityTopicId(senderCommunityContext.topicId) - const transaction = transactionDbToTransaction(item, senderCommunityContext.topicId, recipientCommunityContext.topicId) - await addTransaction(senderCommunityContext.blockchain, recipientCommunityContext.blockchain, transaction) + const transaction = transactionDbToTransaction( + item, + senderCommunityContext.topicId, + recipientCommunityContext.topicId, + ) + await addTransaction( + senderCommunityContext.blockchain, + recipientCommunityContext.blockchain, + transaction, + ) } } - \ No newline at end of file diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/UsersSync.role.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/UsersSync.role.ts index acdf5011d..d6b40938f 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/UsersSync.role.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/UsersSync.role.ts @@ -1,10 +1,9 @@ -import { CreatedUserDb } from '../../valibot.schema' -import { AbstractSyncRole } from './AbstractSync.role' +import { addRegisterAddressTransaction } from '../../blockchain' +import { userDbToTransaction } from '../../convert' import { loadUsers } from '../../database' import { generateKeyPairUserAccount } from '../../keyPair' -import { userDbToTransaction } from '../../convert' -import { addRegisterAddressTransaction } from '../../blockchain' - +import { CreatedUserDb } from '../../valibot.schema' +import { AbstractSyncRole } from './AbstractSync.role' export class UsersSyncRole extends AbstractSyncRole { getDate(): Date { diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/syncDbWithBlockchain.context.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/syncDbWithBlockchain.context.ts index edef30caa..e67cd70da 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/syncDbWithBlockchain.context.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/interaction/syncDbWithBlockchain/syncDbWithBlockchain.context.ts @@ -1,8 +1,8 @@ -import { Context } from '../../Context' import { Profiler } from 'gradido-blockchain-js' -import { TransactionsSyncRole } from './TransactionsSync.role' +import { Context } from '../../Context' import { DeletedTransactionLinksSyncRole } from './DeletedTransactionLinksSync.role' import { TransactionLinksSyncRole } from './TransactionLinksSync.role' +import { TransactionsSyncRole } from './TransactionsSync.role' import { UsersSyncRole } from './UsersSync.role' export async function syncDbWithBlockchainContext(context: Context, batchSize: number) { @@ -11,20 +11,20 @@ export async function syncDbWithBlockchainContext(context: Context, batchSize: n new UsersSyncRole(context), new TransactionsSyncRole(context), new DeletedTransactionLinksSyncRole(context), - new TransactionLinksSyncRole(context) - ] + new TransactionLinksSyncRole(context), + ] - while (true) { - timeUsed.reset() - const results = await Promise.all(containers.map(c => c.ensureFilled(batchSize))) + while (true) { + timeUsed.reset() + const results = await Promise.all(containers.map((c) => c.ensureFilled(batchSize))) const loadedItemsCount = results.reduce((acc, c) => acc + c, 0) // log only, if at least one new item was loaded if (loadedItemsCount && context.logger.isInfoEnabled()) { context.logger.info(`${loadedItemsCount} new items loaded from db in ${timeUsed.string()}`) } - + // remove empty containers - const available = containers.filter(c => !c.isEmpty()) + const available = containers.filter((c) => !c.isEmpty()) if (available.length === 0) { break } @@ -36,4 +36,3 @@ export async function syncDbWithBlockchainContext(context: Context, batchSize: n await available[0].toBlockchain() } } - diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/keyPair.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/keyPair.ts index dda017cbd..b3432da80 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/keyPair.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/keyPair.ts @@ -1,17 +1,21 @@ -import { CommunityDb, UserDb } from './valibot.schema' -import { KeyPairCacheManager } from '../../cache/KeyPairCacheManager' -import { KeyPairIdentifierLogic } from '../../data/KeyPairIdentifier.logic' import { KeyPairEd25519, MemoryBlock, MemoryBlockPtr } from 'gradido-blockchain-js' import { getLogger } from 'log4js' -import { LOG4JS_BASE_CATEGORY } from '../../config/const' +import { KeyPairCacheManager } from '../../cache/KeyPairCacheManager' import { CONFIG } from '../../config' -import { HieroId } from '../../schemas/typeGuard.schema' -import { UserKeyPairRole } from '../../interactions/resolveKeyPair/UserKeyPair.role' +import { LOG4JS_BASE_CATEGORY } from '../../config/const' +import { KeyPairIdentifierLogic } from '../../data/KeyPairIdentifier.logic' import { AccountKeyPairRole } from '../../interactions/resolveKeyPair/AccountKeyPair.role' +import { UserKeyPairRole } from '../../interactions/resolveKeyPair/UserKeyPair.role' +import { HieroId } from '../../schemas/typeGuard.schema' +import { CommunityDb, UserDb } from './valibot.schema' const logger = getLogger(`${LOG4JS_BASE_CATEGORY}.migrations.db-v2.7.0_to_blockchain-v3.6.keyPair`) -export function generateKeyPairCommunity(community: CommunityDb, cache: KeyPairCacheManager, topicId: HieroId): void { +export function generateKeyPairCommunity( + community: CommunityDb, + cache: KeyPairCacheManager, + topicId: HieroId, +): void { let seed: MemoryBlock | null = null if (community.foreign) { const randomBuffer = Buffer.alloc(32) @@ -32,33 +36,37 @@ export function generateKeyPairCommunity(community: CommunityDb, cache: KeyPairC } export async function generateKeyPairUserAccount( - user: UserDb, - cache: KeyPairCacheManager, - communityTopicId: HieroId -): Promise<{userKeyPair: MemoryBlockPtr, accountKeyPair: MemoryBlockPtr}> { + user: UserDb, + cache: KeyPairCacheManager, + communityTopicId: HieroId, +): Promise<{ userKeyPair: MemoryBlockPtr; accountKeyPair: MemoryBlockPtr }> { const communityKeyPair = cache.findKeyPair(communityTopicId)! const userKeyPairRole = new UserKeyPairRole(user.gradidoId, communityKeyPair) - const userKeyPairKey = new KeyPairIdentifierLogic({ - communityTopicId: communityTopicId, + const userKeyPairKey = new KeyPairIdentifierLogic({ + communityTopicId: communityTopicId, account: { userUuid: user.gradidoId, - accountNr: 0 - } - }).getKey() - const userKeyPair = await cache.getKeyPair(userKeyPairKey, () => Promise.resolve(userKeyPairRole.generateKeyPair())) - - const accountKeyPairRole = new AccountKeyPairRole(1, userKeyPair) - const accountKeyPairKey = new KeyPairIdentifierLogic({ - communityTopicId: communityTopicId, - account: { - userUuid: user.gradidoId, - accountNr: 1 - } + accountNr: 0, + }, }).getKey() - const accountKeyPair = await cache.getKeyPair(accountKeyPairKey, () => Promise.resolve(accountKeyPairRole.generateKeyPair())) + const userKeyPair = await cache.getKeyPair(userKeyPairKey, () => + Promise.resolve(userKeyPairRole.generateKeyPair()), + ) + + const accountKeyPairRole = new AccountKeyPairRole(1, userKeyPair) + const accountKeyPairKey = new KeyPairIdentifierLogic({ + communityTopicId: communityTopicId, + account: { + userUuid: user.gradidoId, + accountNr: 1, + }, + }).getKey() + const accountKeyPair = await cache.getKeyPair(accountKeyPairKey, () => + Promise.resolve(accountKeyPairRole.generateKeyPair()), + ) //logger.info(`Key Pairs for user and account added, user: ${userKeyPairKey}, account: ${accountKeyPairKey}`) return { userKeyPair: userKeyPair.getPublicKey()!, - accountKeyPair: accountKeyPair.getPublicKey()! + accountKeyPair: accountKeyPair.getPublicKey()!, } -} \ No newline at end of file +} diff --git a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/utils.ts b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/utils.ts index 57ae73137..c9b4eccb9 100644 --- a/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/utils.ts +++ b/dlt-connector/src/migrations/db-v2.7.0_to_blockchain-v3.5/utils.ts @@ -12,4 +12,4 @@ export function calculateOneHashStep(hash: Buffer, data: Buffer): Buffer= 1'), v.maxLength(255, 'expect string length <= 255'), - v.regex(/^[a-zA-Z0-9-_]+$/, - 'expect string to be a valid (alphanumeric, _, -) folder name'), + v.regex(/^[a-zA-Z0-9-_]+$/, 'expect string to be a valid (alphanumeric, _, -) folder name'), ), }) @@ -63,4 +67,4 @@ export type UserDb = v.InferOutput export type CreatedUserDb = v.InferOutput export type TransactionLinkDb = v.InferOutput export type CommunityDb = v.InferOutput -export type CommunityContext = v.InferOutput \ No newline at end of file +export type CommunityContext = v.InferOutput diff --git a/dlt-connector/src/schemas/typeConverter.schema.ts b/dlt-connector/src/schemas/typeConverter.schema.ts index d5ca78ea3..8774bd6c2 100644 --- a/dlt-connector/src/schemas/typeConverter.schema.ts +++ b/dlt-connector/src/schemas/typeConverter.schema.ts @@ -29,10 +29,14 @@ export const dateSchema = v.pipe( ) export const booleanSchema = v.pipe( - v.union([v.boolean('expect boolean type'), v.number('expect boolean number type'), v.string('expect boolean string type')]), + v.union([ + v.boolean('expect boolean type'), + v.number('expect boolean number type'), + v.string('expect boolean string type'), + ]), v.transform((input) => { if (typeof input === 'number') { - return input != 0 + return input !== 0 } else if (typeof input === 'string') { return input === 'true' } diff --git a/dlt-connector/src/utils/time.ts b/dlt-connector/src/utils/time.ts index 4f69ebd98..6ec73a661 100644 --- a/dlt-connector/src/utils/time.ts +++ b/dlt-connector/src/utils/time.ts @@ -43,4 +43,4 @@ export const printTimeDuration = (duration: number): string => { return result } -export const delay = promisify(setTimeout) \ No newline at end of file +export const delay = promisify(setTimeout)