Skip to content

Commit

Permalink
fix(web3): GwConfig is not a constructor (#1019)
Browse files Browse the repository at this point in the history
Fix `EthRegistryAddress` and `GwConfig` circular references

> TypeError: gw_config_1.GwConfig is not a constructor
  • Loading branch information
classicalliu committed Mar 9, 2023
1 parent 001b6fe commit 7e8e0be
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 42 deletions.
39 changes: 3 additions & 36 deletions web3/packages/api-server/src/base/address.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,21 @@
import { Hash, HexString, Script, utils } from "@ckb-lumos/base";
import { GodwokenClient } from "@godwoken-web3/godwoken";
import { Store } from "../cache/store";
import { BaseEthRegistryAddress } from "./base-eth-registry-address";
import { gwConfig } from "./index";
import { logger } from "./logger";
import { Uint32 } from "./types/uint";

// the eth address vs script hash is not changeable, so we set no expire for cache
const scriptHashCache = new Store(false);

// Only support eth address now!
export class EthRegistryAddress {
private registryId: number;
private addressByteSize: number = 20;
public readonly address: HexString;

export class EthRegistryAddress extends BaseEthRegistryAddress {
// Using optional registryId when gwConfig not initialized
constructor(
address: HexString,
{ registryId }: { registryId?: number } = {}
) {
if (!address.startsWith("0x") || address.length !== 42) {
throw new Error(`Eth address format error: ${address}`);
}
this.address = address.toLowerCase();

this.registryId = registryId || +gwConfig.accounts.ethAddrReg.id;
}

public serialize(): HexString {
return (
"0x" +
new Uint32(this.registryId).toLittleEndian().slice(2) +
new Uint32(this.addressByteSize).toLittleEndian().slice(2) +
this.address.slice(2)
);
}

public static Deserialize(hex: HexString): EthRegistryAddress {
const hexWithoutPrefix = hex.slice(2);
const registryId: number = Uint32.fromLittleEndian(
hexWithoutPrefix.slice(0, 8)
).getValue();
const addressByteSize: number = Uint32.fromLittleEndian(
hexWithoutPrefix.slice(8, 16)
).getValue();
const address: HexString = hexWithoutPrefix.slice(16);
if (addressByteSize !== 20 || address.length !== 40) {
throw new Error(`Eth address deserialize error: ${hex}`);
}
return new EthRegistryAddress("0x" + address, { registryId });
super(address, registryId || +gwConfig.accounts.ethAddrReg.id);
}
}

Expand Down
43 changes: 43 additions & 0 deletions web3/packages/api-server/src/base/base-eth-registry-address.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { HexString } from "@ckb-lumos/base";
import { Uint32 } from "./types/uint";

// NOTE: Not to import `gwConfig`
export class BaseEthRegistryAddress {
private registryId: number;
private addressByteSize: number = 20;
public readonly address: HexString;

// Using optional registryId when gwConfig not initialized
constructor(address: HexString, registryId: number) {
if (!address.startsWith("0x") || address.length !== 42) {
throw new Error(`Eth address format error: ${address}`);
}
this.address = address.toLowerCase();

this.registryId = registryId;
}

public serialize(): HexString {
return (
"0x" +
new Uint32(this.registryId).toLittleEndian().slice(2) +
new Uint32(this.addressByteSize).toLittleEndian().slice(2) +
this.address.slice(2)
);
}

public static Deserialize(hex: HexString): BaseEthRegistryAddress {
const hexWithoutPrefix = hex.slice(2);
const registryId: number = Uint32.fromLittleEndian(
hexWithoutPrefix.slice(0, 8)
).getValue();
const addressByteSize: number = Uint32.fromLittleEndian(
hexWithoutPrefix.slice(8, 16)
).getValue();
const address: HexString = hexWithoutPrefix.slice(16);
if (addressByteSize !== 20 || address.length !== 40) {
throw new Error(`Eth address deserialize error: ${hex}`);
}
return new BaseEthRegistryAddress("0x" + address, registryId);
}
}
11 changes: 6 additions & 5 deletions web3/packages/api-server/src/base/gw-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { CKB_SUDT_ID, ZERO_ETH_ADDRESS } from "../methods/constant";
import { Uint32 } from "./types/uint";
import { snakeToCamel } from "../util";
import { EntryPointContract } from "../gasless/entrypoint";
import { EthRegistryAddress } from "./address";
import { BaseEthRegistryAddress } from "./base-eth-registry-address";
import { logger } from "./logger";

// source: https://github.com/nervosnetwork/godwoken/commit/d6c98d8f8a199b6ec29bc77c5065c1108220bb0a#diff-c56fda2ca3b1366049c88e633389d9b6faa8366151369fd7314c81f6e389e5c7R5
Expand All @@ -39,7 +39,7 @@ export class GwConfig {
private iNodeVersion: string | undefined;
private iEntryPointContract: EntryPointContract | undefined;

constructor(rpcOrUrl: GodwokenClient | string) {
constructor(rpcOrUrl: string) {
if (typeof rpcOrUrl === "string") {
this.rpc = new GodwokenClient(rpcOrUrl);
return;
Expand Down Expand Up @@ -441,9 +441,10 @@ async function zeroAddressAccount(
rpc: GodwokenClient,
registryId: number
): Promise<AccountWithAddress | undefined> {
const registryAddress = new EthRegistryAddress(ZERO_ETH_ADDRESS, {
registryId,
});
const registryAddress = new BaseEthRegistryAddress(
ZERO_ETH_ADDRESS,
registryId
);
const scriptHash: Hash | undefined = await rpc.getScriptHashByRegistryAddress(
registryAddress.serialize()
);
Expand Down
17 changes: 16 additions & 1 deletion web3/packages/api-server/tests/utils/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ mockRpc.getAccountIdByScriptHash = async (scriptHash: HexString) => {
case "0xb5f81e2d10af9600194606989583ae8cc3fcb822a24fdea95f42da5ea18606da":
return 2;

case "0xc48e0895b9fd1af6c0770dbdc2d46a2fa93e4efc4af79e616a2bb87eebfabd84":
return 5;

default:
throw new Error(
`getAccountIdByScriptHash not mock for script hash ${scriptHash}`
Expand Down Expand Up @@ -77,6 +80,17 @@ mockRpc.getScript = async (scriptHash: HexString) => {
}
};

mockRpc.getScriptHashByRegistryAddress = async (registryAddress: HexString) => {
switch (registryAddress) {
case "0x02000000140000000000000000000000000000000000000000000000":
return "0xc48e0895b9fd1af6c0770dbdc2d46a2fa93e4efc4af79e616a2bb87eebfabd84";
default:
throw new Error(
`getScriptHashByRegistryAddress not mock for registryAddress: ${registryAddress}`
);
}
};

mockRpc.getNodeInfo = async () => {
const nodeInfo: NodeInfo = {
backends: [
Expand Down Expand Up @@ -197,7 +211,8 @@ test("init gw config", async (t) => {
},
});
t.is(config.accounts.polyjuiceCreator.id, "0x4");
t.is(config.accounts.defaultFrom.id, "0x3");
// Using zero address as default address
t.is(config.accounts.defaultFrom.id, "0x5");
t.is(config.accounts.ethAddrReg.id, "0x2");
t.is(config.nodeMode, NodeMode.FullNode);
t.is(config.web3ChainId, "0x116e8");
Expand Down

0 comments on commit 7e8e0be

Please sign in to comment.