Skip to content

Commit

Permalink
feat: add detection-only mode to analyze ERC contracts without regist…
Browse files Browse the repository at this point in the history
…ry updates (#1134)

* chore: added ENABLE_DETECTION_ONLY to doc

Signed-off-by: Logan Nguyen <[email protected]>

* feat: enable detectionOnly for erc registry tool

Signed-off-by: Logan Nguyen <[email protected]>

---------

Signed-off-by: Logan Nguyen <[email protected]>
  • Loading branch information
quiet-node authored Jan 7, 2025
1 parent 69dfbd7 commit 8a3f178
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 17 deletions.
1 change: 1 addition & 0 deletions tools/erc-repository-indexer/docs/registry_design.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ The **ERC Contract Indexer** will:
- `HEDERA_NETWORK`: Network environment (e.g., testnet, mainnet).
- `MIRROR_NODE_URL`: API URL for the Hedera mirror node.
- `STARTING_POINT`: Starting contract ID or contract EVM address (or a `next` pointer from a previous run).
- `ENABLE_DETECTION_ONLY`: A configuration flag that enables the detection of ERC contracts while bypassing registry updates, designed for analysis-only scenarios.

### Class Diagram

Expand Down
13 changes: 7 additions & 6 deletions tools/erc-repository-indexer/erc-contract-indexer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ The ERC Contract Indexer is a tool designed to facilitate the indexing and manag

3. Create a `.env` file in the root directory and configure your environment variables:

| Variable | Description | Accepted Values |
| ---------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HEDERA_NETWORK` | The network to connect to. | `local-node`, `previewnet`, `testnet`, or `mainnet` |
| `MIRROR_NODE_URL` | The URL for the Hedera mirror node API. | A valid URL pointing to the Hedera mirror node (e.g., `https://{previewnet\|testnet\|mainnet}.mirrornode.hedera.com`) |
| `MIRROR_NODE_URL_WEB3` | The URL for the Hedera Mirror Node Web3Module API, required only when `HEDERA_NETWORK` is set to `local-node`. | Any value |
| `STARTING_POINT` | The starting point for contract indexing. | A Hedera contract ID (e.g., `0.0.369`), an EVM 20-byte address (e.g., `0x0000000000000000000000000000000000000369`), or a get contract list next pointer (e.g., `/api/v1/contracts?limit=100&order=asc&contract.id=gt:0.0.369`) |
| Variable | Description | Accepted Values |
| ----------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HEDERA_NETWORK` | The network to connect to. | `local-node`, `previewnet`, `testnet`, or `mainnet` |
| `MIRROR_NODE_URL` | The URL for the Hedera mirror node API. | A valid URL pointing to the Hedera mirror node (e.g., `https://{previewnet\|testnet\|mainnet}.mirrornode.hedera.com`) |
| `MIRROR_NODE_URL_WEB3` | The URL for the Hedera Mirror Node Web3Module API, required only when `HEDERA_NETWORK` is set to `local-node`. | Any value |
| `STARTING_POINT` | The starting point for contract indexing. | A Hedera contract ID (e.g., `0.0.369`), an EVM 20-byte address (e.g., `0x0000000000000000000000000000000000000369`), or a get contract list next pointer (e.g., `/api/v1/contracts?limit=100&order=asc&contract.id=gt:0.0.369`) |
| `ENABLE_DETECTION_ONLY` | Enable detection of ERC contracts without updating the registry. | Any |

Example configuration:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
HEDERA_NETWORK=
MIRROR_NODE_URL=
ENABLE_DETECTION_ONLY=
MIRROR_NODE_URL_WEB3= # only necessary for local-node
SDK_OPERATOR_ID= # only necessary for acceptance test
SDK_OPERATOR_KEY= # only necessary for acceptance test
22 changes: 14 additions & 8 deletions tools/erc-repository-indexer/erc-contract-indexer/src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export const ercRegistryRunner = async () => {
next,
contractScannerService,
byteCodeAnalyzer,
registryGenerator
registryGenerator,
configService
);
} catch (error) {
console.error('Error during the indexing process:', error);
Expand All @@ -52,7 +53,8 @@ const processContracts = async (
next: string | null,
contractScannerService: ContractScannerService,
byteCodeAnalyzer: ByteCodeAnalyzer,
registryGenerator: RegistryGenerator
registryGenerator: RegistryGenerator,
configService: ConfigService
) => {
do {
const fetchContractsResponse =
Expand All @@ -70,11 +72,15 @@ const processContracts = async (
fetchContractsResponse.contracts
);

// let the registry update process to run asynchronously in the background
registryGenerator.generateErcRegistry(
ercContracts.erc20Contracts,
ercContracts.erc721Contracts
);
registryGenerator.updateNextPointer(next);
// only update registry if detectionOnly is off
if (!configService.getDetectionOnly()) {
// let the registry update process to run asynchronously in the background
registryGenerator.generateErcRegistry(
ercContracts.erc20Contracts,
ercContracts.erc721Contracts
);

registryGenerator.updateNextPointer(next);
}
} while (next);
};
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,24 @@ export class ConfigService {
*/
private readonly startingPoint: string;

/**
* @private
* @readonly
* @property {boolean} detectionOnly - A flag indicating whether detection-only mode is enabled.
* If `true`, only contract detection occurs; if `false`, registry updates are also performed.
*/
private readonly detectionOnly: boolean;

constructor() {
this.network = process.env.HEDERA_NETWORK || '';
this.mirrorNodeUrl = process.env.MIRROR_NODE_URL || '';
this.mirrorNodeUrlWeb3 = process.env.MIRROR_NODE_URL_WEB3 || '';
this.startingPoint = process.env.STARTING_POINT || '';
this.detectionOnly = process.env.ENABLE_DETECTION_ONLY === 'true';
this.validateConfigs();

console.log(
`Indexing process initiated: network=${this.network}, mirrorNodeUrl=${this.mirrorNodeUrl}, mirrorNodeUrlWeb3=${this.mirrorNodeUrlWeb3}`
`Indexing process initiated: network=${this.network}, mirrorNodeUrl=${this.mirrorNodeUrl}, mirrorNodeUrlWeb3=${this.mirrorNodeUrlWeb3}, detectionOnly=${this.detectionOnly}`
);
}

Expand Down Expand Up @@ -190,4 +199,12 @@ export class ConfigService {
getMirrorNodeUrlWeb3(): string {
return this.mirrorNodeUrlWeb3;
}

/**
* Gets the current status of the detection-only mode.
* @returns {boolean} `true` if detection-only mode is enabled, `false` otherwise.
*/
getDetectionOnly(): boolean {
return this.detectionOnly;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('ERC Registry Acceptance Test', () => {
};
let sdkClient: NodeClient | null = null;

beforeAll(async () => {
beforeEach(async () => {
const contractDeploymentRequirements =
testHelper.prepareContractDeployRequirements(
totalExpectedDeploymentsForEachContractType
Expand Down Expand Up @@ -77,7 +77,7 @@ describe('ERC Registry Acceptance Test', () => {
process.env.STARTING_POINT = allDeployedAddresses[0];
});

afterAll(() => {
afterEach(() => {
// Close or clean up any resources after all test
if (sdkClient) {
sdkClient.close(); // Or any appropriate cleanup method
Expand Down Expand Up @@ -144,4 +144,35 @@ describe('ERC Registry Acceptance Test', () => {
}
});
});

it('should not update registry when ENABLE_DETECTION_ONLY is set to true', async () => {
// Enable detection-only mode
process.env.ENABLE_DETECTION_ONLY = 'true';

// Backup current registry
const currentErc20Registry = JSON.parse(
testHelper.readContentsFromFile(erc20JsonFilePath) || '[]'
);
const currentErc721Registry = JSON.parse(
testHelper.readContentsFromFile(erc721JsonFilePath) || '[]'
);

// Run the tool to index the network and potentially update the registry
await ercRegistryRunner();

// Wait for asynchronous tasks to complete
await new Promise((resolve) => setTimeout(resolve, 500));

// Read updated registry
const updatedErc20Registry = JSON.parse(
testHelper.readContentsFromFile(erc20JsonFilePath) || '[]'
);
const updatedErc721Registry = JSON.parse(
testHelper.readContentsFromFile(erc721JsonFilePath) || '[]'
);

// Verify that the registry was not updated
expect(updatedErc20Registry).toEqual(currentErc20Registry);
expect(updatedErc721Registry).toEqual(currentErc721Registry);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,30 @@ describe('ConfigService', () => {
expect(startingPoint).toBe(mockStartingPoint);
expect(mockRetrieveNextPointer).toHaveBeenCalled();
});
it('should return default value for detectionOnly, false, if ENABLE_DETECTION_ONLY is not set', () => {
process.env.HEDERA_NETWORK = mockValidHederaNetwork;
process.env.MIRROR_NODE_URL = mockValidMirrorNodeUrl;
delete process.env.ENABLE_DETECTION_ONLY;

const configService = new ConfigService();
expect(configService.getDetectionOnly()).toEqual(false);
});

it('should return preconfigured value for detectionOnly if ENABLE_DETECTION_ONLY is provided', () => {
process.env.HEDERA_NETWORK = mockValidHederaNetwork;
process.env.MIRROR_NODE_URL = mockValidMirrorNodeUrl;
process.env.ENABLE_DETECTION_ONLY = 'true';

const configService = new ConfigService();
expect(configService.getDetectionOnly()).toEqual(true);
});

it('should return false for detectionOnly when ENABLE_DETECTION_ONLY is not explicitly set to true', () => {
process.env.HEDERA_NETWORK = mockValidHederaNetwork;
process.env.MIRROR_NODE_URL = mockValidMirrorNodeUrl;
process.env.ENABLE_DETECTION_ONLY = 'not a boolean value';

const configService = new ConfigService();
expect(configService.getDetectionOnly()).toEqual(false);
});
});

0 comments on commit 8a3f178

Please sign in to comment.