Skip to content

Commit

Permalink
Merge pull request #24 from rsksmart/feature/GBI-1584-Guilherme-fedIm…
Browse files Browse the repository at this point in the history
…proviment

Feature/gbi 1584 guilherme fed improviment
  • Loading branch information
MaximStanciu8 authored Jan 19, 2024
2 parents 1d83705 + a73eec0 commit 30fedd1
Show file tree
Hide file tree
Showing 18 changed files with 238 additions and 20,883 deletions.
20,802 changes: 0 additions & 20,802 deletions package-lock.json

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "federator",
"private": "true",
"version": "3.0.2",
"version": "3.0.3",
"description": "RSK Bridge Federator",
"keywords": [
"rsk",
Expand Down
12 changes: 9 additions & 3 deletions src/entities/FailedTransactions.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import {Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn} from 'typeorm';

@Entity()
export class FailedTransactions {
@PrimaryGeneratedColumn()
id: number
id: number;
@Column()
timesRetried: number;
@Column()
mainChain: number;
@Column()
sideChain: number;
@Column()
transactionId: string;
@Column()
txData: string
txData: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}
6 changes: 5 additions & 1 deletion src/entities/Log.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import {Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn} from 'typeorm';

@Entity()
export class Log {
Expand All @@ -10,4 +10,8 @@ export class Log {
sideChain: number;
@Column()
block: number
@CreateDateColumn()
createdAt: Date
@UpdateDateColumn()
updatedAt: Date
}
11 changes: 11 additions & 0 deletions src/entities/LogDebug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Entity, PrimaryGeneratedColumn, Column, CreateDateColumn} from 'typeorm';

@Entity()
export class LogDebug {
@PrimaryGeneratedColumn()
id: number;
@CreateDateColumn()
createdAt: Date;
@Column()
log: string;
}
13 changes: 7 additions & 6 deletions src/lib/Federator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { IFederation } from '../contracts/IFederation';
import { LogWrapper } from './logWrapper';
import {AppDataSource} from "../services/AppDataSource";
import {Log} from "../entities/Log";
import {getLog, insertLog, updateLog} from "../models/log.model";
import {clearOldLogs} from "../models/logDebug.model";

export default abstract class Federator {
public logger: LogWrapper;
Expand Down Expand Up @@ -77,8 +79,7 @@ export default abstract class Federator {
let fromBlock: number = null;
const originalFromBlock = this.config.mainchain.fromBlock || 0;
try {
const log = await AppDataSource.getRepository(Log)
.findOne({ where: { mainChain: mainChainId, sideChain: sideChainId }});
const log = await getLog(mainChainId, sideChainId);
fromBlock = log.block;
} catch (err) {
fromBlock = originalFromBlock;
Expand Down Expand Up @@ -178,14 +179,14 @@ export default abstract class Federator {

async _saveProgress(mainChain: number, sideChain: number, value: number) {
if (value) {
const log = await AppDataSource.getRepository(Log)
.findOne({ where: { mainChain, sideChain }});
const log = await getLog(mainChain, sideChain);

if (log) {
await AppDataSource.getRepository(Log).update({id: log.id}, { block: value });
await updateLog(log.id, { block: value });
} else {
await AppDataSource.getRepository(Log).insert({ mainChain, sideChain, block: value })
await insertLog({ mainChain, sideChain, block: value });
}
}
await clearOldLogs();
}
}
145 changes: 81 additions & 64 deletions src/lib/FederatorERC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ import {
import {AppDataSource} from "../services/AppDataSource";
import {FailedTransactions} from "../entities/FailedTransactions";
import {Votes} from "../entities/Votes";
import {
deleteFailedTransaction,
findFailedTransaction,
insertFailedTransaction, updateFailedTransaction
} from "../models/failedTransactions.model";
import {getVote, insertVote} from "../models/votes.model";
import {insertLogDebug} from "../models/logDebug.model";


type ValidateAndVoteReturn = {
Expand Down Expand Up @@ -58,21 +65,21 @@ export default class FederatorERC extends Federator {
this.logger.trace(`Federator Run started currentBlock: ${currentBlock}, currentChainId: ${mainChainId}`);
const isMainSyncing = await this.getMainChainWeb3().eth.isSyncing();
if (isMainSyncing !== false) {
this.logger.warn(
`ChainId ${mainChainId} is Syncing, ${JSON.stringify(
isMainSyncing,
)}. Federator won't process requests till is synced`,
);
const message = `ChainId ${mainChainId} is Syncing, ${JSON.stringify(
isMainSyncing,
)}. Federator won't process requests till is synced`;
this.logger.warn(message);
await insertLogDebug(message);
return false;
}

const isSideSyncing = await sideChainWeb3.eth.isSyncing();
if (isSideSyncing !== false) {
this.logger.warn(
`ChainId ${sideChainId} is Syncing, ${JSON.stringify(
isSideSyncing,
)}. Federator won't process requests till is synced`,
);
const message = `ChainId ${sideChainId} is Syncing, ${JSON.stringify(
isSideSyncing,
)}. Federator won't process requests till is synced`;
this.logger.warn(message);
await insertLogDebug(message);
return false;
}

Expand Down Expand Up @@ -134,9 +141,9 @@ export default class FederatorERC extends Federator {
}

async getLogsAndProcess(getLogParams: GetLogsParams) {
this.logger.trace(
`getLogsAndProcess started currentBlock: ${getLogParams.currentBlock}, fromBlock: ${getLogParams.fromBlock}, toBlock: ${getLogParams.toBlock}`,
);
const message = `getLogsAndProcess started currentBlock: ${getLogParams.currentBlock}, fromBlock: ${getLogParams.fromBlock}, toBlock: ${getLogParams.toBlock}`;
this.logger.trace(message);
await insertLogDebug(message);
if (getLogParams.fromBlock >= getLogParams.toBlock) {
this.logger.trace('getLogsAndProcess fromBlock >= toBlock', getLogParams.fromBlock, getLogParams.toBlock);
return;
Expand Down Expand Up @@ -223,10 +230,10 @@ export default class FederatorERC extends Federator {
tokenAddress: tokenAddress,
}));
if (!allowed) {
throw new Error(
`Original Token not allowed nor side token Tx:${transactionHash} originalTokenAddress:${tokenAddress}
Bridge Contract Addr ${originBridge}`,
);
const message = `Original Token not allowed nor side token Tx:${transactionHash} originalTokenAddress:${tokenAddress}
Bridge Contract Addr ${originBridge}`;
await insertLogDebug(message);
throw new Error(message);
}
} else {
({allowed, mediumAmount, largeAmount} = await processLogParams.allowTokens.getLimits({
Expand Down Expand Up @@ -282,6 +289,7 @@ export default class FederatorERC extends Federator {
}),
);
this.logger.info('get transaction id:', transactionId);
await insertLogDebug(`Processing transactionID: ${transactionId}`)

await this.processTransaction({
...processLogParams,
Expand Down Expand Up @@ -309,6 +317,7 @@ export default class FederatorERC extends Federator {
destinationChainId: processTransactionParams.destinationChainId,
};
this.logger.info('===dataToHash===', dataToHash);
await insertLogDebug(JSON.stringify(dataToHash));
this.logger.warn('===log===', processTransactionParams.log);
const transactionDataHash = await typescriptUtils.retryNTimes(
processTransactionParams.sideBridgeContract.getTransactionDataHash(dataToHash),
Expand All @@ -317,27 +326,27 @@ export default class FederatorERC extends Federator {
processTransactionParams.sideBridgeContract.getProcessed(transactionDataHash),
);
if (wasProcessed) {
this.logger.info(
`Already processed Block: ${processTransactionParams.log.blockHash} Tx: ${processTransactionParams.log.transactionHash}
originalTokenAddress: ${processTransactionParams.tokenAddress}`,
);
const message = `Already processed Block: ${processTransactionParams.log.blockHash} Tx: ${processTransactionParams.log.transactionHash}
originalTokenAddress: ${processTransactionParams.tokenAddress}`;
this.logger.info(message);
await insertLogDebug(message);
return;
}
const hasVoted = await processTransactionParams.sideFedContract.hasVoted(
processTransactionParams.transactionId,
processTransactionParams.federatorAddress,
);
if (hasVoted) {
this.logger.debug(
`Block: ${processTransactionParams.log.blockHash} Tx: ${processTransactionParams.log.transactionHash}
originalTokenAddress: ${processTransactionParams.tokenAddress} has already been voted by us`,
);
const message = `Block: ${processTransactionParams.log.blockHash} Tx: ${processTransactionParams.log.transactionHash}
originalTokenAddress: ${processTransactionParams.tokenAddress} has already been voted by us`;
this.logger.debug(message);
await insertLogDebug(message);
return;
}
this.logger.info(
`Voting tx: ${processTransactionParams.log.transactionHash} block: ${processTransactionParams.log.blockHash}
originalTokenAddress: ${processTransactionParams.tokenAddress}`,
);
const message = `Voting tx: ${processTransactionParams.log.transactionHash} block: ${processTransactionParams.log.blockHash}
originalTokenAddress: ${processTransactionParams.tokenAddress}`;
this.logger.info(message);
await insertLogDebug(message);
await this._voteTransaction({
...processTransactionParams,
blockHash: processTransactionParams.log.blockHash,
Expand Down Expand Up @@ -380,10 +389,10 @@ export default class FederatorERC extends Federator {
async _voteTransaction(voteTransactionParams: VoteTransactionParams) {
try {
voteTransactionParams.transactionId = voteTransactionParams.transactionId.toLowerCase();
this.logger.info(
`Starting vote process for the TX ${voteTransactionParams.transactionHash} from
${voteTransactionParams.originChainId} with transactionId ${voteTransactionParams.transactionId}`,
);
const message = `Starting vote process for the TX ${voteTransactionParams.transactionHash} from
${voteTransactionParams.originChainId} with transactionId ${voteTransactionParams.transactionId}`;
await insertLogDebug(message);
this.logger.info(message);

const txDataAbi = await voteTransactionParams.sideFedContract.getVoteTransactionABI({
originalTokenAddress: voteTransactionParams.tokenAddress,
Expand All @@ -407,22 +416,19 @@ export default class FederatorERC extends Federator {
}

async verifyIfwasRevertedAndRetry(params, txAbi) {
const revertedTx = await AppDataSource.getRepository(FailedTransactions)
.findOne({
where: {
mainChain: params.mainChainId,
sideChain: params.sideChainId,
transactionId: params.transactionId
}
});
const revertedTx = await findFailedTransaction({
mainChain: params.mainChainId,
sideChain: params.sideChainId,
transactionId: params.transactionId
});

const result = await this.validateAndVote(params, txAbi);

if (revertedTx && (result.voteSuccess || result.wasVotedBefore || result.wasProcessed)) {
await AppDataSource.getRepository(FailedTransactions).delete({
mainChain: params.mainChainId,
sideChain: params.sideChainId,
transactionId: params.transactionId
await deleteFailedTransaction({
mainChain: params.mainChainId,
sideChain: params.sideChainId,
transactionId: params.transactionId
});
}
}
Expand All @@ -440,16 +446,22 @@ export default class FederatorERC extends Federator {
const hasVoted = await params.sideFedContract
.hasVoted(params.transactionId, fedAddress);

const hasVotedDb = await AppDataSource.getRepository(Votes).findOne({
where: {transactionId: params.transactionId}});
const hasVotedDb = await getVote({transactionId: params.transactionId});

const failedRetry = await findFailedTransaction({
transactionId: params.transactionId,
timesRetried: this.config.maxFailedTxRetry
});

const wasProcessed = await params.sideFedContract
.transactionWasProcessed(params.transactionId);

if(hasVoted || wasProcessed || hasVotedDb) {
this.logger.warn(`Transaction ${params.transactionId} will not be voted by the
if(hasVoted || wasProcessed || hasVotedDb || failedRetry) {
const message = `Transaction ${params.transactionId} will not be voted by the
federator: ${fedAddress} hasVoted result ${hasVoted} - wasProcessed result ${wasProcessed} hasVotedDb
result ${hasVotedDb}`);
result ${hasVotedDb}`;
this.logger.warn(message);
await insertLogDebug(message);

validateAndVoteReturn.wasVotedBefore = hasVoted || hasVotedDb;
validateAndVoteReturn.wasProcessed = wasProcessed;
Expand All @@ -470,7 +482,7 @@ export default class FederatorERC extends Federator {
validateAndVoteReturn.receipt = receipt;
validateAndVoteReturn.voteSuccess = true;

await AppDataSource.getRepository(Votes).insert({
const dataToInsert: Partial<Votes> = {
voted: true,
transactionId: params.transactionId,
transactionData: JSON.stringify({
Expand All @@ -485,29 +497,28 @@ export default class FederatorERC extends Federator {
amount: params.amount,
originalTokenAddress: params.tokenAddress,
})
});
};

await insertVote(dataToInsert);
} else {
validateAndVoteReturn.receipt = null;
validateAndVoteReturn.voteSuccess = false;

this.logger.error(
`Voting ${params.amount} of originalTokenAddress:${params.tokenAddress}
TransactionId ${params.transactionId} failed, check the receipt`,
receipt,
);
const message = `Voting ${params.amount} of originalTokenAddress:${params.tokenAddress}
TransactionId ${params.transactionId} failed, check the receipt`;
this.logger.error(message, receipt);
await insertLogDebug(message + ` tx Hash: ${receipt.transactionHash}`)

const hasFailedBefore = await AppDataSource.getRepository(FailedTransactions)
.findOne({
where: {
transactionId: params.transactionId
}
});
const hasFailedBefore = await findFailedTransaction({
transactionId: params.transactionId
});

if(!hasFailedBefore) {
await AppDataSource.getRepository(FailedTransactions).insert({
const dataToInsert: Partial<FailedTransactions> = {
mainChain: params.mainChainId,
sideChain: params.sideChainId,
transactionId: params.transactionId,
timesRetried: 1,
txData: JSON.stringify({
originalTokenAddress: params.tokenAddress,
sender: params.senderAddress,
Expand All @@ -520,6 +531,12 @@ export default class FederatorERC extends Federator {
status: receipt.status,
receipt: {...receipt},
})
};
await insertFailedTransaction(dataToInsert);
} else {
await updateFailedTransaction(hasFailedBefore.id, {
timesRetried: hasFailedBefore.timesRetried + 1 > this.config.maxFailedTxRetry ?
this.config.maxFailedTxRetry : hasFailedBefore.timesRetried + 1
});
}
}
Expand Down
Loading

0 comments on commit 30fedd1

Please sign in to comment.