-
Notifications
You must be signed in to change notification settings - Fork 74
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
feat: Add OPERATOR
tier
#3316
base: main
Are you sure you want to change the base?
feat: Add OPERATOR
tier
#3316
Conversation
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Test Results 20 files - 1 268 suites - 47 46m 4s ⏱️ -29s For more details on these failures, see this check. Results for commit f71eaf6. ± Comparison against base commit c006489. This pull request removes 1 and adds 4 tests. Note that renamed tests count towards both.
♻️ This comment has been updated with latest results. |
…ient Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
…nse` Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
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.
lgtm! but please fix the failing tests in CI
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Signed-off-by: Victor Yanev <[email protected]>
Quality Gate failedFailed conditions |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3316 +/- ##
==========================================
+ Coverage 84.79% 85.00% +0.21%
==========================================
Files 69 69
Lines 4637 4682 +45
Branches 1041 1048 +7
==========================================
+ Hits 3932 3980 +48
+ Misses 398 392 -6
- Partials 307 310 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
|
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.
Nice work.
Some suggestions and questions
duration, | ||
); | ||
|
||
const hapiService = new HAPIService(logger, register, this.cacheService, this.eventEmitter, hbarLimitService); | ||
|
||
this.clientMain = hapiService.getMainClientInstance(); | ||
if (this.clientMain.operatorAccountId) { | ||
hbarLimitService.setOperatorAddress(this.clientMain.operatorAccountId.toSolidityAddress()); |
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.
Q: why is this needed when it's set in the hbarLimitService
constructor?
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.
It's complicated 😄, currently the configuration code in the acceptance tests is quite "spaghetti", I opened a draft PR which attempts to fix it - #3331
@@ -283,43 +283,31 @@ export class GlobalConfig { | |||
envName: 'HBAR_RATE_LIMIT_BASIC', | |||
type: 'number', | |||
required: false, | |||
defaultValue: null, | |||
defaultValue: 1_120_000_000, // 11.2 hbar |
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.
nit: note the assumed duration for context
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.
@@ -111,7 +111,6 @@ Unless you need to set a non-default value, it is recommended to only populate o | |||
| `REDIS_RECONNECT_DELAY_MS` | "1000" | Sets the delay between reconnect retries from the Redis client in ms | | |||
| `SEND_RAW_TRANSACTION_SIZE_LIMIT` | "131072" | Sets the limit of the transaction size the relay accepts on eth_sendRawTransaction | | |||
| `GET_RECORD_DEFAULT_TO_CONSENSUS_NODE` | "false" | Flag to set if get transaction record logic should first query the mirror node (false) or consensus node via the SDK (true). | | |||
| `HBAR_RATE_LIMIT_WHITELIST` | [""] | An array of EVM addresses that are allowed to bypass the HBAR rate limits | |
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.
Q: Was this ever used?
If so what version was this added in?
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.
This is from the old hbar limiter and it's no longer used anywhere, so I removed it
/** | ||
* Relay Operators | ||
*/ | ||
OPERATOR = 'OPERATOR', |
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.
I think this requires an update to the design doc.
Did this already happen or will it be done in follow up?
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.
Good point, I will update the design doc to reflect this
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.
I suggest that we do it in a separate PR to not clutter this one even more with changes
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.
Good work some questions!
const operatorId = ConfigService.get('OPERATOR_ID_MAIN'); | ||
const operatorKey = ConfigService.get('OPERATOR_KEY_MAIN'); | ||
if (operatorId) { | ||
this.operatorAddress = AccountId.fromString(operatorId as string).toSolidityAddress(); |
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.
I just wanted to confirm that toSolidityAddress()
will return only the 20-byte address without the prefix 0x
, correct? If that's the case should we add the 0x
prefix for consistency?
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.
Sure, we can do that
* @private | ||
*/ | ||
private reset: Date; | ||
private operatorAddress?: string; |
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.
Since OPERATOR_ID or OPERATOR_KEY are mandatory config, should we make this as a mandatory variable as well?
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, we can but we would need to duplicate the really screwed up logic in hapiService.ts:
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.
I opened another draft PR which fixes the spaghetti code in order to make it really work by only using the ConfigService
this.logger.trace(`${requestDetails.formattedRequestId} Creating operator spending plan...`); | ||
operatorPlan = await this.createSpendingPlanForAddress( | ||
this.operatorAddress!, | ||
requestDetails, | ||
SubscriptionTier.OPERATOR, |
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.
I understand that this aligns with other plans; however, since OPERATOR is a special plan and should have only one account plus should not be updated, was wondering why don't we create operatorPlan
directly in the constructor to make it more official?
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.
We would still need this logic, so that the operator plan is recreated in case the cache expires (after the limit duration).
Otherwise, if we don't have this on-demand creation, we will need custom logic to create it in intervals of time which could create race conditions and the operator plan might not yet be created for incoming requests.
} else if (operatorKey) { | ||
this.operatorAddress = Utils.createPrivateKeyBasedOnFormat(operatorKey as string).publicKey.toEvmAddress(); | ||
} |
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.
hmm since the OPERATOR_ID is a mandatory config, I think this will never be reached.
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.
Yeah, that's true but in some cases the OPERATOR_ID
is set to an empty string (e.g., in the charts:install
workflow)
for (const plan of operatorPlans) { | ||
await hbarSpendingPlanRepository.addToAmountSpent(plan.id, plan.amountSpent, requestDetails, mockTTL); | ||
} | ||
|
||
// Note: Since the total HBAR budget is shared across the entire Relay instance by multiple test cases, | ||
// and expense updates occur asynchronously, the wait below ensures that the HBAR amount has sufficient time | ||
// to update properly after each test. |
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.
Hmm should we need a new acceptance test to see how new OPERATOR plan work in e2e flow?
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.
Not really, the total limit tests already cover this
for (const plan of operatorPlans) { | ||
await hbarSpendingPlanRepository.addToAmountSpent(plan.id, plan.amountSpent, requestDetails, mockTTL); | ||
} | ||
|
||
// Note: Since the total HBAR budget is shared across the entire Relay instance by multiple test cases, | ||
// and expense updates occur asynchronously, the wait below ensures that the HBAR amount has sufficient time | ||
// to update properly after each test. |
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.
Hmm should we need a new acceptance test to see how new OPERATOR plan work in e2e flow?
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.
The operator plan essentially replaces the in-memory tracking of the total limit that we used to do before
Description:
Instead of tracking the remaining total budget in-memory inside
HbarLimitService
(we would have to divide it by the number of Kubernetes instances, etc - it is creating unnecessary complexity in the configurations), we could create a new subscription tier (SubscriptionTier.OPERATOR
) and add a pre-configured spending plan in the JSON configuration file which links the EVM address(es) of the relay operator account(s) to it.In this way we can only set the total limit for the
OPERATOR
tier toHBAR_RATE_LIMIT_TINYBAR
and it will be shared by all instances of the relay.Related issue(s):
Fixes #3099
Notes for reviewer:
Checklist