Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workaround transactions recreation issue #1377

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,8 @@ Hardhat Network's forking functionality only works with blocks from at least spu
blockOpts: { calcDifficultyFromHeader: parentBlock.header },
});

const transactions = [];

try {
const traces: GatherTracesResult[] = [];

Expand All @@ -1053,6 +1055,7 @@ Hardhat Network's forking functionality only works with blocks from at least spu
if (tx.gasLimit.gt(blockGasLimit.sub(blockBuilder.gasUsed))) {
txHeap.pop();
} else {
transactions.push(tx);
const txResult = await blockBuilder.addTransaction(tx);
const { txReceipt } = await generateTxReceipt.bind(this._vm)(
tx,
Expand All @@ -1078,6 +1081,15 @@ Hardhat Network's forking functionality only works with blocks from at least spu

const block = await blockBuilder.build();

// We replace the block's transactions with the actual ones,
// as the block builder recreates them, turning fake transactions
// into real ones.
//
// IMPORTANT: this workaround only works because while BlockBuilder#addTransaction
// recreates the transactions you pass it, it actually runs yours.
block.transactions.splice(0);
block.transactions.push(...transactions);

await this._txPool.updatePendingAndQueued();

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
numberToRpcQuantity,
rpcQuantityToNumber,
} from "../../../../../src/internal/core/jsonrpc/types/base-types";
import { expectErrorAsync } from "../../../../helpers/errors";
import { ALCHEMY_URL } from "../../../../setup";
import { workaroundWindowsCiFailures } from "../../../../utils/workaround-windows-ci-failures";
import { assertInvalidArgumentsError } from "../../helpers/assertions";
Expand Down Expand Up @@ -62,17 +63,46 @@ describe("Hardhat module", function () {
},
]);

// The tx's msg.sender should be correct during execution

// msg.sender assertion contract:
//
// pragma solidity 0.7.0;
//
// contract C {
// constructor() {
// require(msg.sender == 0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E);
// }
// }
const CODE =
"0x6080604052348015600f57600080fd5b5073c014ba5ec014ba5ec014ba5ec014ba5ec014ba5e73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614605b57600080fd5b603f8060686000396000f3fe6080604052600080fdfea26469706673582212208048da4076c3540ec6ad48a816e6531a302449e979836bd7955dc6bd2c87a52064736f6c63430007000033";

await this.provider.send("hardhat_impersonateAccount", [
impersonatedAddress,
]);

await this.provider.send("eth_sendTransaction", [
await expectErrorAsync(() =>
deployContract(this.provider, CODE, DEFAULT_ACCOUNTS_ADDRESSES[0])
);

// deploying with the right address should work
await deployContract(this.provider, CODE, impersonatedAddress);

// Getting the tx through the RPC should give the right from

const tx = await this.provider.send("eth_sendTransaction", [
{
from: impersonatedAddress,
to: DEFAULT_ACCOUNTS_ADDRESSES[0],
value: "0x10",
to: impersonatedAddress,
},
]);

const receipt = await this.provider.send(
"eth_getTransactionReceipt",
[tx]
);

assert.equal(receipt.from, impersonatedAddress.toLowerCase());
});

it("lets you deploy a contract from an impersonated account", async function () {
Expand Down