Skip to content

Commit

Permalink
chore: replaced eth-address with evm-address in code (#3293)
Browse files Browse the repository at this point in the history
Signed-off-by: Simeon Nakov <[email protected]>
  • Loading branch information
simzzz authored Nov 22, 2024
1 parent bde69e3 commit e46298e
Show file tree
Hide file tree
Showing 24 changed files with 597 additions and 584 deletions.
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 @@ export class HbarSpendingPlanConfigService {
* @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 @@ export class HbarSpendingPlanConfigService {
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()}`),
...ipAddresses.map((ipAddress) => `${ipAddressHbarSpendingPlanKey}:${ipAddress}`),
];
}),
Expand Down Expand Up @@ -201,7 +202,7 @@ export class HbarSpendingPlanConfigService {
`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(
id,
'populatePreconfiguredSpendingPlans',
requestDetails,
Expand Down Expand Up @@ -257,51 +258,51 @@ export class HbarSpendingPlanConfigService {
`Updating associations for HBAR spending plan '${planConfig.name}' with ID ${planConfig.id}...`,
);
}
await this.deleteObsoleteEthAddressAssociations(planConfig, requestDetails);
await this.deleteObsoleteEvmAddressAssociations(planConfig, requestDetails);
await this.deleteObsoleteIpAddressAssociations(planConfig, requestDetails);
await this.updateEthAddressAssociations(planConfig, requestDetails);
await this.updateEvmAddressAssociations(planConfig, requestDetails);
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
.findAllByPlanId(planConfig.id, 'populatePreconfiguredSpendingPlans', requestDetails)
.then((ethAddressPlans) => ethAddressPlans.map((plan) => plan.ethAddress));
.then((evmAddressPlans) => evmAddressPlans.map((plan) => plan.evmAddress));

const addressesToDelete = currentEthAddresses.filter(
(ethAddress) => !planConfig.ethAddresses?.includes(ethAddress),
const addressesToDelete = currentEvmAddresses.filter(
(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);
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(
{ 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}`);
}),
);
}
Expand Down Expand Up @@ -344,28 +345,28 @@ export class HbarSpendingPlanConfigService {
}

/**
* 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);
if (exists) {
const ethAddressPlan = await this.ethAddressHbarSpendingPlanRepository.findByAddress(
ethAddress,
const evmAddressPlan = await this.evmAddressHbarSpendingPlanRepository.findByAddress(
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);
}
}
}
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

0 comments on commit e46298e

Please sign in to comment.