Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

feat: add --flavor feature (ganache chain plugins) #4362

Merged
merged 67 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
3f2d655
delete tezos and refactor plugins
davidmurdoch Sep 16, 2022
c9bdc9a
oops
davidmurdoch Apr 15, 2023
28eed02
oops2
davidmurdoch Apr 15, 2023
e3fe9af
oops3
davidmurdoch Apr 15, 2023
328abc9
import type
davidmurdoch Apr 15, 2023
82f0330
revert
davidmurdoch Apr 15, 2023
d40f30a
Update src/chains/filecoin/filecoin/src/connector.ts
davidmurdoch Apr 15, 2023
9912275
Null
davidmurdoch Apr 15, 2023
19765e7
You
davidmurdoch Apr 15, 2023
a9a4e68
Sigh
davidmurdoch Apr 15, 2023
9edce5a
quick ci test
davidmurdoch Apr 15, 2023
db54103
Merge branch 'flavor2' of github.com:trufflesuite/ganache into flavor2
davidmurdoch Apr 15, 2023
6ba2798
oops_
davidmurdoch Apr 15, 2023
986a281
sfsfdsdf
davidmurdoch Apr 15, 2023
b74032a
lazy
davidmurdoch Apr 16, 2023
40b8f4c
make example work
davidmurdoch Apr 24, 2023
b4875b3
more examples and things
davidmurdoch Apr 25, 2023
79a371d
typo fixes
davidmurdoch Apr 25, 2023
9d235e6
ReturnType<Api[KnownKeys<Api>]> resolved to unknown anyway
davidmurdoch Apr 28, 2023
3d7fbd0
more flavor tweaks and examples
davidmurdoch Apr 28, 2023
160f13b
Merge branch 'develop' into flavor2
davidmurdoch Apr 28, 2023
1fadb7c
polish
davidmurdoch May 2, 2023
05da030
d
davidmurdoch May 2, 2023
fc3ff3a
polish
davidmurdoch May 2, 2023
71e9790
add default options and note
davidmurdoch May 2, 2023
249e43e
back compat, maybe
davidmurdoch May 3, 2023
4e9c01b
.
davidmurdoch May 3, 2023
2514d70
things
davidmurdoch May 3, 2023
39e973e
revert change
davidmurdoch May 3, 2023
078cc0b
revert
davidmurdoch May 3, 2023
504de6a
types
davidmurdoch May 3, 2023
879f26b
add chalk
davidmurdoch May 3, 2023
ae66e80
more filecoin removal
davidmurdoch May 4, 2023
d96d35e
remove change
davidmurdoch May 4, 2023
5ff2e05
clean up dependencies
davidmurdoch May 4, 2023
5b6d3e9
maybe this time
davidmurdoch May 5, 2023
225491f
why you no install on node 14?
davidmurdoch May 5, 2023
fea1248
fix out of date dep
davidmurdoch May 5, 2023
9a1163d
deps
davidmurdoch May 5, 2023
2388cb6
types
davidmurdoch May 5, 2023
6e0449c
this doesn't need to be exported
davidmurdoch May 5, 2023
b8b9d31
we don't allow old flavors anymore, so only support `ready`
davidmurdoch May 5, 2023
2728355
ready note
davidmurdoch May 5, 2023
0d119e0
change interface
davidmurdoch May 5, 2023
9943157
some things
davidmurdoch May 5, 2023
cc62012
remove change
davidmurdoch May 5, 2023
e0d4337
get lazier
davidmurdoch May 5, 2023
861d6bb
i said lazy!
davidmurdoch May 5, 2023
7b04571
lazy
davidmurdoch May 5, 2023
565706d
comment
davidmurdoch May 5, 2023
ea81e2c
remove some changes
davidmurdoch May 5, 2023
928e984
better comment
davidmurdoch May 5, 2023
ed8d2e9
add example test
davidmurdoch May 5, 2023
694496e
update comment
davidmurdoch May 5, 2023
b1fdaf3
naming
davidmurdoch May 5, 2023
899dca4
better?
davidmurdoch May 5, 2023
2d6deab
refactor
davidmurdoch May 5, 2023
12122c9
i don't know why
davidmurdoch May 5, 2023
e351cae
preload
davidmurdoch May 5, 2023
60192de
:-(
davidmurdoch May 5, 2023
78bbafc
typessss
davidmurdoch May 5, 2023
195a914
Merge branch 'develop' into flavor2
davidmurdoch Jul 7, 2023
82dbb01
fix deps and lock files
davidmurdoch Jul 11, 2023
3097f8e
Import from '../index' rather than '..' to resolve tsc issues
jeffsmale90 Jul 25, 2023
b42258c
Merge ganache configuration with flavor configuration to avoid duplic…
jeffsmale90 Jul 26, 2023
809891c
Fix issues with yargs configuration. Remove duplicate 'instances' com…
jeffsmale90 Jul 26, 2023
7cf6285
remove port/host hack
davidmurdoch Aug 4, 2023
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
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ Where `<module>` is the npm-module you want to add and `<package>` is where you
Example:

```bash
npx lerna add @ganache/options -E --scope=@ganache/filecoin
npx lerna add @ganache/options -E --scope=@ganache/ethereum
```

will add our local `@ganache/options` package to the `@ganache/filecoin` package.
will add our local `@ganache/options` package to the `@ganache/ethereum` package.

## To remove a module from another package:

Expand Down
2 changes: 1 addition & 1 deletion docs/assets/js/ganache/ganache.min.js.map

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/chains/ethereum/console.log/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe("@ganache/console.log", () => {

after("shut down the provider", async () => {
provider && (await provider.disconnect());
provider = null;
provider = null!;
});

beforeEach("snapshot", async () => {
Expand All @@ -65,7 +65,7 @@ describe("@ganache/console.log", () => {
method: "evm_revert",
params: [snapshotId]
}));
snapshotId = null;
snapshotId = null!;
});

/**
Expand Down Expand Up @@ -369,7 +369,7 @@ describe("@ganache/console.log", () => {
});

describe(`${name}(${params.join(", ")})`, () => {
const possibleValues = params.map(param => staticValues.get(param));
const possibleValues = params.map(param => staticValues.get(param)!);

const method = get4ByteForSignature(
`${functionName}(${params.map(toAbiType)})`
Expand All @@ -388,7 +388,7 @@ describe("@ganache/console.log", () => {
describe("miscellaneous", () => {
const func = functions.find(
f => f.params.length === 1 && f.params[0].type === "string memory"
);
)!;
const method = get4ByteForSignature(`${func.functionName}(string)`);
const params = [{ type: func.params[0].type, value: "Hello, World!" }];

Expand All @@ -415,7 +415,7 @@ describe("@ganache/console.log", () => {
});

it("does NOT log when `console.log` is called within an `eth_estimateGas`", async () => {
const allLogs = [];
const allLogs: any[] = [];
logger.log = (...logs: any[]) => {
if (logs[0] === "eth_estimateGas") return;

Expand Down Expand Up @@ -509,7 +509,7 @@ contract ${CONTRACT_NAME} {
assert.strictEqual(receipt.status, "0x1");
assert.strictEqual(receipt.transactionIndex, "0x1");

const allLogs = [];
const allLogs: any[] = [];
logger.log = (...logs: any[]) => {
if (logs[0] === "debug_storageRangeAt") return;
allLogs.push(logs);
Expand Down
164 changes: 164 additions & 0 deletions src/chains/ethereum/ethereum/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,169 @@
* @license MIT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this line, but:

  • --port shorthand doesn't work
  • --host shorthand doesn't work
  • instances list shows undefined for the host (no host property is persisted to the instance file) when no host is explicitly provided

*/

import chalk from "chalk";
import { TruffleColors } from "@ganache/colors";
import { Executor, WEI } from "@ganache/utils";
import { toChecksumAddress } from "ethereumjs-util";
import { EthereumProvider } from "./src/provider";
import { Connector } from "./src/connector";
import {
EthereumLegacyProviderOptions,
EthereumOptionsConfig,
EthereumProviderOptions
} from "@ganache/ethereum-options";
import type { Flavor } from "@ganache/flavor";
import { CliOptionsConfig, ServerOptionsConfig } from "@ganache/flavor";

export * from "./src/connector";
export * from "./src/api-types";

function capitalizeFirstLetter(string: string) {
return string[0].toUpperCase() + string.slice(1);
}
function color(str: string) {
return chalk`{hex("${TruffleColors.porsche}") ${str}}`;
}

type EthereumFlavor = Flavor<
"ethereum",
Connector,
EthereumOptionsConfig,
ServerOptionsConfig,
CliOptionsConfig
>;
const EthereumFlavor: EthereumFlavor = {
flavor: "ethereum",
connect: (
options: EthereumProviderOptions | EthereumLegacyProviderOptions,
executor: Executor
) => new Connector(options, executor),
options: {
provider: EthereumOptionsConfig,
server: ServerOptionsConfig,
cli: CliOptionsConfig
},
initialize
};
// flavors are exported as a default export
export default EthereumFlavor;

function initialize(
provider: EthereumProvider,
cliSettings: { host: string; port: number }
) {
const liveOptions = provider.getOptions();
const accounts = provider.getInitialAccounts();

const addresses = Object.keys(accounts);
const logs = [];
logs.push("");
logs.push("Available Accounts");
logs.push("==================");
if (addresses.length > 0) {
addresses.forEach(function (address, index) {
const balance = accounts[address].balance;
const strBalance = balance / WEI;
const about = balance % WEI === 0n ? "" : "~";
let line = `(${index}) ${toChecksumAddress(
address
)} (${about}${strBalance} ETH)`;

if (!accounts[address].unlocked) {
line += " 🔒";
}

logs.push(line);
});

logs.push("");
logs.push("Private Keys");
logs.push("==================");

addresses.forEach(function (address, index) {
logs.push(`(${index}) ${accounts[address].secretKey}`);
});

if (liveOptions.wallet.accountKeysPath != null) {
logs.push("");
logs.push(
`Accounts and keys saved to ${liveOptions.wallet.accountKeysPath}`
);
}
} else {
logs.push("(no accounts unlocked)");
}

if (liveOptions.wallet.accounts == null) {
logs.push("");
logs.push("HD Wallet");
logs.push("==================");
logs.push(`Mnemonic: ${color(liveOptions.wallet.mnemonic)}`);
logs.push(
`Base HD Path: ${color(
liveOptions.wallet.hdPath.join("/") + "/{account_index}"
)}`
);
}

if (liveOptions.miner.defaultGasPrice) {
logs.push("");
logs.push("Default Gas Price");
logs.push("==================");
logs.push(color(liveOptions.miner.defaultGasPrice.toBigInt().toString()));
}

if (liveOptions.miner.blockGasLimit) {
logs.push("");
logs.push("BlockGas Limit");
logs.push("==================");
logs.push(color(liveOptions.miner.blockGasLimit.toBigInt().toString()));
}

if (liveOptions.miner.callGasLimit) {
logs.push("");
logs.push("Call Gas Limit");
logs.push("==================");
logs.push(color(liveOptions.miner.callGasLimit.toBigInt().toString()));
}

if (liveOptions.fork.network || liveOptions.fork.url) {
logs.push("");
logs.push("Forked Chain");
logs.push("==================");
let location: string;
if (liveOptions.fork.network) {
location = `Ethereum ${capitalizeFirstLetter(
liveOptions.fork.network.replace("goerli", "görli")
)}, via ${chalk`{hex("${TruffleColors.infura}") 丕Infura}`}`;
} else {
location = (liveOptions.fork.url as any).toString();
}

logs.push(`Location: ${color(location)}`);
logs.push(
`Block: ${color(liveOptions.fork.blockNumber.toString())}`
);
logs.push(
`Network ID: ${color(liveOptions.chain.networkId.toString())}`
);
logs.push(`Time: ${color(liveOptions.chain.time.toString())}`);

if (liveOptions.fork.requestsPerSecond !== 0) {
logs.push(
`Requests/Second: ${color(
liveOptions.fork.requestsPerSecond.toString()
)}`
);
}
}

logs.push("");
logs.push("Chain Id");
logs.push("==================");
logs.push(color(liveOptions.chain.chainId.toString()));

logs.push("");
logs.push("RPC Listening on " + cliSettings.host + ":" + cliSettings.port);
console.log(logs.join("\n"));
}
2 changes: 2 additions & 0 deletions src/chains/ethereum/ethereum/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"@ethereumjs/tx": "4.1.1",
"@ethereumjs/util": "8.0.5",
"@ethereumjs/vm": "6.4.1",
"@ganache/colors": "0.4.0",
"@ganache/console.log": "0.4.0",
"@ganache/ethereum-address": "0.8.0",
"@ganache/ethereum-block": "0.8.0",
Expand Down Expand Up @@ -87,6 +88,7 @@
"ws": "8.2.3"
},
"devDependencies": {
"@ganache/flavor": "0.9.0",
"@trufflesuite/uws-js-unofficial": "20.10.0-unofficial.2",
"@types/encoding-down": "5.0.0",
"@types/fs-extra": "9.0.2",
Expand Down
32 changes: 11 additions & 21 deletions src/chains/ethereum/ethereum/src/connector.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import Emittery from "emittery";
import EthereumApi from "./api";
import {
Connector as IConnector,
Executor,
makeError,
makeResponse,
Expand All @@ -12,20 +10,19 @@ import {
} from "@ganache/utils";
export type { EthereumProvider } from "./provider";
import { EthereumProvider } from "./provider";
import {
import type {
RecognizedString,
WebSocket,
HttpRequest
} from "@trufflesuite/uws-js-unofficial";
HttpRequest,
Connector as IConnector
} from "@ganache/flavor";
import { CodedError } from "@ganache/ethereum-utils";
import {
EthereumProviderOptions,
EthereumLegacyProviderOptions
} from "@ganache/ethereum-options";
import { bufferify } from "./helpers/bufferify";

type ProviderOptions = EthereumProviderOptions | EthereumLegacyProviderOptions;

function isHttp(
connection: HttpRequest | WebSocket
): connection is HttpRequest {
Expand All @@ -36,35 +33,28 @@ function isHttp(
}

export class Connector<
R extends JsonRpcRequest<
EthereumApi,
KnownKeys<EthereumApi>
> = JsonRpcRequest<EthereumApi, KnownKeys<EthereumApi>>
>
extends Emittery<{ ready: undefined; close: undefined }>
implements IConnector<EthereumApi, R | R[], JsonRpcResponse>
R extends JsonRpcRequest<
EthereumApi,
KnownKeys<EthereumApi>
> = JsonRpcRequest<EthereumApi, KnownKeys<EthereumApi>>
> implements IConnector<EthereumProvider, R | R[], JsonRpcResponse>
{
#provider: EthereumProvider;

static BUFFERIFY_THRESHOLD: number = 100000;

get provider() {
get provider(): EthereumProvider {
return this.#provider;
}
Comment on lines -51 to 48
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just change #provider to be readonly public?


constructor(providerOptions: ProviderOptions = null, executor: Executor) {
super();

constructor(providerOptions: EthereumProviderOptions | EthereumLegacyProviderOptions = null, executor: Executor) {
this.#provider = new EthereumProvider(providerOptions, executor);
}

public BUFFERIFY_THRESHOLD = Connector.BUFFERIFY_THRESHOLD;

async connect() {
await this.#provider.initialize();
// no need to wait for #provider.once("connect") as the initialize()
// promise has already accounted for that after the promise is resolved
await this.emit("ready");
}

parse(message: Buffer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export class HttpHandler extends BaseHandler implements Handler {
const postData = `${JSONRPC_PREFIX}${this.id++},${key.slice(1)}`;
this.headers["content-length"] = postData.length;

// @ts-ignore
const req = this._request(requestOptions);
davidmurdoch marked this conversation as resolved.
Show resolved Hide resolved
req.on("response", res => {
const { headers } = res;
Expand Down
26 changes: 11 additions & 15 deletions src/chains/ethereum/ethereum/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
Executor,
hasOwn,
KnownKeys,
Provider,
JsonRpcRequest,
JsonRpcResponse,
JsonRpcError,
Expand Down Expand Up @@ -124,20 +123,17 @@ type RequestParams<Method extends RequestMethods> = {
readonly method: Method;
readonly params: OverloadedParameters<EthereumApi[Method]> | undefined;
};
export class EthereumProvider
extends Emittery<{
message: MessageEvent;
data: DataEvent;
error: Error;
"ganache:vm:tx:step": VmStepEvent;
"ganache:vm:tx:before": VmBeforeTransactionEvent;
"ganache:vm:tx:after": VmAfterTransactionEvent;
"ganache:vm:tx:console.log": VmConsoleLogEvent;
connect: undefined;
disconnect: undefined;
}>
implements Provider<EthereumApi>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implements Provider<EthereumApi> was basically any, so was pointless.

{
export class EthereumProvider extends Emittery<{
message: MessageEvent;
data: DataEvent;
error: Error;
"ganache:vm:tx:step": VmStepEvent;
"ganache:vm:tx:before": VmBeforeTransactionEvent;
"ganache:vm:tx:after": VmAfterTransactionEvent;
"ganache:vm:tx:console.log": VmConsoleLogEvent;
connect: undefined;
disconnect: undefined;
}> {
#options: EthereumInternalOptions;
#api: EthereumApi;
#wallet: Wallet;
Expand Down
8 changes: 8 additions & 0 deletions src/chains/ethereum/ethereum/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@
{
"name": "@ganache/console.log",
"path": "../console.log"
},
{
"name": "@ganache/flavor",
"path": "../../../packages/flavor"
},
{
"name": "@ganache/colors",
"path": "../../../packages/colors"
}
]
}
Loading