-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OG-658 Fixing selection default mechanism #718
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,22 +16,34 @@ import { | |
} from '@opengsn/common/dist/types/GSNContractsDataTypes' | ||
import { LoggerInterface } from '@opengsn/common/dist/LoggerInterface' | ||
import { ContractInteractor } from '@opengsn/common/dist/ContractInteractor' | ||
|
||
export const EmptyFilter: RelayFilter = (): boolean => { | ||
import { MAX_INTEGER } from 'ethereumjs-util' | ||
import { toBN } from 'web3-utils' | ||
import BN from 'bn.js' | ||
|
||
export const DefaultRelayFilter: RelayFilter = function (registeredEventInfo: RelayRegisteredEventInfo): boolean { | ||
const maxPctRelayFee = 100 | ||
const maxBaseRelayFee = 1e17 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if ( | ||
parseInt(registeredEventInfo.pctRelayFee) > maxPctRelayFee || | ||
parseInt(registeredEventInfo.baseRelayFee) > maxBaseRelayFee | ||
) { | ||
return false | ||
} | ||
return true | ||
} | ||
/** | ||
* Basic score is reversed transaction fee, higher is better. | ||
* Relays that failed to respond recently will be downgraded for some period of time. | ||
*/ | ||
export const DefaultRelayScore = async function (relay: RelayRegisteredEventInfo, txDetails: GsnTransactionDetails, failures: RelayFailureInfo[]): Promise<number> { | ||
const gasLimit = parseInt(txDetails.gas ?? '0') | ||
const gasPrice = parseInt(txDetails.gasPrice ?? '0') | ||
const pctFee = parseInt(relay.pctRelayFee) | ||
const baseFee = parseInt(relay.baseRelayFee) | ||
const transactionCost = baseFee + (gasLimit * gasPrice * (100 + pctFee)) / 100 | ||
let score = Math.max(Number.MAX_SAFE_INTEGER - transactionCost, 0) | ||
score = score * Math.pow(0.9, failures.length) | ||
export const DefaultRelayScore: AsyncScoreCalculator = async function (relay: RelayRegisteredEventInfo, txDetails: GsnTransactionDetails, failures: RelayFailureInfo[]): Promise<BN> { | ||
const gasLimit = toBN(txDetails.gas ?? '0') | ||
const gasPrice = toBN(txDetails.gasPrice ?? '0') | ||
const pctFee = toBN(relay.pctRelayFee) | ||
const baseFee = toBN(relay.baseRelayFee) | ||
const transactionCost = baseFee.add(gasLimit.mul(gasPrice).muln((100 + pctFee.toNumber()) / 100) | ||
) | ||
let score = MAX_INTEGER.sub(transactionCost) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we want to make it the max possible number? we do want to have a number higher than max possible gas so 100eth gas price * arbitrum gas limit yields 1e20 * 1e10 ~ 1e30 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (yes, and I also don't think using BN is good thing - it ties our code to some BigNumber implementation, and if/when we change to ethers, we to change the API (or carry a requirement for another BN library) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand your suggestion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. forget it. what we need is weighted scoring, and this is not something we'll now. |
||
score = score.muln(Math.pow(0.9, failures.length)) | ||
return score | ||
} | ||
|
||
|
@@ -51,7 +63,7 @@ export class KnownRelaysManager { | |
constructor (contractInteractor: ContractInteractor, logger: LoggerInterface, config: GSNConfig, relayFilter?: RelayFilter, scoreCalculator?: AsyncScoreCalculator) { | ||
this.config = config | ||
this.logger = logger | ||
this.relayFilter = relayFilter ?? EmptyFilter | ||
this.relayFilter = relayFilter ?? DefaultRelayFilter | ||
this.scoreCalculator = scoreCalculator ?? DefaultRelayScore | ||
this.contractInteractor = contractInteractor | ||
} | ||
|
@@ -173,9 +185,9 @@ export class KnownRelaysManager { | |
} | ||
|
||
async _sortRelaysInternal (gsnTransactionDetails: GsnTransactionDetails, activeRelays: RelayInfoUrl[]): Promise<RelayInfoUrl[]> { | ||
const scores = new Map<string, number>() | ||
const scores = new Map<string, BN>() | ||
for (const activeRelay of activeRelays) { | ||
let score = 0 | ||
let score = toBN(0) | ||
if (isInfoFromEvent(activeRelay)) { | ||
const eventInfo = activeRelay as RelayRegisteredEventInfo | ||
score = await this.scoreCalculator(eventInfo, gsnTransactionDetails, this.relayFailures.get(activeRelay.relayUrl) ?? []) | ||
|
@@ -187,9 +199,9 @@ export class KnownRelaysManager { | |
.filter(isInfoFromEvent) | ||
.map(value => (value as RelayRegisteredEventInfo)) | ||
.sort((a, b) => { | ||
const aScore = scores.get(a.relayManager) ?? 0 | ||
const bScore = scores.get(b.relayManager) ?? 0 | ||
return bScore - aScore | ||
const aScore = scores.get(a.relayManager) ?? toBN(0) | ||
const bScore = scores.get(b.relayManager) ?? toBN(0) | ||
return bScore.cmp(aScore) | ||
}) | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you check toString that its not constant for all functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is the function code as string.