refactor, finalize export to blockchain file

This commit is contained in:
einhornimmond 2025-11-08 12:47:49 +01:00
parent f09c8e917d
commit 290a6a4f27
18 changed files with 259 additions and 123 deletions

View File

@ -24,6 +24,7 @@
"jsonrpc-ts-client": "^0.2.3",
"log4js": "^6.9.1",
"mysql2": "^3.15.3",
"sodium-native": "5.0.9",
"typescript": "^5.8.3",
"uuid": "^8.3.2",
"valibot": "1.1.0",
@ -342,6 +343,18 @@
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"bare-addon-resolve": ["bare-addon-resolve@1.9.5", "", { "dependencies": { "bare-module-resolve": "^1.10.0", "bare-semver": "^1.0.0" }, "peerDependencies": { "bare-url": "*" }, "optionalPeers": ["bare-url"] }, "sha512-XdqrG73zLK9LDfblOJwoAxmJ+7YdfRW4ex46+f4L+wPhk7H7LDrRMAbBw8s8jkxeEFpUenyB7QHnv0ErAWd3Yg=="],
"bare-module-resolve": ["bare-module-resolve@1.11.2", "", { "dependencies": { "bare-semver": "^1.0.0" }, "peerDependencies": { "bare-url": "*" }, "optionalPeers": ["bare-url"] }, "sha512-HIBu9WacMejg3Dz4X1v6lJjp7ECnwpujvuLub+8I7JJLRwJaGxWMzGYvieOoS9R1n5iRByvTmLtIdPbwjfRgiQ=="],
"bare-os": ["bare-os@3.6.2", "", {}, "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A=="],
"bare-path": ["bare-path@3.0.0", "", { "dependencies": { "bare-os": "^3.0.1" } }, "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw=="],
"bare-semver": ["bare-semver@1.0.2", "", {}, "sha512-ESVaN2nzWhcI5tf3Zzcq9aqCZ676VWzqw07eEZ0qxAcEOAFYBa0pWq8sK34OQeHLY3JsfKXZS9mDyzyxGjeLzA=="],
"bare-url": ["bare-url@2.3.2", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw=="],
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.20", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ=="],
@ -862,6 +875,8 @@
"regenerator-runtime": ["regenerator-runtime@0.13.11", "", {}, "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="],
"require-addon": ["require-addon@1.1.0", "", { "dependencies": { "bare-addon-resolve": "^1.3.0", "bare-url": "^2.1.0" } }, "sha512-KbXAD5q2+v1GJnkzd8zzbOxchTkStSyJZ9QwoCq3QwEXAaIlG3wDYRZGzVD357jmwaGY7hr5VaoEAL0BkF0Kvg=="],
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
"resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
@ -906,6 +921,8 @@
"slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"sodium-native": ["sodium-native@5.0.9", "", { "dependencies": { "require-addon": "^1.1.0", "which-runtime": "^1.2.1" } }, "sha512-6fpu3d6zdrRpLhuV3CDIBO5g90KkgaeR+c3xvDDz0ZnDkAlqbbPhFW7zhMJfsskfZ9SuC3SvBbqvxcECkXRyKw=="],
"sonic-boom": ["sonic-boom@4.2.0", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww=="],
"source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="],
@ -1006,6 +1023,8 @@
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
"which-runtime": ["which-runtime@1.3.2", "", {}, "sha512-5kwCfWml7+b2NO7KrLMhYihjRx0teKkd3yGp1Xk5Vaf2JGdSh+rgVhEALAD9c/59dP+YwJHXoEO7e8QPy7gOkw=="],
"wide-align": ["wide-align@1.1.5", "", { "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } }, "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg=="],
"wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],

View File

@ -38,6 +38,7 @@
"jsonrpc-ts-client": "^0.2.3",
"log4js": "^6.9.1",
"mysql2": "^3.15.3",
"sodium-native": "5.0.9",
"typescript": "^5.8.3",
"uuid": "^8.3.2",
"valibot": "1.1.0",

View File

@ -1,32 +1,31 @@
import { drizzle, MySql2Database } from 'drizzle-orm/mysql2'
import mysql from 'mysql2/promise'
import { InMemoryBlockchain } from 'gradido-blockchain-js'
import { Filter, Profiler, SearchDirection_ASC } from 'gradido-blockchain-js'
import { getLogger, Logger } from 'log4js'
import { HieroId, Uuidv4 } from '../../schemas/typeGuard.schema'
import { Uuidv4 } from '../../schemas/typeGuard.schema'
import { KeyPairCacheManager } from '../../cache/KeyPairCacheManager'
import { loadConfig } from '../../bootstrap/init'
import { CONFIG } from '../../config'
import { LOG4JS_BASE_CATEGORY } from '../../config/const'
export type CommunityContext = {
communityId: string
blockchain: InMemoryBlockchain
topicId: HieroId
}
import { heapStats } from 'bun:jsc'
import { CommunityContext } from './valibot.schema'
import { bytesToMbyte } from './utils'
export class Context {
public logger: Logger
public db: MySql2Database
public communities: Map<string, CommunityContext>
public cache: KeyPairCacheManager
private timeUsed: Profiler
constructor(logger: Logger, db: MySql2Database, cache: KeyPairCacheManager) {
this.logger = logger
this.db = db
this.cache = cache
this.communities = new Map<string, CommunityContext>()
this.timeUsed = new Profiler()
}
static async create(): Promise<Context> {
@ -53,4 +52,29 @@ export class Context {
}
return community
}
logRuntimeStatistics() {
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`
)
}
logBlogchain(communityUuid: Uuidv4) {
const communityContext = this.getCommunityContextByUuid(communityUuid)
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++) {
const transaction = transactions.get(i)
const confirmedTransaction = transaction?.getConfirmedTransaction()
this.logger.info(confirmedTransaction?.toJson(true))
}
}
// TODO: move into utils
}

View File

@ -0,0 +1,8 @@
export enum TransactionTypeId {
CREATION = 1,
SEND = 2,
RECEIVE = 3,
// This is a virtual property, never occurring on the database
DECAY = 4,
LINK_SUMMARY = 5,
}

View File

@ -0,0 +1,76 @@
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 { Context } from './Context'
import { CommunityContext } from './valibot.schema'
export function exportAllCommunities(context: Context, batchSize: number) {
const timeUsed = new Profiler()
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) {
// write as binary file for GradidoNode
const f = new Filter()
f.pagination.size = batchSize
f.pagination.page = 1
f.searchDirection = SearchDirection_ASC
const binFilePath = prepareFolder(communityContext)
let lastTransactionCount = 0
let hash = Buffer.alloc(32, 0)
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
if (!confirmedTransaction) {
throw new Error(`invalid TransactionEntry at index: ${transactionNr} `)
}
hash = exportTransaction(confirmedTransaction, hash, binFilePath)
}
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`
)
}
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`)
}
hash = calculateOneHashStep(hash, binBlock.data())
sizeBuffer.writeUInt16LE(binBlock.size(), 0)
fs.appendFileSync(binFilePath, sizeBuffer)
fs.appendFileSync(binFilePath, binBlock.data())
return hash
}
function prepareFolder(communityContext: CommunityContext): string {
const binFileFolder = path.join(
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 })
return binFilePath
}

View File

@ -28,6 +28,7 @@ function addToBlockchain(builder: GradidoTransactionBuilder, blockchain: InMemor
const transaction = builder.build()
const transactionId = new HieroTransactionId(createdAtTimestamp, defaultHieroAccount)
const interactionSerialize = new InteractionSerialize(transactionId)
try {
const result = blockchain.createAndAddConfirmedTransaction(transaction, interactionSerialize.run(), createdAtTimestamp)
return result

View File

@ -1,5 +1,4 @@
import { Context } from './Context'
import { CommunityContext } from './Context'
import { loadCommunities } from './database'
import { HieroId, hieroIdSchema } from '../../schemas/typeGuard.schema'
import * as v from 'valibot'
@ -7,6 +6,7 @@ import { InMemoryBlockchainProvider } from 'gradido-blockchain-js'
import { generateKeyPairCommunity } from './keyPair'
import { communityDbToCommunity } from './convert'
import { addCommunityRootTransaction } from './blockchain'
import { CommunityContext } from './valibot.schema'
export async function bootstrap(): Promise<Context> {
const context = await Context.create()
@ -35,7 +35,8 @@ async function bootstrapCommunities(context: Context): Promise<Map<string, Commu
communities.set(communityDb.communityUuid, {
communityId: communityDb.uniqueAlias,
blockchain,
topicId
topicId,
folder: communityDb.uniqueAlias.replace(/[^a-zA-Z0-9]/g, '_'),
})
generateKeyPairCommunity(communityDb, context.cache, topicId)

View File

@ -1,9 +1,10 @@
import { InputTransactionType } from '../../data/InputTransactionType.enum'
import { CommunityDb, TransactionDb, TransactionTypeId, CreatedUserDb, TransactionLinkDb } from './database'
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 { TransactionTypeId } from './TransactionTypeId'
export function getInputTransactionTypeFromTypeId(typeId: TransactionTypeId): InputTransactionType {
switch (typeId) {

View File

@ -1,5 +1,3 @@
import { memoSchema, uuidv4Schema, identifierSeedSchema, gradidoAmountSchema } from '../../schemas/typeGuard.schema'
import { dateSchema, booleanSchema } from '../../schemas/typeConverter.schema'
import * as v from 'valibot'
import { LOG4JS_BASE_CATEGORY } from '../../config/const'
import { getLogger } from 'log4js'
@ -8,61 +6,17 @@ import { communitiesTable, transactionLinksTable, transactionsTable, usersTable
import { asc, sql, eq, isNotNull } from 'drizzle-orm'
import { alias } from 'drizzle-orm/mysql-core'
import { GradidoUnit } from 'gradido-blockchain-js'
export const createdUserDbSchema = v.object({
gradidoId: uuidv4Schema,
communityUuid: uuidv4Schema,
createdAt: dateSchema,
})
export const userDbSchema = v.object({
gradidoId: uuidv4Schema,
communityUuid: uuidv4Schema,
})
export enum TransactionTypeId {
CREATION = 1,
SEND = 2,
RECEIVE = 3,
// This is a virtual property, never occurring on the database
DECAY = 4,
LINK_SUMMARY = 5,
}
export const transactionDbSchema = v.object({
typeId: v.enum(TransactionTypeId),
amount: gradidoAmountSchema,
balanceDate: dateSchema,
memo: memoSchema,
creationDate: v.nullish(dateSchema),
user: userDbSchema,
linkedUser: userDbSchema,
transactionLinkCode: v.nullish(identifierSeedSchema),
})
export const transactionLinkDbSchema = v.object({
user: userDbSchema,
code: identifierSeedSchema,
amount: gradidoAmountSchema,
memo: memoSchema,
createdAt: dateSchema,
validUntil: dateSchema,
})
export const communityDbSchema = v.object({
foreign: booleanSchema,
communityUuid: uuidv4Schema,
name: v.string(),
creationDate: dateSchema,
userMinCreatedAt: dateSchema,
uniqueAlias: v.string(),
})
export type TransactionDb = v.InferOutput<typeof transactionDbSchema>
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>
import {
CommunityDb,
communityDbSchema,
CreatedUserDb,
createdUserDbSchema,
TransactionDb,
transactionDbSchema,
TransactionLinkDb,
transactionLinkDbSchema
} from './valibot.schema'
import { TransactionTypeId } from './TransactionTypeId'
const logger = getLogger(`${LOG4JS_BASE_CATEGORY}.migrations.db-v2.7.0_to_blockchain-v3.6.blockchain`)

View File

@ -2,7 +2,6 @@
import { mysqlTable, unique, int, varchar, char, datetime, tinyint, decimal, index } from 'drizzle-orm/mysql-core'
import { sql } from 'drizzle-orm'
// 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(),
@ -14,7 +13,6 @@ export const communitiesTable = mysqlTable('communities', {
unique('uuid_key').on(table.communityUuid),
])
export const usersTable = mysqlTable('users', {
id: int().autoincrement().notNull(),
gradidoId: char('gradido_id', { length: 36 }).notNull(),
@ -27,20 +25,19 @@ export const usersTable = mysqlTable('users', {
export const transactionsTable = mysqlTable('transactions', {
id: int().autoincrement().notNull(),
typeId: int("type_id").default(sql`NULL`),
transactionLinkId: int("transaction_link_id").default(sql`NULL`),
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(),
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`),
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),
index('user_id').on(table.userId),
])
export const transactionLinksTable = mysqlTable('transaction_links', {
id: int().autoincrement().notNull(),
userId: int().notNull(),

View File

@ -1,18 +1,12 @@
import {
InMemoryBlockchain,
Filter,
SearchDirection_ASC,
Profiler
} from 'gradido-blockchain-js'
import { Logger } from 'log4js'
import { bootstrap } from './bootstrap'
import { heapStats } from 'bun:jsc'
import { onShutdown } from '../../../../shared/src/helper/onShutdown'
import { syncDbWithBlockchainContext } from './interaction/syncDbWithBlockchain/syncDbWithBlockchain.context'
import { exportAllCommunities } from './binaryExport'
import { Filter } from 'gradido-blockchain-js'
const BATCH_SIZE = 100
async function main() {
const timeUsed = new Profiler()
// prepare in memory blockchains
const context = await bootstrap()
onShutdown(async (reason, error) => {
@ -22,42 +16,19 @@ async function main() {
}
})
// synchronize to blockchain
const BATCH_SIZE = 100
// synchronize to in memory blockchain
await syncDbWithBlockchainContext(context, BATCH_SIZE)
// write as binary file for GradidoNode
exportAllCommunities(context, BATCH_SIZE)
// log runtime statistics
context.logRuntimeStatistics()
try {
await syncDbWithBlockchainContext(context, BATCH_SIZE)
} catch (e) {
console.error(e)
throw e
}
context.logger.info(`${timeUsed.string()} for synchronizing to blockchain`)
const runtimeStats = heapStats()
context.logger.info(
`Memory Statistics: heap size: ${bytesToMbyte(runtimeStats.heapSize)} MByte, heap capacity: ${bytesToMbyte(runtimeStats.heapCapacity)} MByte, extra memory: ${bytesToMbyte(runtimeStats.extraMemorySize)} MByte`
)
// needed because of shutdown handler (TODO: fix shutdown handler)
process.exit(0)
}
function bytesToMbyte(bytes: number): string {
return (bytes / 1024 / 1024).toFixed(4)
}
function logBlogchain(logger: Logger, blockchain: InMemoryBlockchain) {
const f = new Filter()
f.pagination.size = 0
f.searchDirection = SearchDirection_ASC
const transactions = blockchain.findAll(f)
for(let i = 0; i < transactions.size(); i++) {
const transaction = transactions.get(i)
const confirmedTransaction = transaction?.getConfirmedTransaction()
logger.info(confirmedTransaction?.toJson(true))
}
}
main().catch((e) => {
// biome-ignore lint/suspicious/noConsole: maybe logger isn't initialized here
console.error(e)

View File

@ -1,6 +1,6 @@
import { loadDeletedTransactionLinks } from '../../database'
import { TransactionsSyncRole } from './TransactionsSync.role'
import { TransactionDb } from '../../database'
import { TransactionDb } from '../../valibot.schema'
export class DeletedTransactionLinksSyncRole extends TransactionsSyncRole {
itemTypeName(): string {

View File

@ -1,4 +1,5 @@
import { TransactionLinkDb, loadTransactionLinks } from '../../database'
import { TransactionLinkDb } from '../../valibot.schema'
import { loadTransactionLinks } from '../../database'
import { transactionLinkDbToTransaction } from '../../convert'
import { addTransaction } from '../../blockchain'
import { AbstractSyncRole } from './AbstractSync.role'

View File

@ -1,4 +1,5 @@
import { TransactionDb, loadTransactions } from '../../database'
import { TransactionDb } from '../../valibot.schema'
import { loadTransactions } from '../../database'
import { transactionDbToTransaction } from '../../convert'
import { addTransaction } from '../../blockchain'
import { AbstractSyncRole } from './AbstractSync.role'

View File

@ -1,4 +1,4 @@
import { CreatedUserDb } from '../../database'
import { CreatedUserDb } from '../../valibot.schema'
import { AbstractSyncRole } from './AbstractSync.role'
import { loadUsers } from '../../database'
import { generateKeyPairUserAccount } from '../../keyPair'

View File

@ -1,4 +1,4 @@
import { CommunityDb, UserDb } from './database'
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'

View File

@ -0,0 +1,15 @@
import { crypto_generichash_batch, crypto_generichash_KEYBYTES } from 'sodium-native'
export function bytesToMbyte(bytes: number): string {
return (bytes / 1024 / 1024).toFixed(4)
}
export function bytesToKbyte(bytes: number): string {
return (bytes / 1024).toFixed(0)
}
export function calculateOneHashStep(hash: Buffer, data: Buffer): Buffer<ArrayBuffer> {
const outputHash = Buffer.alloc(crypto_generichash_KEYBYTES, 0)
crypto_generichash_batch(outputHash, [hash, data])
return outputHash
}

View File

@ -0,0 +1,66 @@
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'
export const createdUserDbSchema = v.object({
gradidoId: uuidv4Schema,
communityUuid: uuidv4Schema,
createdAt: dateSchema,
})
export const userDbSchema = v.object({
gradidoId: uuidv4Schema,
communityUuid: uuidv4Schema,
})
export const transactionDbSchema = v.object({
typeId: v.enum(TransactionTypeId),
amount: gradidoAmountSchema,
balanceDate: dateSchema,
memo: memoSchema,
creationDate: v.nullish(dateSchema),
user: userDbSchema,
linkedUser: userDbSchema,
transactionLinkCode: v.nullish(identifierSeedSchema),
})
export const transactionLinkDbSchema = v.object({
user: userDbSchema,
code: identifierSeedSchema,
amount: gradidoAmountSchema,
memo: memoSchema,
createdAt: dateSchema,
validUntil: dateSchema,
})
export const communityDbSchema = v.object({
foreign: booleanSchema,
communityUuid: uuidv4Schema,
name: v.string(),
creationDate: dateSchema,
userMinCreatedAt: dateSchema,
uniqueAlias: v.string(),
})
export const communityContextSchema = v.object({
communityId: v.string(),
blockchain: v.instance(InMemoryBlockchain, 'expect InMemoryBlockchain type'),
topicId: hieroIdSchema,
folder: v.pipe(
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'),
),
})
export type TransactionDb = v.InferOutput<typeof transactionDbSchema>
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>