mirror of
https://github.com/IT4Change/gradido.git
synced 2026-03-01 12:44:43 +00:00
fix lint
This commit is contained in:
parent
56e4d6387c
commit
a7c3bab20e
@ -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)
|
||||
|
||||
@ -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<void> {
|
||||
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(() => {
|
||||
|
||||
@ -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<HieroId>, homeFolder: string): boolean {
|
||||
export function checkCommunityAvailable(
|
||||
communityTopicIds: Set<HieroId>,
|
||||
homeFolder: string,
|
||||
): boolean {
|
||||
const communitiesPath = path.join(homeFolder, 'communities.json')
|
||||
if (!checkFileExist(communitiesPath)) {
|
||||
return false
|
||||
@ -81,6 +84,8 @@ export function checkCommunityAvailable(communityTopicIds: Set<HieroId>, 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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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'),
|
||||
})
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ import { UserKeyPairRole } from './UserKeyPair.role'
|
||||
*/
|
||||
export async function ResolveKeyPair(input: KeyPairIdentifierLogic): Promise<KeyPairEd25519> {
|
||||
const cache = KeyPairCacheManager.getInstance()
|
||||
|
||||
|
||||
return await cache.getKeyPair(
|
||||
input.getKey(),
|
||||
// function is called from cache manager, if key isn't currently cached
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
}
|
||||
|
||||
@ -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<ArrayBuffer>, binFilePath: string): Buffer<ArrayBuffer> {
|
||||
const sizeBuffer = Buffer.alloc(2)
|
||||
function exportTransaction(
|
||||
confirmedTransaction: ConfirmedTransaction,
|
||||
hash: Buffer<ArrayBuffer>,
|
||||
binFilePath: string,
|
||||
): Buffer<ArrayBuffer> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<void> {
|
||||
export async function addCommunityRootTransaction(
|
||||
blockchain: InMemoryBlockchain,
|
||||
community: Community,
|
||||
): Promise<void> {
|
||||
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<void> {
|
||||
export async function addRegisterAddressTransaction(
|
||||
blockchain: InMemoryBlockchain,
|
||||
transaction: Transaction,
|
||||
): Promise<void> {
|
||||
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<void> {
|
||||
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}`)
|
||||
|
||||
@ -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<Context> {
|
||||
@ -18,18 +18,20 @@ async function bootstrapCommunities(context: Context): Promise<Map<string, Commu
|
||||
const communities = new Map<string, CommunityContext>()
|
||||
const communitiesDb = await loadCommunities(context.db)
|
||||
const topicIds = new Set<HieroId>()
|
||||
|
||||
|
||||
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<Map<string, Commu
|
||||
topicId,
|
||||
folder: communityDb.uniqueAlias.replace(/[^a-zA-Z0-9]/g, '_'),
|
||||
})
|
||||
|
||||
|
||||
generateKeyPairCommunity(communityDb, context.cache, topicId)
|
||||
// create community root transaction 1 minute before first user
|
||||
const creationDate = new Date(new Date(communityDb.userMinCreatedAt).getTime() - 1000 * 60)
|
||||
|
||||
@ -1,10 +1,21 @@
|
||||
import { InputTransactionType } from '../../data/InputTransactionType.enum'
|
||||
import { CommunityDb, TransactionDb, CreatedUserDb, TransactionLinkDb } from './valibot.schema'
|
||||
import { Community, communitySchema, transactionSchema, Transaction, TransactionInput } from '../../schemas/transaction.schema'
|
||||
import { AccountType } from '../../data/AccountType.enum'
|
||||
import { gradidoAmountSchema, HieroId, memoSchema, timeoutDurationSchema } from '../../schemas/typeGuard.schema'
|
||||
import * as v from 'valibot'
|
||||
import { AccountType } from '../../data/AccountType.enum'
|
||||
import { InputTransactionType } from '../../data/InputTransactionType.enum'
|
||||
import {
|
||||
Community,
|
||||
communitySchema,
|
||||
Transaction,
|
||||
TransactionInput,
|
||||
transactionSchema,
|
||||
} from '../../schemas/transaction.schema'
|
||||
import {
|
||||
gradidoAmountSchema,
|
||||
HieroId,
|
||||
memoSchema,
|
||||
timeoutDurationSchema,
|
||||
} from '../../schemas/typeGuard.schema'
|
||||
import { TransactionTypeId } from './TransactionTypeId'
|
||||
import { CommunityDb, CreatedUserDb, TransactionDb, TransactionLinkDb } from './valibot.schema'
|
||||
|
||||
export function getInputTransactionTypeFromTypeId(typeId: TransactionTypeId): InputTransactionType {
|
||||
switch (typeId) {
|
||||
@ -19,13 +30,17 @@ export function getInputTransactionTypeFromTypeId(typeId: TransactionTypeId): In
|
||||
}
|
||||
}
|
||||
|
||||
export function communityDbToCommunity(topicId: HieroId, communityDb: CommunityDb, creationDate: Date): Community {
|
||||
return v.parse(communitySchema, {
|
||||
export function communityDbToCommunity(
|
||||
topicId: HieroId,
|
||||
communityDb: CommunityDb,
|
||||
creationDate: Date,
|
||||
): Community {
|
||||
return v.parse(communitySchema, {
|
||||
hieroTopicId: topicId,
|
||||
uuid: communityDb.communityUuid,
|
||||
foreign: communityDb.foreign,
|
||||
creationDate,
|
||||
})
|
||||
creationDate,
|
||||
})
|
||||
}
|
||||
|
||||
export function userDbToTransaction(userDb: CreatedUserDb, communityTopicId: HieroId): Transaction {
|
||||
@ -41,17 +56,18 @@ export function userDbToTransaction(userDb: CreatedUserDb, communityTopicId: Hie
|
||||
}
|
||||
|
||||
export function transactionDbToTransaction(
|
||||
transactionDb: TransactionDb,
|
||||
communityTopicId: HieroId,
|
||||
recipientCommunityTopicId: HieroId
|
||||
transactionDb: TransactionDb,
|
||||
communityTopicId: HieroId,
|
||||
recipientCommunityTopicId: HieroId,
|
||||
): Transaction {
|
||||
if (
|
||||
transactionDb.typeId !== TransactionTypeId.CREATION
|
||||
&& transactionDb.typeId !== TransactionTypeId.SEND
|
||||
&& transactionDb.typeId !== TransactionTypeId.RECEIVE) {
|
||||
transactionDb.typeId !== TransactionTypeId.CREATION &&
|
||||
transactionDb.typeId !== TransactionTypeId.SEND &&
|
||||
transactionDb.typeId !== TransactionTypeId.RECEIVE
|
||||
) {
|
||||
throw new Error('not implemented')
|
||||
}
|
||||
|
||||
|
||||
const user = {
|
||||
communityTopicId: communityTopicId,
|
||||
account: { userUuid: transactionDb.user.gradidoId },
|
||||
@ -80,7 +96,9 @@ export function transactionDbToTransaction(
|
||||
}
|
||||
if (transactionDb.transactionLinkCode) {
|
||||
if (transactionDb.typeId !== TransactionTypeId.RECEIVE) {
|
||||
throw new Error('linked transaction which isn\'t receive, send will taken care of on link creation')
|
||||
throw new Error(
|
||||
"linked transaction which isn't receive, send will taken care of on link creation",
|
||||
)
|
||||
}
|
||||
transaction.user = {
|
||||
communityTopicId: recipientCommunityTopicId,
|
||||
@ -91,7 +109,10 @@ export function transactionDbToTransaction(
|
||||
return v.parse(transactionSchema, transaction)
|
||||
}
|
||||
|
||||
export function transactionLinkDbToTransaction(transactionLinkDb: TransactionLinkDb, communityTopicId: HieroId): Transaction {
|
||||
export function transactionLinkDbToTransaction(
|
||||
transactionLinkDb: TransactionLinkDb,
|
||||
communityTopicId: HieroId,
|
||||
): Transaction {
|
||||
return v.parse(transactionSchema, {
|
||||
user: {
|
||||
communityTopicId: communityTopicId,
|
||||
@ -105,7 +126,11 @@ export function transactionLinkDbToTransaction(transactionLinkDb: TransactionLin
|
||||
amount: v.parse(gradidoAmountSchema, transactionLinkDb.amount),
|
||||
memo: v.parse(memoSchema, transactionLinkDb.memo),
|
||||
createdAt: transactionLinkDb.createdAt,
|
||||
timeoutDuration: v.parse(timeoutDurationSchema, Math.round((transactionLinkDb.validUntil.getTime() - transactionLinkDb.createdAt.getTime()) / 1000)),
|
||||
timeoutDuration: v.parse(
|
||||
timeoutDurationSchema,
|
||||
Math.round(
|
||||
(transactionLinkDb.validUntil.getTime() - transactionLinkDb.createdAt.getTime()) / 1000,
|
||||
),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -1,38 +1,46 @@
|
||||
import { asc, eq, inArray, isNotNull, sql } from 'drizzle-orm'
|
||||
import { alias } from 'drizzle-orm/mysql-core'
|
||||
import { MySql2Database } from 'drizzle-orm/mysql2'
|
||||
import { GradidoUnit } from 'gradido-blockchain-js'
|
||||
import { getLogger } from 'log4js'
|
||||
import * as v from 'valibot'
|
||||
import { LOG4JS_BASE_CATEGORY } from '../../config/const'
|
||||
import { getLogger } from 'log4js'
|
||||
import { MySql2Database } from 'drizzle-orm/mysql2'
|
||||
import { communitiesTable, transactionLinksTable, transactionsTable, usersTable } from './drizzle.schema'
|
||||
import { asc, sql, eq, isNotNull, inArray } from 'drizzle-orm'
|
||||
import { alias } from 'drizzle-orm/mysql-core'
|
||||
import { GradidoUnit } from 'gradido-blockchain-js'
|
||||
import {
|
||||
CommunityDb,
|
||||
communityDbSchema,
|
||||
CreatedUserDb,
|
||||
createdUserDbSchema,
|
||||
TransactionDb,
|
||||
transactionDbSchema,
|
||||
TransactionLinkDb,
|
||||
transactionLinkDbSchema
|
||||
} from './valibot.schema'
|
||||
import {
|
||||
communitiesTable,
|
||||
transactionLinksTable,
|
||||
transactionsTable,
|
||||
usersTable,
|
||||
} from './drizzle.schema'
|
||||
import { TransactionTypeId } from './TransactionTypeId'
|
||||
import {
|
||||
CommunityDb,
|
||||
CreatedUserDb,
|
||||
communityDbSchema,
|
||||
createdUserDbSchema,
|
||||
TransactionDb,
|
||||
TransactionLinkDb,
|
||||
transactionDbSchema,
|
||||
transactionLinkDbSchema,
|
||||
} from './valibot.schema'
|
||||
|
||||
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`,
|
||||
)
|
||||
|
||||
// queries
|
||||
export async function loadCommunities(db: MySql2Database): Promise<CommunityDb[]> {
|
||||
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<string>()
|
||||
return result.map((row: any) => {
|
||||
@ -49,33 +57,50 @@ export async function loadCommunities(db: MySql2Database): Promise<CommunityDb[]
|
||||
})
|
||||
}
|
||||
|
||||
export async function loadUsers(db: MySql2Database, offset: number, count: number): Promise<CreatedUserDb[]> {
|
||||
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<CreatedUserDb[]> {
|
||||
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<TransactionDb[]> {
|
||||
export async function loadTransactions(
|
||||
db: MySql2Database,
|
||||
offset: number,
|
||||
count: number,
|
||||
): Promise<TransactionDb[]> {
|
||||
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<TransactionLinkDb[]> {
|
||||
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<TransactionLinkDb[]> {
|
||||
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<TransactionDb[]> {
|
||||
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<TransactionDb[]> {
|
||||
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,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
})
|
||||
|
||||
@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
@ -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<T> {
|
||||
private items: T[] = []
|
||||
@ -9,17 +9,18 @@ export abstract class AbstractSyncRole<T> {
|
||||
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<T[]>
|
||||
abstract pushToBlockchain(item: T): Promise<void>
|
||||
abstract itemTypeName(): string
|
||||
|
||||
|
||||
// return count of new loaded items
|
||||
async ensureFilled(batchSize: number): Promise<number>
|
||||
{
|
||||
async ensureFilled(batchSize: number): Promise<number> {
|
||||
if (this.items.length === 0) {
|
||||
let timeUsed: Profiler | undefined
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
@ -28,7 +29,9 @@ export abstract class AbstractSyncRole<T> {
|
||||
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
|
||||
}
|
||||
|
||||
@ -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<TransactionDb[]> {
|
||||
return await loadDeletedTransactionLinks(this.context.db, offset, count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<TransactionLinkDb> {
|
||||
@ -23,4 +23,3 @@ export class TransactionLinksSyncRole extends AbstractSyncRole<TransactionLinkDb
|
||||
await addTransaction(communityContext.blockchain, communityContext.blockchain, transaction)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { TransactionDb } from '../../valibot.schema'
|
||||
import { loadTransactions } from '../../database'
|
||||
import { transactionDbToTransaction } from '../../convert'
|
||||
import { addTransaction } from '../../blockchain'
|
||||
import { transactionDbToTransaction } from '../../convert'
|
||||
import { loadTransactions } from '../../database'
|
||||
import { TransactionDb } from '../../valibot.schema'
|
||||
import { AbstractSyncRole } from './AbstractSync.role'
|
||||
|
||||
export class TransactionsSyncRole extends AbstractSyncRole<TransactionDb> {
|
||||
@ -19,10 +19,19 @@ export class TransactionsSyncRole extends AbstractSyncRole<TransactionDb> {
|
||||
|
||||
async pushToBlockchain(item: TransactionDb): Promise<void> {
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<CreatedUserDb> {
|
||||
getDate(): Date {
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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()!,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,4 +12,4 @@ export function calculateOneHashStep(hash: Buffer, data: Buffer): Buffer<ArrayBu
|
||||
const outputHash = Buffer.alloc(crypto_generichash_KEYBYTES, 0)
|
||||
crypto_generichash_batch(outputHash, [hash, data])
|
||||
return outputHash
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,26 @@
|
||||
import { memoSchema, uuidv4Schema, identifierSeedSchema, gradidoAmountSchema, hieroIdSchema } from '../../schemas/typeGuard.schema'
|
||||
import { dateSchema, booleanSchema } from '../../schemas/typeConverter.schema'
|
||||
import { TransactionTypeId } from './TransactionTypeId'
|
||||
import { InMemoryBlockchain } from 'gradido-blockchain-js'
|
||||
import * as v from 'valibot'
|
||||
import { booleanSchema, dateSchema } from '../../schemas/typeConverter.schema'
|
||||
import {
|
||||
gradidoAmountSchema,
|
||||
hieroIdSchema,
|
||||
identifierSeedSchema,
|
||||
memoSchema,
|
||||
uuidv4Schema,
|
||||
} from '../../schemas/typeGuard.schema'
|
||||
import { TransactionTypeId } from './TransactionTypeId'
|
||||
|
||||
export const createdUserDbSchema = v.object({
|
||||
gradidoId: uuidv4Schema,
|
||||
communityUuid: uuidv4Schema,
|
||||
communityUuid: uuidv4Schema,
|
||||
createdAt: dateSchema,
|
||||
})
|
||||
|
||||
export const userDbSchema = v.object({
|
||||
gradidoId: uuidv4Schema,
|
||||
communityUuid: uuidv4Schema,
|
||||
communityUuid: uuidv4Schema,
|
||||
})
|
||||
|
||||
|
||||
export const transactionDbSchema = v.object({
|
||||
typeId: v.enum(TransactionTypeId),
|
||||
amount: gradidoAmountSchema,
|
||||
@ -53,8 +58,7 @@ export const communityContextSchema = v.object({
|
||||
v.string(),
|
||||
v.minLength(1, 'expect string length >= 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<typeof userDbSchema>
|
||||
export type CreatedUserDb = v.InferOutput<typeof createdUserDbSchema>
|
||||
export type TransactionLinkDb = v.InferOutput<typeof transactionLinkDbSchema>
|
||||
export type CommunityDb = v.InferOutput<typeof communityDbSchema>
|
||||
export type CommunityContext = v.InferOutput<typeof communityContextSchema>
|
||||
export type CommunityContext = v.InferOutput<typeof communityContextSchema>
|
||||
|
||||
@ -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<boolean | number | string, boolean>((input) => {
|
||||
if (typeof input === 'number') {
|
||||
return input != 0
|
||||
return input !== 0
|
||||
} else if (typeof input === 'string') {
|
||||
return input === 'true'
|
||||
}
|
||||
|
||||
@ -43,4 +43,4 @@ export const printTimeDuration = (duration: number): string => {
|
||||
return result
|
||||
}
|
||||
|
||||
export const delay = promisify(setTimeout)
|
||||
export const delay = promisify(setTimeout)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user