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

chore(release): publish v7.9.2 #4563

Merged
merged 6 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
20 changes: 16 additions & 4 deletions packages/core/tests/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion packages/ethereum/ethereum/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/ethereum/ethereum/src/miner/miner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down
17 changes: 16 additions & 1 deletion packages/ethereum/ethereum/tests/api/eth/sign.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
19 changes: 17 additions & 2 deletions packages/ganache/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!-- Using h2 instead of h1 because npm doesn't support align=center on h1 tags -->
<h2 align="center">
<a href="#readme" title="Ganache README.md"><img alt="Ganache" src="https://ganache.dev/assets/img/ganache-logo-dark.svg" alt="Ganache" width="160"/></a>
<a href="#readme" title="Ganache README.md"><img alt="Ganache" src="https://raw.githubusercontent.com/trufflesuite/ganache/develop/docs/assets/img/ganache-logo-dark.svg" alt="Ganache" width="160"/></a>
</h2>

<h3 align="center">
Expand Down Expand Up @@ -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
- <a href="https://github.com/trufflesuite/ganache/tree/develop/packages/flavor#readme">Flavors</a> (aka Plugins), like <a href="https://github.com/trufflesuite/ganache-plugin-filecoin/tree/main/packages/filecoin#readme">Filecoin</a>

## Getting Started

Expand Down Expand Up @@ -146,7 +147,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:

Expand Down Expand Up @@ -203,6 +204,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:
Expand Down
95 changes: 95 additions & 0 deletions scripts/update-ethereum-js.ts
Original file line number Diff line number Diff line change
@@ -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<string[]> {
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<string, Buffer>();

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<Buffer>((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);