Skip to content

Commit

Permalink
Merge pull request #142 from fioprotocol/main
Browse files Browse the repository at this point in the history
Main > Release 1.4.x
  • Loading branch information
trukhilio authored Jan 16, 2025
2 parents 110f110 + 977b03c commit 03084c4
Show file tree
Hide file tree
Showing 18 changed files with 742 additions and 521 deletions.
84 changes: 15 additions & 69 deletions controller/api/eth.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'dotenv/config';
import fs from 'fs';

import Web3 from 'web3';
import { isAddress } from 'web3-validator';

import fioABI from '../../config/ABI/FIO.json' assert { type: 'json' };
import fioNftABI from '../../config/ABI/FIONFT.json' assert { type: 'json' };
import config from '../../config/config.js';

import {
Expand All @@ -16,40 +14,19 @@ import {
import { ORACLE_CACHE_KEYS } from '../constants/cron-jobs.js';
import { NON_VALID_ORACLE_ADDRESS } from '../constants/errors.js';
import { LOG_FILES_PATH_NAMES } from '../constants/log-files.js';
import { DEFAULT_ETH_GAS_PRICE, ETH_GAS_LIMIT } from '../constants/prices.js';
import {
handleEthChainCommon,
isOracleEthAddressValid,
convertNativeFioIntoFio,
} from '../utils/chain.js';
import { isOracleEthAddressValid, convertNativeFioIntoFio } from '../utils/chain.js';
import {
addLogMessage,
updateEthNonce,
handleChainError,
handleLogFailedWrapItem,
handleEthNonceValue,
handleUpdatePendingPolygonItemsQueue,
handleUpdatePendingItemsQueue,
handleServerError,
} from '../utils/log-files.js';
import { getEthGasPriceSuggestion } from '../utils/prices.js';
import { polygonTransaction } from '../utils/transactions.js';
import { blockChainTransaction } from '../utils/transactions.js';

const {
eth: { ETH_ORACLE_PUBLIC, ETH_ORACLE_PRIVATE, ETH_CONTRACT, ETH_NFT_CONTRACT },
infura: { eth },
oracleCache,
} = config;
const { oracleCache } = config;

class EthCtrl {
constructor() {
this.web3 = new Web3(eth);
this.fioContract = new this.web3.eth.Contract(fioABI, ETH_CONTRACT);
this.fioNftContract = new this.web3.eth.Contract(fioNftABI, ETH_NFT_CONTRACT);
}

// It handles both wrap actions (domain and tokens) on ETH chain, this is designed to prevent nonce collisions,
// when asynchronous jobs make transactions with same nonce value from one address (oracle public address),
// so it causes "replacing already existing transaction in the chain".
async handleWrap() {
if (!oracleCache.get(ORACLE_CACHE_KEYS.isWrapOnEthJobExecuting))
oracleCache.set(ORACLE_CACHE_KEYS.isWrapOnEthJobExecuting, true, 0); // ttl = 0 means that value shouldn't ever been expired
Expand Down Expand Up @@ -80,61 +57,30 @@ class EthCtrl {
let isTransactionProceededSuccessfully = false;

try {
const oraclePublicKey = ETH_ORACLE_PUBLIC;
const oraclePrivateKey = ETH_ORACLE_PRIVATE;

if (
this.web3.utils.isAddress(pubaddress) === true &&
chaincode === ETH_TOKEN_CODE
) {
if (isAddress(pubaddress) === true && chaincode === ETH_TOKEN_CODE) {
//check validation if the address is ERC20 address
console.log(`${logPrefix} preparing wrap action.`);
const wrapFunction = this.fioContract.methods.wrap(
pubaddress,
amount,
wrapOracleId,
);

const wrapABI = wrapFunction.encodeABI();

const chainNonce = await this.web3.eth.getTransactionCount(
oraclePublicKey,
'pending',
);
const txNonce = handleEthNonceValue({ chainNonce });

const common = handleEthChainCommon();

const onSussessTransaction = (receipt) => {
addLogMessage({
filePath: LOG_FILES_PATH_NAMES.ETH,
message: `${ETH_CHAIN_NAME_CONSTANT} ${CONTRACT_NAMES.ERC_20} ${ACTION_NAMES.WRAP_TOKENS} receipt ${JSON.stringify(receipt)}`,
message: `${ETH_CHAIN_NAME_CONSTANT} ${CONTRACT_NAMES.ERC_20} ${ACTION_NAMES.WRAP_TOKENS} receipt ${receipt}`,
});

isTransactionProceededSuccessfully = true;
};

await polygonTransaction({
amount: amount,
await blockChainTransaction({
action: ACTION_NAMES.WRAP_TOKENS,
chainName: ETH_CHAIN_NAME_CONSTANT,
common,
contract: ETH_CONTRACT,
contractName: CONTRACT_NAMES.ERC_20,
data: wrapABI,
defaultGasPrice: DEFAULT_ETH_GAS_PRICE,
getGasPriceSuggestionFn: getEthGasPriceSuggestion,
gasLimit: ETH_GAS_LIMIT,
handleSuccessedResult: onSussessTransaction,
logFilePath: LOG_FILES_PATH_NAMES.ETH,
contractActionParams: {
amount,
obtId: wrapOracleId,
pubaddress,
},
logPrefix,
oraclePrivateKey,
oraclePublicKey,
shouldThrowError: true,
tokenCode: ETH_TOKEN_CODE,
txNonce,
updateNonce: updateEthNonce,
web3Instance: this.web3,
handleSuccessedResult: onSussessTransaction,
});
} else {
console.log(`${logPrefix} Invalid Address`);
Expand All @@ -155,7 +101,7 @@ class EthCtrl {
});
}

handleUpdatePendingPolygonItemsQueue({
handleUpdatePendingItemsQueue({
action: this.handleWrap.bind(this),
logPrefix,
logFilePath: LOG_FILES_PATH_NAMES.wrapEthTransactionQueue,
Expand Down
51 changes: 24 additions & 27 deletions controller/api/fio.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dotenv/config';

import fs from 'fs';

import Web3 from 'web3';
import { Web3 } from 'web3';

import ethCtrl from './eth.js';
import moralis from './moralis.js';
Expand Down Expand Up @@ -33,7 +33,7 @@ import {
getFioDeltasV2,
runUnwrapFioTransaction,
} from '../utils/fio-chain.js';
import { sleep, convertTimestampIntoMs, formatDateYYYYMMDD } from '../utils/general.js';
import { sleep, convertTimestampIntoMs, stringifyWithBigInt } from '../utils/general.js';
import {
addLogMessage,
updateBlockNumberFIOForBurnNFT,
Expand All @@ -47,27 +47,21 @@ import {
getLastProcessedFioOracleItemId,
updateFioOracleId,
handleLogFailedWrapItem,
handleUpdatePendingPolygonItemsQueue,
handleUpdatePendingItemsQueue,
handleServerError,
handleChainError,
} from '../utils/log-files.js';
import MathOp from '../utils/math.js';
import { Web3Service } from '../utils/web3-services.js';

const {
eth: { BLOCKS_RANGE_LIMIT_ETH, BLOCKS_OFFSET_ETH, ETH_CONTRACT, ETH_NFT_CONTRACT },
eth: { BLOCKS_RANGE_LIMIT_ETH, BLOCKS_OFFSET_ETH },
fio: { FIO_TRANSACTION_MAX_RETRIES, FIO_HISTORY_HYPERION_OFFSET, LOWEST_ORACLE_ID },
infura: { eth, polygon },
nfts: { NFT_CHAIN_NAME },
oracleCache,
polygon: { BLOCKS_RANGE_LIMIT_POLY, POLYGON_CONTRACT },
} = config;

const web3 = new Web3(eth);
const polyWeb3 = new Web3(polygon);
const fioTokenContractOnEthChain = new web3.eth.Contract(fioABI, ETH_CONTRACT);
const fioNftContract = new web3.eth.Contract(fioNftABI, ETH_NFT_CONTRACT);
const fioPolygonNftContract = new polyWeb3.eth.Contract(fioPolygonABI, POLYGON_CONTRACT);

// execute unwrap action job
const handleUnwrapFromEthToFioChainJob = async () => {
if (!oracleCache.get(ORACLE_CACHE_KEYS.isUnwrapOnEthJobExecuting))
Expand Down Expand Up @@ -150,7 +144,7 @@ const handleUnwrapFromEthToFioChainJob = async () => {
});
}

handleUpdatePendingPolygonItemsQueue({
handleUpdatePendingItemsQueue({
action: handleUnwrapFromEthToFioChainJob,
logPrefix,
logFilePath: LOG_FILES_PATH_NAMES.unwrapEthTransactionQueue,
Expand Down Expand Up @@ -232,7 +226,7 @@ const handleUnwrapFromPolygonToFioChainJob = async () => {
});
}

handleUpdatePendingPolygonItemsQueue({
handleUpdatePendingItemsQueue({
action: handleUnwrapFromPolygonToFioChainJob,
logPrefix,
logFilePath: LOG_FILES_PATH_NAMES.unwrapPolygonTransactionQueue,
Expand Down Expand Up @@ -384,9 +378,7 @@ class FIOCtrl {
const blocksOffset = parseInt(BLOCKS_OFFSET_ETH) || 0;

const getEthActionsLogs = async (from, to, isTokens = false) => {
return await (
isTokens ? fioTokenContractOnEthChain : fioNftContract
).getPastEvents(
return await Web3Service.getEthContract().getPastEvents(
'unwrapped',
{
fromBlock: from,
Expand All @@ -413,8 +405,9 @@ class FIOCtrl {
};

const getUnprocessedActionsLogs = async (isTokens = false) => {
const chainBlockNumber = await web3.eth.getBlockNumber();
const lastInChainBlockNumber = new MathOp(chainBlockNumber)
const chainBlockNumber = await Web3Service.getEthWeb3().eth.getBlockNumber();

const lastInChainBlockNumber = new MathOp(parseInt(chainBlockNumber))
.sub(blocksOffset)
.toNumber();
const lastProcessedBlockNumber = isTokens
Expand Down Expand Up @@ -472,11 +465,11 @@ class FIOCtrl {

if (unwrapTokensData.length > 0) {
unwrapTokensData.forEach((item) => {
const logText = `${item.transactionHash} ${JSON.stringify(item.returnValues)}`;
const logText = `${item.transactionHash} ${stringifyWithBigInt(item.returnValues)}`;

addLogMessage({
filePath: LOG_FILES_PATH_NAMES.ETH,
message: `${ETH_TOKEN_CODE} ${CONTRACT_NAMES.ERC_20} unwraptokens ${JSON.stringify(item)}`,
message: `${ETH_TOKEN_CODE} ${CONTRACT_NAMES.ERC_20} unwraptokens ${stringifyWithBigInt(item)}`,
});

// save tx data into unwrap tokens and domains queue log file
Expand All @@ -489,11 +482,12 @@ class FIOCtrl {
}
if (unwrapDomainsData.length > 0) {
unwrapDomainsData.forEach((item) => {
const logText = item.transactionHash + ' ' + JSON.stringify(item.returnValues);
const logText =
item.transactionHash + ' ' + stringifyWithBigInt(item.returnValues);

addLogMessage({
filePath: LOG_FILES_PATH_NAMES.ETH,
message: `${ETH_CHAIN_NAME_CONSTANT} ${CONTRACT_NAMES.ERC_721} unwrapdomains ${JSON.stringify(item)}`,
message: `${ETH_CHAIN_NAME_CONSTANT} ${CONTRACT_NAMES.ERC_721} unwrapdomains ${stringifyWithBigInt(item)}`,
});

// save tx data into unwrap tokens and domains queue log file
Expand Down Expand Up @@ -550,7 +544,7 @@ class FIOCtrl {
const blocksRangeLimit = parseInt(BLOCKS_RANGE_LIMIT_POLY);

const getPolygonActionsLogs = async (from, to) => {
return await fioPolygonNftContract.getPastEvents(
return await Web3Service.getPolygonContract().getPastEvents(
'unwrapped',
{
fromBlock: from,
Expand All @@ -575,7 +569,9 @@ class FIOCtrl {
};

const getUnprocessedActionsLogs = async () => {
const lastInChainBlockNumber = await polyWeb3.eth.getBlockNumber();
const lastInChainBlockNumber = parseInt(
await Web3Service.getPolygonWeb3().eth.getBlockNumber(),
);
const lastProcessedBlockNumber =
getLastProceededBlockNumberOnPolygonChainForDomainUnwrapping();

Expand Down Expand Up @@ -623,11 +619,12 @@ class FIOCtrl {

if (data.length > 0) {
data.forEach((item) => {
const logText = item.transactionHash + ' ' + JSON.stringify(item.returnValues);
const logText =
item.transactionHash + ' ' + stringifyWithBigInt(item.returnValues);

addLogMessage({
filePath: LOG_FILES_PATH_NAMES.POLYGON,
message: `${POLYGON_CHAIN_NAME} ${CONTRACT_NAMES.ERC_721} unwrapdomains ${JSON.stringify(item)}`,
message: `${POLYGON_CHAIN_NAME} ${CONTRACT_NAMES.ERC_721} unwrapdomains ${stringifyWithBigInt(item)}`,
});

// save tx data into unwrap tokens and domains queue log file
Expand Down Expand Up @@ -772,7 +769,7 @@ class FIOCtrl {
);

if (existingDomainInBurnList) {
const trxId = `AutomaticDomainBurn${formatDateYYYYMMDD(new Date())}${name}`;
const trxId = `${token_id}AutomaticDomainBurn${name}`;

nftsListToBurn.push({
tokenId: token_id,
Expand Down
Loading

0 comments on commit 03084c4

Please sign in to comment.