first codings finished

This commit is contained in:
clauspeterhuebner 2025-07-23 02:17:37 +02:00
parent f020d860b7
commit 69ed4658f2
2 changed files with 129 additions and 92 deletions

View File

@ -204,10 +204,13 @@ export async function processXComCommittingSendCoins(
sender: dbUser,
recipient: SendCoinsResult,
): Promise<SendCoinsResult> {
const methodLogger = createLogger(`processXComCommittingSendCoins`)
const handshakeID = randombytes_random().toString()
methodLogger.addContext('handshakeID', handshakeID)
const sendCoinsResult = new SendCoinsResult()
try {
if(logger.isDebugEnabled()) {
logger.debug(
if(methodLogger.isDebugEnabled()) {
methodLogger.debug(
'XCom: processXComCommittingSendCoins...', {
receiverCom: new CommunityLoggingView(receiverCom),
senderCom: new CommunityLoggingView(senderCom),
@ -233,40 +236,49 @@ export async function processXComCommittingSendCoins(
memo,
})
if (pendingTx) {
if(logger.isDebugEnabled()) {
logger.debug(`find pending Tx for settlement: ${new PendingTransactionLoggingView(pendingTx)}`)
if(methodLogger.isDebugEnabled()) {
methodLogger.debug(`find pending Tx for settlement: ${new PendingTransactionLoggingView(pendingTx)}`)
}
const receiverFCom = await DbFederatedCommunity.findOneOrFail({
where: {
publicKey: Buffer.from(receiverCom.publicKey),
apiVersion: CONFIG.FEDERATION_BACKEND_SEND_ON_API,
},
})
const client = SendCoinsClientFactory.getInstance(receiverFCom)
if (client instanceof V1_0_SendCoinsClient) {
const args = new SendCoinsArgs()
args.recipientCommunityUuid = pendingTx.linkedUserCommunityUuid
const payload = new SendCoinsJwtPayloadType(
handshakeID,
pendingTx.linkedUserCommunityUuid
? pendingTx.linkedUserCommunityUuid
: CONFIG.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID,
pendingTx.linkedUserGradidoID!,
pendingTx.balanceDate.toISOString(),
pendingTx.amount.mul(-1),
pendingTx.memo,
pendingTx.userCommunityUuid,
pendingTx.userGradidoID!,
pendingTx.userName!,
sender.alias,
)
payload.recipientCommunityUuid = pendingTx.linkedUserCommunityUuid
? pendingTx.linkedUserCommunityUuid
: CONFIG.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID
if (pendingTx.linkedUserGradidoID) {
args.recipientUserIdentifier = pendingTx.linkedUserGradidoID
payload.recipientUserIdentifier = pendingTx.linkedUserGradidoID
}
args.creationDate = pendingTx.balanceDate.toISOString()
args.amount = pendingTx.amount.mul(-1)
args.memo = pendingTx.memo
args.senderCommunityUuid = pendingTx.userCommunityUuid
args.senderUserUuid = pendingTx.userGradidoID
if (pendingTx.userName) {
args.senderUserName = pendingTx.userName
}
args.senderAlias = sender.alias
if(logger.isDebugEnabled()) {
logger.debug(`ready for settleSendCoins with args=${new SendCoinsArgsLoggingView(args)}`)
if(methodLogger.isDebugEnabled()) {
methodLogger.debug(`ready for settleSendCoins with payload=${ JSON.stringify(payload)}`)
}
const jws = await encryptAndSign(payload, senderCom.privateJwtKey!, receiverCom.publicJwtKey!)
// prepare the args for the client invocation
const args = new EncryptedTransferArgs()
args.publicKey = senderCom.publicKey.toString('hex')
args.jwt = jws
args.handshakeID = handshakeID
const acknowledge = await client.settleSendCoins(args)
logger.debug(`returnd from settleSendCoins: ${acknowledge}`)
methodLogger.debug(`return from settleSendCoins: ${acknowledge}`)
if (acknowledge) {
// settle the pending transaction on receiver-side was successfull, so now settle the sender side
try {
@ -290,13 +302,13 @@ export async function processXComCommittingSendCoins(
sendCoinsResult.recipAlias = recipient.recipAlias
}
} catch (err) {
logger.error(`Error in writing sender pending transaction: ${JSON.stringify(err, null, 2)}`)
methodLogger.error(`Error in writing sender pending transaction: ${JSON.stringify(err, null, 2)}`)
// revert the existing pending transaction on receiver side
let revertCount = 0
logger.debug('first try to revertSetteledSendCoins of receiver')
methodLogger.debug('first try to revertSetteledSendCoins of receiver')
do {
if (await client.revertSettledSendCoins(args)) {
logger.debug(
methodLogger.debug(
`revertSettledSendCoins()-1_0... successfull after revertCount=${revertCount}`,
)
// treat revertingSettledSendCoins as an error of the whole sendCoins-process
@ -312,7 +324,7 @@ export async function processXComCommittingSendCoins(
}
}
} catch (err) {
logger.error(`Error: ${JSON.stringify(err, null, 2)}`)
methodLogger.error(`Error: ${JSON.stringify(err, null, 2)}`)
sendCoinsResult.vote = false
}
return sendCoinsResult

View File

@ -10,7 +10,7 @@ import Decimal from 'decimal.js-light'
import { getLogger } from 'log4js'
import { Arg, Mutation, Resolver } from 'type-graphql'
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
import { encryptAndSign, PendingTransactionState } from 'shared'
import { encryptAndSign, PendingTransactionState, verifyAndDecrypt } from 'shared'
import { TransactionTypeId } from '../enum/TransactionTypeId'
import { SendCoinsArgsLoggingView } from '../logger/SendCoinsArgsLogging.view'
import { SendCoinsArgs } from '../model/SendCoinsArgs'
@ -213,135 +213,160 @@ export class SendCoinsResolver {
@Mutation(() => Boolean)
async settleSendCoins(
@Arg('data')
args: SendCoinsArgs,
args: EncryptedTransferArgs,
): Promise<boolean> {
logger.debug(`settleSendCoins() via apiVersion=1_0 ...`, new SendCoinsArgsLoggingView(args))
const methodLogger = createLogger(`settleSendCoins`)
methodLogger.addContext('handshakeID', args.handshakeID)
if(methodLogger.isDebugEnabled()) {
methodLogger.debug(`settleSendCoins() via apiVersion=1_0 ...`, args)
}
const authArgs = await interpretEncryptedTransferArgs(args) as SendCoinsJwtPayloadType
if (!authArgs) {
const errmsg = `invalid settleSendCoins payload of requesting community with publicKey` + args.publicKey
methodLogger.error(errmsg)
throw new Error(errmsg)
}
if(methodLogger.isDebugEnabled()) {
methodLogger.debug(`settleSendCoins() via apiVersion=1_0 ...`, authArgs)
}
// first check if receiver community is correct
const homeCom = await DbCommunity.findOneBy({
communityUuid: args.recipientCommunityUuid,
communityUuid: authArgs.recipientCommunityUuid,
})
if (!homeCom) {
throw new LogError(
`settleSendCoins with wrong recipientCommunityUuid`,
args.recipientCommunityUuid,
)
const errmsg = `settleSendCoins with wrong recipientCommunityUuid` + authArgs.recipientCommunityUuid
methodLogger.error(errmsg)
throw new Error(errmsg)
}
// second check if receiver user exists in this community
const receiverUser = await findUserByIdentifier(args.recipientUserIdentifier)
const receiverUser = await findUserByIdentifier(authArgs.recipientUserIdentifier)
if (!receiverUser) {
logger.error('Error in findUserByIdentifier')
throw new LogError(
`settleSendCoins with unknown recipientUserIdentifier in the community=`,
homeCom.name,
)
const errmsg = `settleSendCoins with unknown recipientUserIdentifier in the community=` + homeCom.name
methodLogger.error(errmsg)
throw new Error(errmsg)
}
const pendingTx = await DbPendingTransaction.findOneBy({
userCommunityUuid: args.recipientCommunityUuid,
userCommunityUuid: authArgs.recipientCommunityUuid,
userGradidoID: receiverUser.gradidoID,
state: PendingTransactionState.NEW,
typeId: TransactionTypeId.RECEIVE,
balanceDate: new Date(args.creationDate),
linkedUserCommunityUuid: args.senderCommunityUuid,
linkedUserGradidoID: args.senderUserUuid,
balanceDate: new Date(authArgs.creationDate),
linkedUserCommunityUuid: authArgs.senderCommunityUuid,
linkedUserGradidoID: authArgs.senderUserUuid,
})
logger.debug(
'XCom: settleSendCoins found pendingTX=',
pendingTx ? new PendingTransactionLoggingView(pendingTx) : 'null',
)
if(methodLogger.isDebugEnabled()) {
methodLogger.debug(
'XCom: settleSendCoins found pendingTX=',
pendingTx ? new PendingTransactionLoggingView(pendingTx) : 'null',
)
}
if (
pendingTx &&
pendingTx.amount.toString() === args.amount.toString() &&
pendingTx.memo === args.memo
pendingTx.amount.toString() === authArgs.amount.toString() &&
pendingTx.memo === authArgs.memo
) {
logger.debug('XCom: settleSendCoins matching pendingTX for settlement...')
methodLogger.debug('XCom: settleSendCoins matching pendingTX for settlement...')
await settlePendingReceiveTransaction(homeCom, receiverUser, pendingTx)
// after successful x-com-tx store the recipient as foreign user
logger.debug('store recipient as foreign user...')
if (await storeForeignUser(args)) {
logger.info(
methodLogger.debug('store recipient as foreign user...')
if (await storeForeignUser(authArgs)) {
methodLogger.info(
'X-Com: new foreign user inserted successfully...',
args.senderCommunityUuid,
args.senderUserUuid,
authArgs.senderCommunityUuid,
authArgs.senderUserUuid,
)
}
logger.debug(`XCom: settlePendingReceiveTransaction()-1_0... successful`)
methodLogger.debug(`XCom: settlePendingReceiveTransaction()-1_0... successful`)
return true
} else {
logger.debug('XCom: settlePendingReceiveTransaction NOT matching pendingTX for settlement...')
throw new LogError(
`Can't find in settlePendingReceiveTransaction the pending receiver TX for `,
{
args: new SendCoinsArgsLoggingView(args),
pendingTransactionState: PendingTransactionState.NEW,
methodLogger.debug('XCom: settlePendingReceiveTransaction NOT matching pendingTX for settlement...')
const errmsg = `Can't find in settlePendingReceiveTransaction the pending receiver TX for ` + {
args: new SendCoinsArgsLoggingView(authArgs),
pendingTransactionState: PendingTransactionState.NEW,
transactionTypeId: TransactionTypeId.RECEIVE,
},
)
}
methodLogger.error(errmsg)
throw new Error(errmsg)
}
}
@Mutation(() => Boolean)
async revertSettledSendCoins(
@Arg('data')
args: SendCoinsArgs,
args: EncryptedTransferArgs,
): Promise<boolean> {
logger.debug(`revertSettledSendCoins() via apiVersion=1_0 ...`)
const methodLogger = createLogger(`revertSettledSendCoins`)
methodLogger.addContext('handshakeID', args.handshakeID)
if(methodLogger.isDebugEnabled()) {
methodLogger.debug(`revertSettledSendCoins() via apiVersion=1_0 ...`)
}
const authArgs = await interpretEncryptedTransferArgs(args) as SendCoinsJwtPayloadType
if (!authArgs) {
const errmsg = `invalid revertSettledSendCoins payload of requesting community with publicKey` + args.publicKey
methodLogger.error(errmsg)
throw new Error(errmsg)
}
if(methodLogger.isDebugEnabled()) {
methodLogger.debug(`revertSettledSendCoins() via apiVersion=1_0 ...`, authArgs)
}
// first check if receiver community is correct
const homeCom = await DbCommunity.findOneBy({
communityUuid: args.recipientCommunityUuid,
communityUuid: authArgs.recipientCommunityUuid,
})
if (!homeCom) {
throw new LogError(
`revertSettledSendCoins with wrong recipientCommunityUuid`,
args.recipientCommunityUuid,
)
const errmsg = `revertSettledSendCoins with wrong recipientCommunityUuid` + authArgs.recipientCommunityUuid
methodLogger.error(errmsg)
throw new Error(errmsg)
}
// second check if receiver user exists in this community
const receiverUser = await findUserByIdentifier(args.recipientUserIdentifier)
const receiverUser = await findUserByIdentifier(authArgs.recipientUserIdentifier)
if (!receiverUser) {
logger.error('Error in findUserByIdentifier')
throw new LogError(
`revertSettledSendCoins with unknown recipientUserIdentifier in the community=`,
homeCom.name,
)
const errmsg = `revertSettledSendCoins with unknown recipientUserIdentifier in the community=` + homeCom.name
methodLogger.error(errmsg)
throw new Error(errmsg)
}
const pendingTx = await DbPendingTransaction.findOneBy({
userCommunityUuid: args.recipientCommunityUuid,
userGradidoID: args.recipientUserIdentifier,
userCommunityUuid: authArgs.recipientCommunityUuid,
userGradidoID: authArgs.recipientUserIdentifier,
state: PendingTransactionState.SETTLED,
typeId: TransactionTypeId.RECEIVE,
balanceDate: new Date(args.creationDate),
linkedUserCommunityUuid: args.senderCommunityUuid,
linkedUserGradidoID: args.senderUserUuid,
balanceDate: new Date(authArgs.creationDate),
linkedUserCommunityUuid: authArgs.senderCommunityUuid,
linkedUserGradidoID: authArgs.senderUserUuid,
})
logger.debug(
methodLogger.debug(
'XCom: revertSettledSendCoins found pendingTX=',
pendingTx ? new PendingTransactionLoggingView(pendingTx) : 'null',
)
if (
pendingTx &&
pendingTx.amount.toString() === args.amount.toString() &&
pendingTx.memo === args.memo
pendingTx.amount.toString() === authArgs.amount.toString() &&
pendingTx.memo === authArgs.memo
) {
logger.debug('XCom: revertSettledSendCoins matching pendingTX for remove...')
methodLogger.debug('XCom: revertSettledSendCoins matching pendingTX for remove...')
try {
await revertSettledReceiveTransaction(homeCom, receiverUser, pendingTx)
logger.debug('XCom: revertSettledSendCoins pendingTX successfully')
methodLogger.debug('XCom: revertSettledSendCoins pendingTX successfully')
} catch (err) {
throw new LogError('Error in revertSettledSendCoins of receiver: ', err)
const errmsg = `Error in revertSettledSendCoins of receiver: ` + err
methodLogger.error(errmsg)
throw new Error(errmsg)
}
} else {
logger.debug('XCom: revertSettledSendCoins NOT matching pendingTX...')
throw new LogError(`Can't find in revertSettledSendCoins the pending receiver TX for `, {
args: new SendCoinsArgsLoggingView(args),
methodLogger.debug('XCom: revertSettledSendCoins NOT matching pendingTX...')
const errmsg = `Can't find in revertSettledSendCoins the pending receiver TX for ` + {
args: new SendCoinsArgsLoggingView(authArgs),
pendingTransactionState: PendingTransactionState.SETTLED,
transactionTypeId: TransactionTypeId.RECEIVE,
})
}
methodLogger.error(errmsg)
throw new Error(errmsg)
}
logger.debug(`revertSendCoins()-1_0... successfull`)
methodLogger.debug(`revertSettledSendCoins()-1_0... successfull`)
return true
}
}