diff --git a/packages/validator/config/config-local.yaml b/packages/validator/config/config-local.yaml new file mode 100644 index 0000000..874a6e9 --- /dev/null +++ b/packages/validator/config/config-local.yaml @@ -0,0 +1,52 @@ +################################################################################ +## Network interface ## +################################################################################ +server: + # Address to which we bind (default: 127.0.0.1) + address: "${HOST_IP}" + # Port on which we bind (default: 7070) + port: "${HOST_PORT}" + +################################################################################ +## Database options ## +################################################################################ +database: + host: "${DATABASE_HOST}" + user: "${DATABASE_USER}" + password: "${DATABASE_PASSWORD}" + database: "${DATABASE_NAME}" + scheme: "${DATABASE_SCHEME}" + port: "${DATABASE_PORT}" + connectionTimeoutMillis: 5000 + max: 100 + +################################################################################ +## Logging options ## +################################################################################ +logging: + # Values: error, warn, info, http, verbose, debug, silly + level: verbose + +################################################################################ +## Scheduler options ## +################################################################################ +scheduler: + enable: true + items: + - name: bridge + enable: true + expression: "*/10 * * * * *" + +bridge: + networkAName: "production_main" + networkABridgeAddress: "0x4Ca91738C7cD24895467c6d550D96BE8dC4b33AA" + networkATokenAddress: "0xB1A90a5C6e30d64Ab6f64C30eD392F46eDBcb022" + networkBName: "production_side" + networkBBridgeAddress: "0xd73e6a2f2e47236F1Ff737E72497f598652122F9" + networkBTokenAddress: "0xB1A90a5C6e30d64Ab6f64C30eD392F46eDBcb022" + validators: + - "${BRIDGE_VALIDATOR1}" + - "${BRIDGE_VALIDATOR2}" + - "${BRIDGE_VALIDATOR3}" + - "${BRIDGE_VALIDATOR4}" + - "${BRIDGE_VALIDATOR5}" diff --git a/packages/validator/config/config-testnet.yaml b/packages/validator/config/config-testnet.yaml new file mode 100644 index 0000000..169e731 --- /dev/null +++ b/packages/validator/config/config-testnet.yaml @@ -0,0 +1,52 @@ +################################################################################ +## Network interface ## +################################################################################ +server: + # Address to which we bind (default: 127.0.0.1) + address: "${HOST_IP}" + # Port on which we bind (default: 7070) + port: "${HOST_PORT}" + +################################################################################ +## Database options ## +################################################################################ +database: + host: "${DATABASE_HOST}" + user: "${DATABASE_USER}" + password: "${DATABASE_PASSWORD}" + database: "${DATABASE_NAME}" + scheme: "${DATABASE_SCHEME}" + port: "${DATABASE_PORT}" + connectionTimeoutMillis: 5000 + max: 100 + +################################################################################ +## Logging options ## +################################################################################ +logging: + # Values: error, warn, info, http, verbose, debug, silly + level: verbose + +################################################################################ +## Scheduler options ## +################################################################################ +scheduler: + enable: true + items: + - name: bridge + enable: true + expression: "*/10 * * * * *" + +bridge: + networkAName: "production_main" + networkABridgeAddress: "0x7265F4D550AEdc3Ed97a6ae6dDAf4289eDFaC0C5" + networkATokenAddress: "0x3A90432BBfd5Bd87788f397F46c24685492fb30E" + networkBName: "production_side" + networkBBridgeAddress: "0x6DA3F9D26C5964ab6E3902fFD7907B6bc3465493" + networkBTokenAddress: "0x3A90432BBfd5Bd87788f397F46c24685492fb30E" + validators: + - "${BRIDGE_VALIDATOR1}" + - "${BRIDGE_VALIDATOR2}" + - "${BRIDGE_VALIDATOR3}" + - "${BRIDGE_VALIDATOR4}" + - "${BRIDGE_VALIDATOR5}" diff --git a/packages/validator/config/config.yaml b/packages/validator/config/config.yaml index 874a6e9..169e731 100644 --- a/packages/validator/config/config.yaml +++ b/packages/validator/config/config.yaml @@ -39,11 +39,11 @@ scheduler: bridge: networkAName: "production_main" - networkABridgeAddress: "0x4Ca91738C7cD24895467c6d550D96BE8dC4b33AA" - networkATokenAddress: "0xB1A90a5C6e30d64Ab6f64C30eD392F46eDBcb022" + networkABridgeAddress: "0x7265F4D550AEdc3Ed97a6ae6dDAf4289eDFaC0C5" + networkATokenAddress: "0x3A90432BBfd5Bd87788f397F46c24685492fb30E" networkBName: "production_side" - networkBBridgeAddress: "0xd73e6a2f2e47236F1Ff737E72497f598652122F9" - networkBTokenAddress: "0xB1A90a5C6e30d64Ab6f64C30eD392F46eDBcb022" + networkBBridgeAddress: "0x6DA3F9D26C5964ab6E3902fFD7907B6bc3465493" + networkBTokenAddress: "0x3A90432BBfd5Bd87788f397F46c24685492fb30E" validators: - "${BRIDGE_VALIDATOR1}" - "${BRIDGE_VALIDATOR2}" diff --git a/packages/validator/env/.env.testnet b/packages/validator/env/.env.testnet new file mode 100644 index 0000000..4647a28 --- /dev/null +++ b/packages/validator/env/.env.testnet @@ -0,0 +1,34 @@ +# HOST SERVER +HOST_IP=0.0.0.0 +HOST_PORT=7500 + +# CHAIN URL +PRODUCTION_MAIN_URL=https://testnet.bosagora.org +PRODUCTION_MAIN_CHAIN_ID=2019 +PRODUCTION_SIDE_URL=https://rpc.test.kios.bosagora.org +PRODUCTION_SIDE_CHAIN_ID=215115 + +# DATABASE INFO +DATABASE_HOST=127.0.0.1 +DATABASE_USER=agora +DATABASE_NAME=bridge-loyalty +DATABASE_SCHEME= +DATABASE_PASSWORD=12345678 +DATABASE_PORT=5432 + +# 0x6F8CF905906dDe9E440F0DF5B26146cf1f195F12 +DEPLOYER=0x0d451ab5bd459f59fda0cf8018cfbfa4df5c454c5c25a844b70a5afcaf246c98 +# 0x6629E54deC62B88b34d6fF7439B290cC0f1bfaEC +FEE=0xcfefe53d3c74cda9aa7b0af55d0b615cdcf7d4ed3b8653fb87fb2259f083f007 +# 0x035DEa1B3427B7118B0750aA3e2341dBf3eB521d +BRIDGE_VALIDATOR1=0xdc09a76275fd2e8cfc8e5bf3cd2d04d4ff1be591d5b852f9cf939adeef1a09f2 +# 0xF8d80AB87DFd751d9B045FE68ACB47eBaa6fa361 +BRIDGE_VALIDATOR2=0xe77a456994aa357ed3a7fa20974445ba55a752593499901182ec24892042861f +# 0xf762Eea24A9B751D49159478214d37c414FE9037 +BRIDGE_VALIDATOR3=0x26d91992f8f68e10e398d0e752713d48bbe279e3f33f99930b7c570f4d1044ea +# 0x060c3D1ec7EE75FB45DC229B3ed58167AD826740 +BRIDGE_VALIDATOR4=0xdc4ecf707e85aa04b1c107f211af1294ce235192dd06e048cc527b0adc07955a +# 0x443bc4b6D445459047423Eae577d6E01eE490B78 +BRIDGE_VALIDATOR5=0x5b620b1429056d3429647d06d460236adbde78b12bb1226a29a1896a1e6d35cd + +REPORT_GAS=true diff --git a/packages/validator/package.json b/packages/validator/package.json index 33c6f77..fae9887 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -74,7 +74,7 @@ "dotenv": "^10.0.0", "ethereum-waffle": "^4.0.10", "ethereumjs-util": "^7.1.5", - "ethers": "npm:boa-ethers2@^5.7.9", + "ethers": "^5.7.0", "expo-server-sdk": "^3.7.0", "express": "^4.17.1", "express-validator": "^6.14.0", diff --git a/packages/validator/src/DefaultServer.ts b/packages/validator/src/DefaultServer.ts index dff9a34..f6d8a1c 100644 --- a/packages/validator/src/DefaultServer.ts +++ b/packages/validator/src/DefaultServer.ts @@ -21,7 +21,6 @@ export class DefaultServer extends WebService { public readonly defaultRouter: DefaultRouter; public readonly storage: ValidatorStorage; - public readonly validators: Validator[]; /** * Constructor @@ -40,7 +39,6 @@ export class DefaultServer extends WebService { this.config = config; this.storage = storage; this.defaultRouter = new DefaultRouter(this, this.metrics); - this.validators = this.config.bridge.validators.map((m) => new Validator(this.config, this.storage, m)); if (!schedules) schedules = []; schedules.forEach((m) => this.schedules.push(m)); @@ -49,7 +47,6 @@ export class DefaultServer extends WebService { config: this.config, storage: this.storage, metrics: this.metrics, - validators: this.validators, }) ); } diff --git a/packages/validator/src/scheduler/BridgeScheduler.ts b/packages/validator/src/scheduler/BridgeScheduler.ts index 7906e6a..125fb3e 100644 --- a/packages/validator/src/scheduler/BridgeScheduler.ts +++ b/packages/validator/src/scheduler/BridgeScheduler.ts @@ -28,6 +28,9 @@ export class BridgeScheduler extends Scheduler { private _tokenIdA: string | undefined; private _tokenIdB: string | undefined; + private _providerA: ethers.providers.Provider | undefined; + private _providerB: ethers.providers.Provider | undefined; + private old_time_stamp: number; private new_time_stamp: number; @@ -73,47 +76,63 @@ export class BridgeScheduler extends Scheduler { if (options) { if (options.config && options.config instanceof Config) this._config = options.config; if (options.storage && options.storage instanceof ValidatorStorage) this._storage = options.storage; - if (options.validators) this._validators = options.validators; if (options.metrics && options.metrics instanceof Metrics) this._metrics = options.metrics; } } public async onStart() { + console.log("Chain A : ", this.config.bridge.networkAName); + console.log(" Bridge : ", this.config.bridge.networkABridgeAddress); + console.log(" Token : ", this.config.bridge.networkATokenAddress); + console.log("Chain B : ", this.config.bridge.networkBName); + console.log(" Bridge : ", this.config.bridge.networkBBridgeAddress); + console.log(" Token : ", this.config.bridge.networkBTokenAddress); + console.log(""); + await hre.changeNetwork(this.config.bridge.networkAName); + this._providerA = hre.ethers.provider; this._bridgeA = new hre.ethers.Contract( this.config.bridge.networkABridgeAddress, IBridge__factory.createInterface(), - hre.ethers.provider - ) as IBridge; + this._providerA + ).connect(this._providerA) as IBridge; const factoryA = await hre.ethers.getContractFactory("BIP20DelegatedTransfer"); - this._tokenA = factoryA.attach(this.config.bridge.networkATokenAddress); + this._tokenA = factoryA.attach(this.config.bridge.networkATokenAddress).connect(this._providerA); this._tokenIdA = ContractUtils.getTokenId(await this._tokenA.name(), await this._tokenA.symbol()); - console.log("Chain A: ", this.config.bridge.networkAName); - console.log(" : ", this.config.bridge.networkABridgeAddress); - const balanceA1 = new BOACoin( - await this._bridgeA.provider.getBalance(this.config.bridge.networkABridgeAddress) - ); - console.log("BOA : ", balanceA1.toDisplayString(true, 2)); - + const balanceA1 = new BOACoin(await this._tokenA.provider.getBalance(this.config.bridge.networkABridgeAddress)); + console.log("Chain A Balance : "); + console.log(" BOA : ", balanceA1.toDisplayString(true, 2)); const balanceA2 = new BOACoin(await this._bridgeA.getTotalLiquidity(this._tokenIdA)); - console.log("Token : ", balanceA2.toDisplayString(true, 2)); + console.log(" Token : ", balanceA2.toDisplayString(true, 2)); await hre.changeNetwork(this.config.bridge.networkBName); + this._providerB = hre.ethers.provider; this._bridgeB = new hre.ethers.Contract( this.config.bridge.networkBBridgeAddress, IBridge__factory.createInterface(), - hre.ethers.provider - ) as IBridge; + this._providerB + ).connect(this._providerB) as IBridge; const factoryB = await hre.ethers.getContractFactory("BIP20DelegatedTransfer"); - this._tokenB = factoryB.attach(this.config.bridge.networkBTokenAddress); + this._tokenB = factoryB.attach(this.config.bridge.networkBTokenAddress).connect(this._providerB); this._tokenIdB = ContractUtils.getTokenId(await this._tokenB.name(), await this._tokenB.symbol()); - console.log("Chain B: ", this.config.bridge.networkBName); - console.log(" : ", this.config.bridge.networkBBridgeAddress); const balanceB1 = new BOACoin(await this._tokenB.provider.getBalance(this.config.bridge.networkBBridgeAddress)); - console.log("BOA : ", balanceB1.toDisplayString(true, 2)); + console.log("Chain B Balance : "); + console.log(" BOA : ", balanceB1.toDisplayString(true, 2)); const balanceB2 = new BOACoin(await this._bridgeB.getTotalLiquidity(this._tokenIdB)); - console.log("Token : ", balanceB2.toDisplayString(true, 2)); + console.log(" Token : ", balanceB2.toDisplayString(true, 2)); + + const info = { + providerA: this._providerA, + providerB: this._providerB, + tokenA: this._tokenA, + tokenB: this._tokenB, + bridgeA: this._bridgeA, + bridgeB: this._bridgeB, + tokenIdA: this._tokenIdA, + tokenIdB: this._tokenIdB, + }; + this._validators = this.config.bridge.validators.map((m) => new Validator(this.config, this.storage, m, info)); } protected async work() { diff --git a/packages/validator/src/scheduler/EventCollector.ts b/packages/validator/src/scheduler/EventCollector.ts index b4d560f..05171be 100644 --- a/packages/validator/src/scheduler/EventCollector.ts +++ b/packages/validator/src/scheduler/EventCollector.ts @@ -16,7 +16,7 @@ export class EventCollector { private readonly contractAddress: string; private readonly startNumber: bigint; private storage: ValidatorStorage; - private provider: Provider | undefined; + private provider: Provider; private interfaceOfBridge: IBridgeInterface | undefined; constructor( @@ -25,7 +25,8 @@ export class EventCollector { network: string, contractAddress: string, startBlockNumber: bigint, - wallet: Wallet + wallet: Wallet, + provider: Provider ) { this.storage = storage; this.type = type; @@ -33,14 +34,10 @@ export class EventCollector { this.contractAddress = contractAddress; this.startNumber = startBlockNumber; this.wallet = wallet; + this.provider = provider; } public async work() { - if (this.provider === undefined) { - await hre.changeNetwork(this.network); - this.provider = hre.ethers.provider; - } - if (this.interfaceOfBridge === undefined) { this.interfaceOfBridge = IBridge__factory.createInterface(); } diff --git a/packages/validator/src/scheduler/Executor.ts b/packages/validator/src/scheduler/Executor.ts index 79f1430..49d0a58 100644 --- a/packages/validator/src/scheduler/Executor.ts +++ b/packages/validator/src/scheduler/Executor.ts @@ -20,8 +20,8 @@ export class Executor { private readonly targetType: ValidatorType; private readonly sourceNetwork: string; private readonly targetNetwork: string; - private readonly targetContractAddress: string; - private targetProvider: Provider | undefined; + private targetProvider: Provider; + private targetBridge: IBridge; constructor( storage: ValidatorStorage, @@ -29,24 +29,21 @@ export class Executor { sourceNetwork: string, targetType: ValidatorType, targetNetwork: string, - targetContractAddress: string, - wallet: Wallet + wallet: Wallet, + targetProvider: Provider, + targetBridge: IBridge ) { this.storage = storage; this.sourceType = sourceType; this.targetType = targetType; this.sourceNetwork = sourceNetwork; this.targetNetwork = targetNetwork; - this.targetContractAddress = targetContractAddress; this.wallet = new Wallet(wallet.privateKey); + this.targetProvider = targetProvider; + this.targetBridge = targetBridge; } public async work() { - if (this.targetProvider === undefined) { - await hre.changeNetwork(this.targetNetwork); - this.targetProvider = hre.ethers.provider; - } - const events = await this.storage.getNotExecutedEvents( this.wallet.address, this.sourceType, @@ -56,16 +53,10 @@ export class Executor { const signer = new NonceManager(new GasPriceManager(this.wallet.connect(this.targetProvider))); - const contract = new hre.ethers.Contract( - this.targetContractAddress, - IBridge__factory.createInterface(), - this.targetProvider - ) as IBridge; - for (const event of events) { - const status = await contract.getWithdrawInfo(event.depositId); + const status = await this.targetBridge.getWithdrawInfo(event.depositId); if (!status.executed) { - const confirmed = await contract.isConfirmedOf(event.depositId, this.wallet.address); + const confirmed = await this.targetBridge.isConfirmedOf(event.depositId, this.wallet.address); if (!confirmed) { if ( event.withdrawStatus < WithdrawStatus.Sent || @@ -76,7 +67,7 @@ export class Executor { logger.info( `[${this.wallet.address}]-[${this.targetNetwork}]: Starting Withdraw [${event.depositId}]` ); - const tx = await contract + const tx = await this.targetBridge .connect(signer) .withdrawFromBridge(event.tokenId, event.depositId, event.account, event.amount); diff --git a/packages/validator/src/scheduler/Validator.ts b/packages/validator/src/scheduler/Validator.ts index 570db3b..4404671 100644 --- a/packages/validator/src/scheduler/Validator.ts +++ b/packages/validator/src/scheduler/Validator.ts @@ -3,8 +3,8 @@ import { ValidatorStorage } from "../storage/ValidatorStorage"; import { EventCollector } from "./EventCollector"; import { Wallet } from "ethers"; +import { IContractInformation, ValidatorType } from "../types"; import { Executor } from "./Executor"; -import { ValidatorType } from "../types"; export class Validator { private config: Config; @@ -16,7 +16,7 @@ export class Validator { private executorA: Executor; private executorB: Executor; - constructor(config: Config, storage: ValidatorStorage, key: string) { + constructor(config: Config, storage: ValidatorStorage, key: string, contractInfo: IContractInformation) { this.config = config; this.storage = storage; this.wallet = new Wallet(key); @@ -27,7 +27,8 @@ export class Validator { config.bridge.networkAName, config.bridge.networkABridgeAddress, 1n, - this.wallet + this.wallet, + contractInfo.providerA ); this.eventCollectorB = new EventCollector( @@ -36,7 +37,8 @@ export class Validator { config.bridge.networkBName, config.bridge.networkBBridgeAddress, 1n, - this.wallet + this.wallet, + contractInfo.providerB ); this.executorA = new Executor( @@ -45,8 +47,9 @@ export class Validator { config.bridge.networkAName, ValidatorType.B, config.bridge.networkBName, - config.bridge.networkBBridgeAddress, - this.wallet + this.wallet, + contractInfo.providerB, + contractInfo.bridgeB ); this.executorB = new Executor( @@ -55,8 +58,9 @@ export class Validator { config.bridge.networkBName, ValidatorType.A, config.bridge.networkAName, - config.bridge.networkABridgeAddress, - this.wallet + this.wallet, + contractInfo.providerA, + contractInfo.bridgeA ); } diff --git a/packages/validator/src/types/index.ts b/packages/validator/src/types/index.ts index 7a7abf0..7afa799 100644 --- a/packages/validator/src/types/index.ts +++ b/packages/validator/src/types/index.ts @@ -1,4 +1,5 @@ -import { BigNumber } from "ethers"; +import { BigNumber, ethers } from "ethers"; +import { BIP20DelegatedTransfer, IBridge } from "../../typechain-types"; export const SignatureZero = "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; @@ -26,3 +27,14 @@ export enum ValidatorType { A, B, } + +export interface IContractInformation { + providerA: ethers.providers.Provider; + providerB: ethers.providers.Provider; + tokenA: BIP20DelegatedTransfer; + tokenB: BIP20DelegatedTransfer; + bridgeA: IBridge; + bridgeB: IBridge; + tokenIdA: string; + tokenIdB: string; +} diff --git a/packages/validator/test/01-Collector.test.ts b/packages/validator/test/01-Collector.test.ts index e955089..3a8d132 100644 --- a/packages/validator/test/01-Collector.test.ts +++ b/packages/validator/test/01-Collector.test.ts @@ -81,7 +81,8 @@ describe("Test for EventCollector", () => { config.bridge.networkAName, bridgeContract.address, 1n, - validatorWallet + validatorWallet, + hre.ethers.provider ); });