Skip to content
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

chore: replaced eth-address with evm-address in code #3293

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions docs/design/hbar-limiter.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ flowchart TD

### Supported Projects (EXTENDED tier) and Trusted Partners (PRIVILEGED tier):

**NOTE:** There will be one spending plan per project/partner with a total spending limit, shared amongst a group of users (IP and ETH addresses) linked to that plan. This means that they will share a common total spending limit for the project/partner.
**NOTE:** There will be one spending plan per project/partner with a total spending limit, shared amongst a group of users (IP and EVM addresses) linked to that plan. This means that they will share a common total spending limit for the project/partner.

All users associated with a project/partner will be pre-configured in the relay as shown in the

Expand Down Expand Up @@ -159,13 +159,13 @@ classDiagram

class HBarLimitService {
-hbarSpendingPlanRepository: HbarSpendingPlanRepository
-ethAddressHbarSpendingPlanRepository: EthAddressHbarSpendingPlanRepository
-evmAddressHbarSpendingPlanRepository: EvmAddressHbarSpendingPlanRepository
-ipAddressHbarSpendingPlanRepository: IpAddressHbarSpendingPlanRepository
+shouldLimit(txFrom: string, ip?: string) boolean
+shouldPreemtivelyLimitFileTransactions(callDataSize: number, fileChunkSize: number, currentNetworkExchangeRateInCents: number) boolean
+resetLimiter() void
+addExpense(amount: number, txFrom: string, ip?: string) void
-getSpendingPlanOfEthAddress(address: string): HbarSpendingPlan
-getSpendingPlanOfEvmAddress(address: string): HbarSpendingPlan
-getSpendingPlanOfIpAddress(ip: string): HbarSpendingPlan
-checkTotalSpent() boolean
-shouldReset() boolean
Expand Down Expand Up @@ -202,8 +202,8 @@ classDiagram
-timestamp: Date
}

class EthAddressHbarSpendingPlan {
-ethAddress: string
class EvmAddressHbarSpendingPlan {
-evmAddress: string
-planId: string
}

Expand Down Expand Up @@ -237,11 +237,11 @@ classDiagram
+addToAmountSpent(id: string, amount: number): Promise<void>
}

class EthAddressHbarSpendingPlanRepository {
class EvmAddressHbarSpendingPlanRepository {
-cache: CacheService
+findByAddress(ethAddress: string): Promise<EthAddressHbarSpendingPlan>
+save(ethAddressPlan: EthAddressHbarSpendingPlan): Promise<void>
+delete(ethAddress: string): Promise<void>
+findByAddress(evmAddress: string): Promise<EvmAddressHbarSpendingPlan>
+save(evmAddressPlan: EvmAddressHbarSpendingPlan): Promise<void>
+delete(evmAddress: string): Promise<void>
}

class IpAddressHbarSpendingPlanRepository {
Expand All @@ -259,11 +259,11 @@ classDiagram

HbarSpendingPlan --> SubscriptionTier : could be one of the types
HbarSpendingPlan --> HbarSpendingRecord : stores history of
EthAddressHbarSpendingPlan --> HbarSpendingPlan : links an ETH address to
EvmAddressHbarSpendingPlan --> HbarSpendingPlan : links an EVM address to
IpAddressHbarSpendingPlan --> HbarSpendingPlan : links an IP address to

HbarSpendingPlanRepository --> CacheService : uses
EthAddressHbarSpendingPlanRepository --> CacheService : uses
EvmAddressHbarSpendingPlanRepository --> CacheService : uses
IpAddressHbarSpendingPlanRepository --> CacheService : uses
```
### Support flexible alerting mechanisms for spending thresholds
Expand Down Expand Up @@ -320,9 +320,9 @@ c. Current day's usage (increase limits if overall usage is low)

### Pre-populating the Cache with Spending Plans for Supported Projects and Partner Projects

The following configurations will be used to automatically populate the cache with `HbarSpendingPlan`, `EthAddressHbarSpendingPlan`, and `IPAddressHbarSpendingPlan` entries for the outlined supported projects and partner projects on every start-up of the relay.
The following configurations will be used to automatically populate the cache with `HbarSpendingPlan`, `EvmAddressHbarSpendingPlan`, and `IPAddressHbarSpendingPlan` entries for the outlined supported projects and partner projects on every start-up of the relay.

All other users (ETH and IP addresses which are not specified in the configuration file) will be treated as "general users" and will be assigned a basic `HbarSpendingPlan` on their first request and their ETH address and IP address will be linked to that plan for all subsequent requests.
All other users (ETH and IP addresses which are not specified in the configuration file) will be treated as "general users" and will be assigned a basic `HbarSpendingPlan` on their first request and their EVM address and IP address will be linked to that plan for all subsequent requests.

### JSON Configuration File

Expand All @@ -337,20 +337,20 @@ The default filename for the configuration file is `spendingPlansConfig.json`, b
{
"id": "c758c095-342c-4607-9db5-867d7e90ab9d",
"name": "partner name",
"ethAddresses": ["0x123", "0x124"],
"evmAddresses": ["0x123", "0x124"],
"ipAddresses": ["127.0.0.1", "128.0.0.1"],
"subscriptionTier": "PRIVILEGED"
},
{
"id": "a68488b0-6f7d-44a0-87c1-774ad64615f2",
"name": "some other partner that has given us only eth addresses",
"ethAddresses": ["0x125", "0x126"],
"name": "some other partner that has given us only evm addresses",
"evmAddresses": ["0x125", "0x126"],
"subscriptionTier": "PRIVILEGED"
},
{
"id": "af13d6ed-d676-4d33-8b9d-cf05d1ad7134",
"name": "supported project name",
"ethAddresses": ["0x127", "0x128"],
"evmAddresses": ["0x127", "0x128"],
"ipAddresses": ["129.0.0.1", "130.0.0.1"],
"subscriptionTier": "EXTENDED"
},
Expand All @@ -366,7 +366,7 @@ The default filename for the configuration file is `spendingPlansConfig.json`, b
#### Important notes
- The `id` field is **strictly required** for each supported project or partner project. It is used as a unique identifier and as key in the cache and also for reference in the logs. We recommend using a UUID for this field, but any unique string will work.
- The `name` field is used just for reference and can be any string. It is not used in the cache or for any other purpose, only for better readability in the logs on start-up of the relay when the spending plans are being configured.
- The `ethAddresses` and `ipAddresses` fields are arrays of strings containing the ETH addresses and IP addresses associated with the supported project or partner project. **At least one** of these two fields must be present and contain **at least one entry**.
- The `evmAddresses` and `ipAddresses` fields are arrays of strings containing the EVM addresses and IP addresses associated with the supported project or partner project. **At least one** of these two fields must be present and contain **at least one entry**.
- The `subscriptionTier` field is also **required**. It is an enum with the following possible values: `BASIC`, `EXTENDED`, and `PRIVILEGED`.

On every start-up, the relay will check if these entries are already populated in the cache. If not, it will populate them accordingly.
Expand All @@ -386,7 +386,7 @@ The JSON file can also be updated over time to add new partners or supported pro
{
"id": "0b054498-5c48-4402-aad4-b9b455f33457",
"name": "new partner name",
"ethAddresses": ["0x129", "0x130"],
"evmAddresses": ["0x129", "0x130"],
"ipAddresses": ["133.0.0.1"],
"subscriptionTier": "PRIVILEGED"
}
Expand All @@ -397,7 +397,7 @@ The JSON file can also be updated over time to add new partners or supported pro

If some of the pre-configured plans are removed them from the JSON file, they will be considered "obsolete" and removed from the cache on the next start-up of the relay.

You can also add new ETH addresses or IP addresses to existing plans by updating the JSON file.
You can also add new EVM addresses or IP addresses to existing plans by updating the JSON file.

```javascript
[
Expand All @@ -406,14 +406,14 @@ You can also add new ETH addresses or IP addresses to existing plans by updating
{
"id": "c758c095-342c-4607-9db5-867d7e90ab9d",
"name": "partner name",
"ethAddresses": ["0x123", "0x124", "<new_eth_address>"],
"evmAddresses": ["0x123", "0x124", "<new_evm_address>"],
"ipAddresses": ["127.0.0.1", "128.0.0.1", "<new_ip_address>", "<another_new_ip_address>"],
"subscriptionTier": "PRIVILEGED",
}
]
```

Or if you remove any existing ETH addresses or IP addresses from the JSON file, only those will be removed from the cache on the next start-up.
Or if you remove any existing EVM addresses or IP addresses from the JSON file, only those will be removed from the cache on the next start-up.

```javascript
[
Expand All @@ -422,7 +422,7 @@ Or if you remove any existing ETH addresses or IP addresses from the JSON file,
{
"id": "c758c095-342c-4607-9db5-867d7e90ab9d",
"name": "partner name",
"ethAddresses": ["0x123"], // removed "0x124"
"evmAddresses": ["0x123"], // removed "0x124"
"ipAddresses": ["127.0.0.1"], // removed "128.0.0.1"
"subscriptionTier": "PRIVILEGED",
}
Expand Down
79 changes: 40 additions & 39 deletions packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@
*
*/

import fs from 'fs';
import { ConfigService } from '@hashgraph/json-rpc-config-service/dist/services';
import findConfig from 'find-config';
import { isValidSpendingPlanConfig, SpendingPlanConfig } from '../types/spendingPlanConfig';
import fs from 'fs';
import { Logger } from 'pino';

import { EvmAddressHbarSpendingPlanRepository } from '../db/repositories/hbarLimiter/evmAddressHbarSpendingPlanRepository';
import { HbarSpendingPlanRepository } from '../db/repositories/hbarLimiter/hbarSpendingPlanRepository';
import { EthAddressHbarSpendingPlanRepository } from '../db/repositories/hbarLimiter/ethAddressHbarSpendingPlanRepository';
import { IPAddressHbarSpendingPlanRepository } from '../db/repositories/hbarLimiter/ipAddressHbarSpendingPlanRepository';
import { RequestDetails } from '../types';
import { Logger } from 'pino';
import { SubscriptionTier } from '../db/types/hbarLimiter/subscriptionTier';
import { IDetailedHbarSpendingPlan } from '../db/types/hbarLimiter/hbarSpendingPlan';
import { ConfigService } from '@hashgraph/json-rpc-config-service/dist/services';
import { SubscriptionTier } from '../db/types/hbarLimiter/subscriptionTier';
import { RequestDetails } from '../types';
import { isValidSpendingPlanConfig, SpendingPlanConfig } from '../types/spendingPlanConfig';

/**
* Service for managing pre-configured {@link HbarSpendingPlan} entities.
Expand All @@ -54,13 +55,13 @@
* @constructor
* @param {Logger} logger - The logger instance.
* @param {HbarSpendingPlanRepository} hbarSpendingPlanRepository - The repository for HBAR spending plans.
* @param {EthAddressHbarSpendingPlanRepository} ethAddressHbarSpendingPlanRepository - The repository for ETH address associations.
* @param {EvmAddressHbarSpendingPlanRepository} evmAddressHbarSpendingPlanRepository - The repository for EVM address associations.
* @param {IPAddressHbarSpendingPlanRepository} ipAddressHbarSpendingPlanRepository - The repository for IP address associations.
*/
constructor(
private readonly logger: Logger,
private readonly hbarSpendingPlanRepository: HbarSpendingPlanRepository,
private readonly ethAddressHbarSpendingPlanRepository: EthAddressHbarSpendingPlanRepository,
private readonly evmAddressHbarSpendingPlanRepository: EvmAddressHbarSpendingPlanRepository,
private readonly ipAddressHbarSpendingPlanRepository: IPAddressHbarSpendingPlanRepository,
) {}

Expand All @@ -73,17 +74,17 @@
public static getPreconfiguredSpendingPlanKeys(logger: Logger): Set<string> {
try {
const { collectionKey: hbarSpendingPlanKey } = HbarSpendingPlanRepository;
const { collectionKey: ethAddressHbarSpendingPlanKey } = EthAddressHbarSpendingPlanRepository;
const { collectionKey: evmAddressHbarSpendingPlanKey } = EvmAddressHbarSpendingPlanRepository;
const { collectionKey: ipAddressHbarSpendingPlanKey } = IPAddressHbarSpendingPlanRepository;

return new Set<string>(
this.loadSpendingPlansConfig(logger).flatMap((plan) => {
const { id, ethAddresses = [], ipAddresses = [] } = plan;
const { id, evmAddresses = [], ipAddresses = [] } = plan;
return [
`${hbarSpendingPlanKey}:${id}`,
`${hbarSpendingPlanKey}:${id}:amountSpent`,
`${hbarSpendingPlanKey}:${id}:spendingHistory`,
...ethAddresses.map((ethAddress) => `${ethAddressHbarSpendingPlanKey}:${ethAddress.trim().toLowerCase()}`),
...evmAddresses.map((evmAddress) => `${evmAddressHbarSpendingPlanKey}:${evmAddress.trim().toLowerCase()}`),

Check warning on line 87 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L87

Added line #L87 was not covered by tests
...ipAddresses.map((ipAddress) => `${ipAddressHbarSpendingPlanKey}:${ipAddress}`),
];
}),
Expand Down Expand Up @@ -201,7 +202,7 @@
`Deleting HBAR spending plan with ID "${id}", as it is no longer in the spending plan configuration...`,
);
await this.hbarSpendingPlanRepository.delete(id, requestDetails);
await this.ethAddressHbarSpendingPlanRepository.deleteAllByPlanId(
await this.evmAddressHbarSpendingPlanRepository.deleteAllByPlanId(

Check warning on line 205 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L205

Added line #L205 was not covered by tests
id,
'populatePreconfiguredSpendingPlans',
requestDetails,
Expand Down Expand Up @@ -257,51 +258,51 @@
`Updating associations for HBAR spending plan '${planConfig.name}' with ID ${planConfig.id}...`,
);
}
await this.deleteObsoleteEthAddressAssociations(planConfig, requestDetails);
await this.deleteObsoleteEvmAddressAssociations(planConfig, requestDetails);

Check warning on line 261 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L261

Added line #L261 was not covered by tests
await this.deleteObsoleteIpAddressAssociations(planConfig, requestDetails);
await this.updateEthAddressAssociations(planConfig, requestDetails);
await this.updateEvmAddressAssociations(planConfig, requestDetails);

Check warning on line 263 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L263

Added line #L263 was not covered by tests
await this.updateIpAddressAssociations(planConfig, requestDetails);
}
}

/**
* Updates the associations of an HBAR spending plan with ETH addresses.
* Updates the associations of an HBAR spending plan with EVM addresses.
*
* @param {SpendingPlanConfig} planConfig - The spending plan configuration.
* @param {RequestDetails} requestDetails - The details of the current request.
* @returns {Promise<void>} - A promise that resolves when the operation is complete.
* @private
*/
private async updateEthAddressAssociations(
private async updateEvmAddressAssociations(
planConfig: SpendingPlanConfig,
requestDetails: RequestDetails,
): Promise<void> {
const currentEthAddresses = await this.ethAddressHbarSpendingPlanRepository
const currentEvmAddresses = await this.evmAddressHbarSpendingPlanRepository

Check warning on line 280 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L280

Added line #L280 was not covered by tests
.findAllByPlanId(planConfig.id, 'populatePreconfiguredSpendingPlans', requestDetails)
.then((ethAddressPlans) => ethAddressPlans.map((plan) => plan.ethAddress));
.then((evmAddressPlans) => evmAddressPlans.map((plan) => plan.evmAddress));

Check warning on line 282 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L282

Added line #L282 was not covered by tests

const addressesToDelete = currentEthAddresses.filter(
(ethAddress) => !planConfig.ethAddresses?.includes(ethAddress),
const addressesToDelete = currentEvmAddresses.filter(

Check warning on line 284 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L284

Added line #L284 was not covered by tests
(evmAddress) => !planConfig.evmAddresses?.includes(evmAddress),
);
await Promise.all(
addressesToDelete.map(async (ethAddress) => {
await this.ethAddressHbarSpendingPlanRepository.delete(ethAddress, requestDetails);
addressesToDelete.map(async (evmAddress) => {
await this.evmAddressHbarSpendingPlanRepository.delete(evmAddress, requestDetails);

Check warning on line 289 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L288-L289

Added lines #L288 - L289 were not covered by tests
this.logger.info(
`Removed association between ETH address ${ethAddress} and HBAR spending plan '${planConfig.name}'`,
`Removed association between EVM address ${evmAddress} and HBAR spending plan '${planConfig.name}'`,
);
}),
);

const addressesToAdd =
planConfig.ethAddresses?.filter((ethAddress) => !currentEthAddresses.includes(ethAddress)) || [];
planConfig.evmAddresses?.filter((evmAddress) => !currentEvmAddresses.includes(evmAddress)) || [];
await Promise.all(
addressesToAdd.map(async (ethAddress) => {
await this.ethAddressHbarSpendingPlanRepository.save(
{ ethAddress, planId: planConfig.id },
addressesToAdd.map(async (evmAddress) => {
await this.evmAddressHbarSpendingPlanRepository.save(

Check warning on line 300 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L299-L300

Added lines #L299 - L300 were not covered by tests
{ evmAddress, planId: planConfig.id },
requestDetails,
this.TTL,
);
this.logger.info(`Associated HBAR spending plan '${planConfig.name}' with ETH address ${ethAddress}`);
this.logger.info(`Associated HBAR spending plan '${planConfig.name}' with EVM address ${evmAddress}`);

Check warning on line 305 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L305

Added line #L305 was not covered by tests
}),
);
}
Expand Down Expand Up @@ -344,28 +345,28 @@
}

/**
* Deletes obsolete ETH address associations from the cache.
* Deletes obsolete EVM address associations from the cache.
*
* For example, if an ETH address is associated with a plan different from the one in the {@link SPENDING_PLANS_CONFIG},
* For example, if an EVM address is associated with a plan different from the one in the {@link SPENDING_PLANS_CONFIG},
* the association is deleted from the cache to allow the new association from the configuration file to take effect.
*
* @param {SpendingPlanConfig} planConfig - The spending plan configuration.
* @param {RequestDetails} requestDetails - The details of the current request.
* @private
*/
private async deleteObsoleteEthAddressAssociations(planConfig: SpendingPlanConfig, requestDetails: RequestDetails) {
for (const ethAddress of planConfig.ethAddresses || []) {
const exists = await this.ethAddressHbarSpendingPlanRepository.existsByAddress(ethAddress, requestDetails);
private async deleteObsoleteEvmAddressAssociations(planConfig: SpendingPlanConfig, requestDetails: RequestDetails) {
for (const evmAddress of planConfig.evmAddresses || []) {
const exists = await this.evmAddressHbarSpendingPlanRepository.existsByAddress(evmAddress, requestDetails);

Check warning on line 359 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L359

Added line #L359 was not covered by tests
if (exists) {
const ethAddressPlan = await this.ethAddressHbarSpendingPlanRepository.findByAddress(
ethAddress,
const evmAddressPlan = await this.evmAddressHbarSpendingPlanRepository.findByAddress(

Check warning on line 361 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L361

Added line #L361 was not covered by tests
evmAddress,
requestDetails,
);
if (ethAddressPlan.planId !== planConfig.id) {
if (evmAddressPlan.planId !== planConfig.id) {
this.logger.info(
`Deleting association between ETH address ${ethAddress} and HBAR spending plan '${planConfig.name}'`,
`Deleting association between EVM address ${evmAddress} and HBAR spending plan '${planConfig.name}'`,
);
await this.ethAddressHbarSpendingPlanRepository.delete(ethAddress, requestDetails);
await this.evmAddressHbarSpendingPlanRepository.delete(evmAddress, requestDetails);

Check warning on line 369 in packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/config/hbarSpendingPlanConfigService.ts#L369

Added line #L369 was not covered by tests
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
*
*/

import { IEthAddressHbarSpendingPlan } from '../../types/hbarLimiter/ethAddressHbarSpendingPlan';
import { IEvmAddressHbarSpendingPlan } from '../../types/hbarLimiter/evmAddressHbarSpendingPlan';

export class EthAddressHbarSpendingPlan implements IEthAddressHbarSpendingPlan {
ethAddress: string;
export class EvmAddressHbarSpendingPlan implements IEvmAddressHbarSpendingPlan {
evmAddress: string;
planId: string;

constructor(data: IEthAddressHbarSpendingPlan) {
this.ethAddress = data.ethAddress;
constructor(data: IEvmAddressHbarSpendingPlan) {
this.evmAddress = data.evmAddress;
this.planId = data.planId;
}
}
Loading
Loading