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

Commit

Permalink
Merge pull request #4563 from trufflesuite/develop
Browse files Browse the repository at this point in the history
chore(release): publish v7.9.2
  • Loading branch information
davidmurdoch authored Dec 21, 2023
2 parents d461889 + ca2965e commit 10002d5
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 10 deletions.
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);

0 comments on commit 10002d5

Please sign in to comment.