From 60ef6c1df0de3ca5a9ca9fff8381325b8d6d471d Mon Sep 17 00:00:00 2001
From: David Murdoch <187813+davidmurdoch@users.noreply.github.com>
Date: Tue, 22 Aug 2023 18:49:09 -0400
Subject: [PATCH 1/6] test: increase test timeout duration for slow test
(#4506)
---
packages/core/tests/server.test.ts | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/packages/core/tests/server.test.ts b/packages/core/tests/server.test.ts
index bf83ed3de2..18d339d5c7 100644
--- a/packages/core/tests/server.test.ts
+++ b/packages/core/tests/server.test.ts
@@ -461,7 +461,9 @@ describe("server", () => {
} finally {
await teardown();
}
- });
+ // TODO: this test can take a while on mac in CI, figure out why
+ // https://github.com/trufflesuite/ganache/issues/4505
+ }).timeout(0);
it("fails to `.listen()` twice, Callback", async () => {
await setup();
@@ -514,9 +516,19 @@ describe("server", () => {
await s.close();
- const error = await post("localhost", port, jsonRpcJson, agent).catch(e => e);
- assert(error instanceof Error, `Expected error to be an instance of Error, but got ${error} instead`);
- assert("code" in error && (error["code"] === "ECONNREFUSED" || error["code"] === "ECONNRESET"), `Expected error.code to be ECONNREFUSED or ECONNRESET, got ${error} instead`);
+ const error = await post("localhost", port, jsonRpcJson, agent).catch(
+ e => e
+ );
+ assert(
+ error instanceof Error,
+ `Expected error to be an instance of Error, but got ${error} instead`
+ );
+ assert(
+ "code" in error &&
+ (error["code"] === "ECONNREFUSED" ||
+ error["code"] === "ECONNRESET"),
+ `Expected error.code to be ECONNREFUSED or ECONNRESET, got ${error} instead`
+ );
} finally {
teardown();
}
From 4b4f92128f5f59cbfa4cf4fc4a127a879b9ba3b1 Mon Sep 17 00:00:00 2001
From: David Murdoch <187813+davidmurdoch@users.noreply.github.com>
Date: Tue, 22 Aug 2023 18:49:30 -0400
Subject: [PATCH 2/6] docs: add instructions for using ganache with viem
(#4476)
---
packages/ganache/README.md | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/packages/ganache/README.md b/packages/ganache/README.md
index 0075c03c3b..b6bd561805 100644
--- a/packages/ganache/README.md
+++ b/packages/ganache/README.md
@@ -146,7 +146,7 @@ You can use Ganache programmatically from Node.js. Install Ganache into your npm
$ npm install ganache
```
-Then you can use ganache as an [EIP-1193 provider only](#as-an-eip-1193-provider-only), an [EIP-1193 provider and JSON-RPC web server](#as-an-eip-1193-provider-and-json-rpc-web-server), as a [Web3 provider](#as-a-web3js-provider), or an [ethers provider](#as-an-ethersjs-provider).
+Then you can use ganache as an [EIP-1193 provider only](#as-an-eip-1193-provider-only), an [EIP-1193 provider and JSON-RPC web server](#as-an-eip-1193-provider-and-json-rpc-web-server), as a [Web3 provider](#as-a-web3js-provider), an [ethers provider](#as-an-ethersjs-provider), or a [viem transport](#as-a-viem-transport).
#### As an EIP-1193 provider only:
@@ -203,6 +203,20 @@ const ganache = require("ganache");
const provider = new ethers.providers.Web3Provider(ganache.provider());
```
+#### As a [viem](https://www.npmjs.com/package/viem) transport:
+
+To use a ganache provider as a viem transport:
+
+```javascript
+import { createWalletClient, custom } from "viem";
+import { localhost } from "viem/chains";
+import ganache from "ganache";
+const client = createWalletClient({
+ chain: localhost,
+ transport: custom(ganache.provider())
+});
+```
+
### Browser Use
You can also use Ganache in the browser by adding the following script to your HTML:
From b44196292537686b5568d78e2c7581985846c3fd Mon Sep 17 00:00:00 2001
From: David Murdoch <187813+davidmurdoch@users.noreply.github.com>
Date: Mon, 28 Aug 2023 18:19:43 -0400
Subject: [PATCH 3/6] docs: add plugins to features list in readme (#4519)
---
packages/ganache/README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/ganache/README.md b/packages/ganache/README.md
index b6bd561805..0ae6b02ac7 100644
--- a/packages/ganache/README.md
+++ b/packages/ganache/README.md
@@ -40,6 +40,7 @@ Ganache is an Ethereum simulator that makes developing Ethereum applications fas
- Listens for JSON-RPC 2.0 requests over HTTP/WebSockets
- Programmatic use in Node.js
- Pending Transactions
+- Flavors (aka Plugins), like Filecoin
## Getting Started
From 040428f60734489ddb163ac3bac8c968b92010f8 Mon Sep 17 00:00:00 2001
From: David Murdoch <187813+davidmurdoch@users.noreply.github.com>
Date: Fri, 15 Sep 2023 19:44:48 -0400
Subject: [PATCH 4/6] fix: regression in `eth_sign` signature `v` values
(#4527)
---
package.json | 3 +-
packages/ethereum/ethereum/src/api.ts | 2 +-
.../ethereum/tests/api/eth/sign.test.ts | 17 +++-
scripts/update-ethereum-js.ts | 95 +++++++++++++++++++
4 files changed, 114 insertions(+), 3 deletions(-)
create mode 100644 scripts/update-ethereum-js.ts
diff --git a/package.json b/package.json
index b957ee65fc..c5cd9451f0 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,8 @@
"start": "lerna exec --loglevel=silent --scope ganache -- npm run start --silent -- ",
"test": "lerna exec --concurrency 1 -- npm run test",
"tsc": "tsc --build",
- "tsc.clean": "npx lerna exec -- npx shx rm -rf lib dist typings"
+ "tsc.clean": "npx lerna exec -- npx shx rm -rf lib dist typings",
+ "update-ethereumjs": "cd scripts && ts-node update-ethereumjs"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "1.0.2",
diff --git a/packages/ethereum/ethereum/src/api.ts b/packages/ethereum/ethereum/src/api.ts
index 93d5674e8a..c4289b6825 100644
--- a/packages/ethereum/ethereum/src/api.ts
+++ b/packages/ethereum/ethereum/src/api.ts
@@ -2079,7 +2079,7 @@ export default class EthereumApi implements Api {
const messageHash = hashPersonalMessage(Data.toBuffer(message));
const { v, r, s } = ecsign(messageHash, privateKey.toBuffer());
- return toRpcSig(v, r, s);
+ return toRpcSig(v + 27n, r, s);
}
/**
diff --git a/packages/ethereum/ethereum/tests/api/eth/sign.test.ts b/packages/ethereum/ethereum/tests/api/eth/sign.test.ts
index ecfab32d06..f57726ba4e 100644
--- a/packages/ethereum/ethereum/tests/api/eth/sign.test.ts
+++ b/packages/ethereum/ethereum/tests/api/eth/sign.test.ts
@@ -8,6 +8,7 @@ import {
} from "@ethereumjs/util";
import getProvider from "../../helpers/getProvider";
import { Data, Quantity } from "@ganache/utils";
+import { sign } from "crypto";
describe("api", () => {
describe("eth", () => {
@@ -37,10 +38,17 @@ describe("api", () => {
const msgHash = hashPersonalMessage(msg);
const address = accounts[0];
- let sgn = await provider.send("eth_sign", [
+ let sgn: string = await provider.send("eth_sign", [
address,
Data.toString(msg)
]);
+
+ assert.strictEqual(
+ sgn.substring(sgn.length - 2),
+ "1c", // 28 in hex
+ "eth_sign should produce a v value of 27 or 28"
+ );
+
const { v, r, s } = fromRpcSig(sgn);
const pub = ecrecover(msgHash, v, r, s);
@@ -59,7 +67,14 @@ describe("api", () => {
let sgn = await provider.send("eth_sign", [accounts[0], msgHex]);
+ assert.strictEqual(
+ sgn.substring(sgn.length - 2),
+ "1c", // 28 in hex
+ "eth_sign should produce a v value of 27 or 28"
+ );
+
const { v, r, s } = fromRpcSig(sgn);
+
const pub = ecrecover(msgHash, v, r, s);
const addr = fromSigned(pubToAddress(pub));
const strAddr = Data.toString(Quantity.toBuffer(addr), 20);
diff --git a/scripts/update-ethereum-js.ts b/scripts/update-ethereum-js.ts
new file mode 100644
index 0000000000..8cc014d9a9
--- /dev/null
+++ b/scripts/update-ethereum-js.ts
@@ -0,0 +1,95 @@
+// search through all folders in the parent directory to find all package.json
+// files. Then read each file looking for ethereumjs dependencies,
+// devDependencies, or optionalDependencies. If found, update the version
+// number to the latest version on npm (by querying the npm registry).
+
+import * as fs from "fs";
+import * as path from "path";
+import * as util from "util";
+import * as child_process from "child_process";
+import * as https from "https";
+
+const readdir = util.promisify(fs.readdir);
+const readFile = util.promisify(fs.readFile);
+const writeFile = util.promisify(fs.writeFile);
+const exec = util.promisify(child_process.exec);
+
+const parentDir = path.resolve(__dirname, "../");
+
+async function findPackageFiles(dir: string): Promise {
+ const files: string[] = [];
+ const dirents = await readdir(dir, { withFileTypes: true });
+
+ for (const dirent of dirents) {
+ const res = path.resolve(dir, dirent.name);
+ if (dirent.isDirectory() && dirent.name !== "node_modules") {
+ const subFiles = await findPackageFiles(res);
+ files.push(...subFiles);
+ } else if (dirent.isFile() && dirent.name === "package.json") {
+ files.push(res);
+ }
+ }
+
+ return files;
+}
+
+const cache = new Map();
+
+async function updateDependencies(packagePath: string) {
+ const packageData = await readFile(packagePath, { encoding: "utf-8" });
+ const packageJson = JSON.parse(packageData);
+
+ const dependencies = [
+ [[...Object.entries(packageJson.dependencies ?? {})], "dependencies"],
+ [[...Object.entries(packageJson.devDependencies ?? {})], "devDependencies"],
+ [
+ [...Object.entries(packageJson.optionalDependencies ?? {})],
+ "optionalDependencies"
+ ]
+ ] as [[string, string][], string][];
+
+ let changed = false;
+
+ for (const [matches, group] of dependencies) {
+ for (const [name, version] of matches) {
+ if (name.startsWith("@ethereumjs/")) {
+ const response = cache.has(name)
+ ? cache.get(name)!
+ : await new Promise((resolve, reject) => {
+ https
+ .get(`https://registry.npmjs.org/${name}`, res => {
+ const chunks: Uint8Array[] = [];
+ res.on("data", chunk => chunks.push(chunk));
+ res.on("end", () => resolve(Buffer.concat(chunks)));
+ })
+ .on("error", reject);
+ });
+ if (cache.has(name)) {
+ cache.set(name, response);
+ }
+ const registryData = JSON.parse(response.toString());
+ const latestVersion = registryData["dist-tags"].latest;
+ if (version !== latestVersion) {
+ packageJson[group][name] = latestVersion;
+ changed = true;
+ }
+ }
+ }
+ }
+
+ if (changed) {
+ await writeFile(packagePath, JSON.stringify(packageJson, null, 2));
+ }
+}
+
+async function main() {
+ const packagePaths = await findPackageFiles(parentDir);
+
+ for (const packagePath of packagePaths) {
+ await updateDependencies(packagePath);
+ }
+
+ await exec("npm run reinstall", { cwd: parentDir });
+}
+
+main().catch(console.error);
From 1c9b9953386183c83d560847eae3e08e65013246 Mon Sep 17 00:00:00 2001
From: David Murdoch <187813+davidmurdoch@users.noreply.github.com>
Date: Mon, 18 Dec 2023 11:54:00 -0500
Subject: [PATCH 5/6] docs: fix logo in README.md (#4562)
---
packages/ganache/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/ganache/README.md b/packages/ganache/README.md
index 0ae6b02ac7..584608a4ce 100644
--- a/packages/ganache/README.md
+++ b/packages/ganache/README.md
@@ -1,6 +1,6 @@
-
+
From ca2965e689982771a3d11cfe2556bef455a19aed Mon Sep 17 00:00:00 2001
From: David Murdoch <187813+davidmurdoch@users.noreply.github.com>
Date: Mon, 18 Dec 2023 14:37:11 -0500
Subject: [PATCH 6/6] fix: block bloom filter (#4535)
---
packages/ethereum/ethereum/src/miner/miner.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/ethereum/ethereum/src/miner/miner.ts b/packages/ethereum/ethereum/src/miner/miner.ts
index 3cb1684d9c..6c1621c273 100644
--- a/packages/ethereum/ethereum/src/miner/miner.ts
+++ b/packages/ethereum/ethereum/src/miner/miner.ts
@@ -64,7 +64,7 @@ export type BlockData = {
const updateBloom = (blockBloom: Buffer, bloom: Buffer) => {
let i = 256;
- while (--i) blockBloom[i] |= bloom[i];
+ while (i--) blockBloom[i] |= bloom[i];
};
const sortByPrice = (values: TypedTransaction[], a: number, b: number) =>