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

Commit

Permalink
fix: set the earliest block tag on startup when forking (#3755)
Browse files Browse the repository at this point in the history
Co-authored-by: Andres Adjimann <[email protected]>
Co-authored-by: Micaiah Reid <[email protected]>
Co-authored-by: David Murdoch <[email protected]>
  • Loading branch information
4 people authored Jan 12, 2023
1 parent 702db83 commit 7ee7d4b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
10 changes: 8 additions & 2 deletions src/chains/ethereum/ethereum/src/blockchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,14 @@ export default class Blockchain extends Emittery<BlockchainTypedEvents> {
options.miner.blockGasLimit,
initialAccounts
);
blocks.earliest = blocks.latest =
await this.#blockBeingSavedPromise.then(({ block }) => block);
blocks.latest = await this.#blockBeingSavedPromise.then(
({ block }) => block
);
// when we are forking, blocks.earliest is already set to what was
// retrieved from the fork
if (!blocks.earliest) {
blocks.earliest = blocks.latest;
}
}
}

Expand Down
33 changes: 28 additions & 5 deletions src/chains/ethereum/ethereum/src/data-managers/block-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
TypedDatabaseTransaction
} from "@ganache/ethereum-transaction";
import { GanacheLevelUp } from "../database";
import { Ethereum } from "../api-types";

const LATEST_INDEX_KEY = BUFFER_ZERO;

Expand Down Expand Up @@ -274,17 +275,39 @@ export default class BlockManager extends Manager<Block> {
await this.#blockIndexes.put(LATEST_INDEX_KEY, number);
}

async getEarliest() {
const fallback = this.#blockchain.fallback;
if (fallback) {
const json = await fallback.request<Ethereum.Block<true, "public">>(
"eth_getBlockByNumber",
[Tag.earliest, true],
// TODO: re-enable cache once this is fixed
// https://github.com/trufflesuite/ganache/issues/3773
{ disableCache: true }
);
if (json) {
const common = fallback.getCommonForBlockNumber(
this.#common,
BigInt(json.number)
);
return new Block(BlockManager.rawFromJSON(json, common), common);
}
} else {
// if we're forking, there shouldn't be an earliest block saved to the db,
// it's always retrieved from the fork
for await (const data of this.base.createValueStream({ limit: 1 })) {
return new Block(data as Buffer, this.#common);
}
}
}

/**
* Updates the this.latest and this.earliest properties with data
* from the database.
*/
async updateTaggedBlocks() {
const [earliest, latestBlockNumber] = await Promise.all([
(async () => {
for await (const data of this.base.createValueStream({ limit: 1 })) {
return new Block(data as Buffer, this.#common);
}
})(),
this.getEarliest(),
this.#blockIndexes.get(LATEST_INDEX_KEY).catch(e => null)
]);

Expand Down
16 changes: 16 additions & 0 deletions src/chains/ethereum/ethereum/tests/forking/block.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ describe("forking", function () {
assert.deepStrictEqual(block.parentHash, remoteBlock.hash);
});

it("after initialization our earliest block should be the fork earliest block, parentHash should match", async () => {
const res = await request.post(URL).send({
jsonrpc: "2.0",
id: "1",
method: "eth_getBlockByNumber",
params: ["earliest", true]
});
const remoteBlock = JSON.parse(res.text).result;
const block = await provider.send("eth_getBlockByNumber", [
"earliest",
true
]);
assert.deepStrictEqual(parseInt(block.number), parseInt(remoteBlock.number));
assert.deepStrictEqual(block.hash, remoteBlock.hash);
});

//todo: reinstate this test after https://github.com/trufflesuite/ganache/issues/3616 is fixed
it.skip("should get a block from the original chain", async () => {
const res = await request.post(URL).send({
Expand Down

0 comments on commit 7ee7d4b

Please sign in to comment.