diff --git a/README.md b/README.md index 555f70e..97aa40d 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ git checkout https://github.com/flare-foundation/reward-scripts.git If a configuration file doesn't exist or some parameters are missing, (those) parameters will have default values from [configuration service](./src/services/ConfigurationService.ts). If a default value is `undefined` it will be read from the blockchain. +For the fastest execution `RPC` with unlimited number of requests should be used and parameter `MAX_REQUESTS_PER_SECOND` should be set to `Infinity`. + - Install packages ```bash yarn diff --git a/ftso-address.csv b/ftso-address.csv index 64c711d..faecda7 100644 --- a/ftso-address.csv +++ b/ftso-address.csv @@ -62,11 +62,11 @@ DeFiOracles,0x3fE77e9be1ECcDe815311f9bcc40814F4eC6AE09,NodeID-9WF8MvjNhmR45AdNjV FlarePortal,0x9225db8B30A59D8Dd15448E2E5918BD160262b5D,NodeID-Nwi6MgscyMFQciLyabSFWpWHBQATBVGfk FlareIS,0xf8B1Dcf2594AfD082aae088661bF574CB9BbDC61,NodeID-66rV9yEWSVGLC8fs9ynKptVf9f6bSbHC8 Luganodes,0xB53F6CFaB63CAbFc255c702ebeB273510DB541d7,NodeID-MWNqxgXd8itY143jaNyq8aMYTeV1RXJgS -SenseiNode ,0xe08898B7B8b18dBCdDcC6339c8b9c19EFfA81413,NodeID-xi5DWBUKqBJUWvHiDEr9hpVNLGbxRtu2 -Restake ,0xbF55a6eb78487F49197806025CA82DdaF633204e,NodeID-JZuVSDnBui1u82RmkbkWKJ1JxfdxuVYR9 -Kiln ,0x6df84895f1f1f6F6767C59324F94089d4097051A,NodeID-FHPDnySFVqde5bGvEXsFnvZGhXwcyRfNY +SenseiNode,0xe08898B7B8b18dBCdDcC6339c8b9c19EFfA81413,NodeID-xi5DWBUKqBJUWvHiDEr9hpVNLGbxRtu2 +Restake,0xbF55a6eb78487F49197806025CA82DdaF633204e,NodeID-JZuVSDnBui1u82RmkbkWKJ1JxfdxuVYR9 +Kiln,0x6df84895f1f1f6F6767C59324F94089d4097051A,NodeID-FHPDnySFVqde5bGvEXsFnvZGhXwcyRfNY INFStones,0xB1Aa0F2691Db6bBb2969EfC7BE70787F58DD2461,NodeID-s16BotZkrwu9pfqjmD8vUAsjYtk83dDv -Figment ,0x08233630C4C9e2c1f865B5519e70047EaBAeFAe2,NodeID-Q9KeAQKSyxtJj8mfum951Q5akkoFBJLTs +Figment,0x08233630C4C9e2c1f865B5519e70047EaBAeFAe2,NodeID-Q9KeAQKSyxtJj8mfum951Q5akkoFBJLTs FTSOExpress,0xc0452CEcee694Ab416d19E95a0907f022DEC5664,NodeID-CeX1NfNPHCdaJXUVtkLysShaZCtsHRK3D IntoTheBlock,0x2e8320B92B640cF8CBdEaFFBe70d4bC407303b9F,NodeID-8qSyua2WVQ4uNRc1wwPKmSUWY421bifiq Gateway.fm,0xf26Be97eB0d7a9fBf8d67f813D3Be411445885ce,NodeID-LxpVHRQAYXPRf7q5oz1iT4N1z9XHz5rHU diff --git a/src/services/CalculatingRewardsService.ts b/src/services/CalculatingRewardsService.ts index 1a355ec..b819101 100644 --- a/src/services/CalculatingRewardsService.ts +++ b/src/services/CalculatingRewardsService.ts @@ -107,14 +107,14 @@ export class CalculatingRewardsService { //// for each node check if it is eligible for rewarding, get its delegations, decide to which entity it belongs and calculate boost, total stake amount, ... for (const activeNode of activeNodes) { - let [eligible, ftsoAddress] = await this.isEligibleForReward(activeNode, eligibleNodesUptime, ftsoAddresses, ftsoRewardManager, epoch, ftsoPerformanceForRewardWei); + let [eligible, ftsoAddress] = await this.isEligibleForReward(activeNode, eligibleNodesUptime, ftsoAddresses, ftsoRewardManager, epoch, ftsoPerformanceForRewardWei, rps); // decide to which group node belongs let node = await this.nodeGroup(activeNode, ftsoAddress, boostingAddresses, pChainAddresses); node.eligible = eligible; if (node.group === 1) { - let [selfDelegations, normalDelegations, delegators] = await this.nodeGroup1Data(delegations, node, boostingAddresses, addressBinder); + let [selfDelegations, normalDelegations, delegators] = await this.nodeGroup1Data(delegations, node, boostingAddresses, addressBinder, rps); let virtualBoost = BigInt(boostingFactor) * selfDelegations > BigInt(10e6) * GWEI ? BigInt(boostingFactor) * selfDelegations - BigInt(10e6) * GWEI : BigInt(0); node.boostDelegations = virtualBoost < BigInt(5e6) * GWEI ? virtualBoost : BigInt(5e6) * GWEI; node.boost = node.selfBond + node.boostDelegations; @@ -125,7 +125,7 @@ export class CalculatingRewardsService { node.delegators = delegators; node.totalStakeAmount = selfDelegations + node.boost + normalDelegations; } else if (node.group === 2) { - let [selfDelegation, normalDelegations, boost, delegators] = await this.nodeGroup2Data(delegations, boostingAddresses, node, addressBinder); + let [selfDelegation, normalDelegations, boost, delegators] = await this.nodeGroup2Data(delegations, boostingAddresses, node, addressBinder, rps); node.BEB = node.selfBond; node.boostDelegations = boost; node.boost = boost; @@ -334,7 +334,7 @@ export class CalculatingRewardsService { } // check if node is eligible (high enough ftso performance and uptime) for rewards - public async isEligibleForReward(node: NodeData, eligibleNodesUptime: string[], ftsoAddresses: FtsoData[], ftsoRewardManager: FtsoRewardManager, epochNum: number, ftsoPerformanceForReward: string): Promise<[boolean, string]> { + public async isEligibleForReward(node: NodeData, eligibleNodesUptime: string[], ftsoAddresses: FtsoData[], ftsoRewardManager: FtsoRewardManager, epochNum: number, ftsoPerformanceForReward: string, rps: number): Promise<[boolean, string]> { // find node's entity/ftso address let ftsoObj = ftsoAddresses.find(obj => { return obj.nodeId == node.nodeID; @@ -349,6 +349,7 @@ export class CalculatingRewardsService { } // ftso rewards + await sleepms(1000 / rps); let ftsoPerformance = await ftsoRewardManager.methods.getDataProviderPerformanceInfo(epochNum.toString(), ftsoObj.ftsoAddress).call(); return [BigInt(ftsoPerformance[0]) > BigInt(ftsoPerformanceForReward), ftsoObj.ftsoAddress]; } @@ -456,7 +457,7 @@ export class CalculatingRewardsService { return activeNodes; } - public async nodeGroup1Data(delegations: DelegationData[], node: ActiveNode, boostingAddresses: string[], addressBinder: AddressBinder): Promise<[bigint, bigint, DelegatorData[]]> { + public async nodeGroup1Data(delegations: DelegationData[], node: ActiveNode, boostingAddresses: string[], addressBinder: AddressBinder, rps: number): Promise<[bigint, bigint, DelegatorData[]]> { let selfDelegations = BigInt(0); let regularDelegations = BigInt(0); let delegators = [] as DelegatorData[]; @@ -480,6 +481,7 @@ export class CalculatingRewardsService { delegators[i].amount += delegation.weight; } else { let cAddr = await addressBinder.methods.pAddressToCAddress(pAddressToBytes20(delegation.inputAddresses[0])).call(); + await sleepms(1000 / rps); if (cAddr === ZERO_ADDRESS) { this.logger.error(`Delegation address ${delegation.inputAddresses[0]} is not binded`); } @@ -494,7 +496,7 @@ export class CalculatingRewardsService { return [selfDelegations, regularDelegations, delegators]; } - public async nodeGroup2Data(delegations: DelegationData[], boostingAddresses: string[], node: ActiveNode, addressBinder: AddressBinder): Promise<[bigint, bigint, bigint, DelegatorData[]]> { + public async nodeGroup2Data(delegations: DelegationData[], boostingAddresses: string[], node: ActiveNode, addressBinder: AddressBinder, rps: number): Promise<[bigint, bigint, bigint, DelegatorData[]]> { let selfDelegations = BigInt(0); let regularDelegations = BigInt(0); let boost = BigInt(0); @@ -519,6 +521,7 @@ export class CalculatingRewardsService { delegators[i].amount += delegation.weight; } else { let cAddr = await addressBinder.methods.pAddressToCAddress(pAddressToBytes20(delegation.inputAddresses[0])).call(); + await sleepms(1000 / rps); if (cAddr === ZERO_ADDRESS) { this.logger.error(`Delegation address ${delegation.inputAddresses[0]} is not binded`); }