mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 01:38:32 +00:00
## Implement E2E Testing Framework with Isolated Networks ### Summary Refactors the existing E2E testing infrastructure to provide isolated test environments with parallel execution support. Each test suite now runs in its own network namespace, preventing resource conflicts. ### Key Changes - **New Testing Framework** (`test/framework/`): Base classes for test lifecycle management with automatic setup/teardown - **Launcher Module** (`test/launcher/`): Extracted network orchestration logic from CLI handlers for reusability - **Parallel Execution**: Added `test-parallel.ts` script with concurrency limits to prevent resource exhaustion - **Test Isolation**: Each suite gets unique network IDs (format: `suiteName-timestamp`) and Docker networks - **Improved Test Organization**: Migrated tests to new framework, deprecated old test structure ### Test Improvements - Added 4 new test suites demonstrating framework usage. : - `contracts.test.ts` - Smart contract deployment/interaction - `datahaven-substrate.test.ts` - Substrate API operations - `cross-chain.test.ts` - Snowbridge cross-chain messaging - `ethereum-basic.test.ts` - Ethereum network operations > [!WARNING] The test suites themselves are bad and shouldn't be consider examples of good tests. They were AI generated just to test the concurrency of test runners ### Documentation - Added comprehensive framework overview (`E2E_FRAMEWORK_OVERVIEW.md`) - Updated README with parallel testing commands - Added test patterns and best practices ### Breaking Changes - Old test suites moved to `e2e - DEPRECATED/` directory - Test execution now requires extending `BaseTestSuite` class ### Testing Run tests with: `bun test:e2e` or `bun test:e2e:parallel` (with concurrency limits) ### TODO - [ ] Implement good test examples. - [ ] Implement useful test utils (like waiting for an event to show up in DataHaven or Ethereum). - [ ] Enforce tests with CI (currently cannot be done due to intermittent error when sending a transaction with PAPI). --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: undercover-cactus <lola@moonsonglabs.com>
42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import { secp256k1 } from "@noble/curves/secp256k1";
|
|
import { keccak_256 } from "@noble/hashes/sha3";
|
|
import type { Hex } from "viem";
|
|
|
|
/**
|
|
* Converts a compressed ECDSA public key to an Ethereum address.
|
|
* Used for converting BEEFY authorities public keys to Ethereum addresses.
|
|
*
|
|
* @param compressedPubKey - The compressed public key (33 bytes)
|
|
* @returns The Ethereum address derived from the public key
|
|
*/
|
|
export const compressedPubKeyToEthereumAddress = (compressedPubKey: Hex): Hex => {
|
|
// Remove 0x prefix if present
|
|
const pubKeyBytes = compressedPubKey.startsWith("0x")
|
|
? compressedPubKey.slice(2)
|
|
: compressedPubKey;
|
|
|
|
// Convert hex string to Uint8Array
|
|
const matches = pubKeyBytes.match(/.{1,2}/g);
|
|
if (!matches) {
|
|
throw new Error("Invalid hex string format");
|
|
}
|
|
const compressedBytes = new Uint8Array(matches.map((byte) => Number.parseInt(byte, 16)));
|
|
|
|
// Get the uncompressed point
|
|
const point = secp256k1.ProjectivePoint.fromHex(compressedBytes);
|
|
const uncompressedBytes = point.toRawBytes(false); // false = uncompressed
|
|
|
|
// Remove the first byte (0x04) which indicates uncompressed format
|
|
const publicKeyBytes = uncompressedBytes.slice(1);
|
|
|
|
// Keccak256 hash of the public key
|
|
const hash = keccak_256(publicKeyBytes);
|
|
|
|
// Take the last 20 bytes as the Ethereum address
|
|
const address = hash.slice(-20);
|
|
|
|
// Convert to hex string with 0x prefix
|
|
return `0x${Array.from(address)
|
|
.map((b) => b.toString(16).padStart(2, "0"))
|
|
.join("")}` as Hex;
|
|
};
|