Skip to content

Commit 566ef9e

Browse files
authored
Merge pull request trufflesuite#4274 from trufflesuite/develop
chore(release): publish v7.7.6
2 parents e0bb8e3 + ff0a295 commit 566ef9e

File tree

5 files changed

+174
-112
lines changed

5 files changed

+174
-112
lines changed

src/chains/ethereum/ethereum/src/api.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -1274,14 +1274,12 @@ export default class EthereumApi implements Api {
12741274
@assertArgLength(1)
12751275
async eth_getBlockTransactionCountByHash(hash: DATA) {
12761276
const { blocks } = this.#blockchain;
1277-
const blockNum = await blocks.getNumberFromHash(hash);
1278-
if (!blockNum) return null;
1279-
1280-
const rawBlock = await blocks.getRawByBlockNumber(Quantity.from(blockNum));
1281-
if (!rawBlock) return null;
1282-
1283-
const [, rawTransactions] = decode<GanacheRawBlock>(rawBlock);
1284-
return Quantity.from(rawTransactions.length);
1277+
const block = await blocks
1278+
.getByHash(hash)
1279+
.catch<Block>(_ => null);
1280+
if (!block) return null;
1281+
const transactions = block.getTransactions();
1282+
return Quantity.from(transactions.length);
12851283
}
12861284

12871285
/**

src/chains/ethereum/ethereum/src/blockchain.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -1054,11 +1054,22 @@ export default class Blockchain extends Emittery<BlockchainTypedEvents> {
10541054
process.nextTick(this.emit.bind(this), "pendingTransaction", transaction);
10551055
}
10561056

1057-
const hash = transaction.hash;
1058-
if (this.#isPaused() || !this.#instamine) {
1057+
const { hash } = transaction;
1058+
const instamine = this.#instamine;
1059+
if (!instamine || this.#isPaused()) {
10591060
return hash;
10601061
} else {
1061-
if (this.#instamine && this.#options.miner.instamine === "eager") {
1062+
const options = this.#options;
1063+
// if the transaction is not executable, we just have to return the hash
1064+
if (instamine && options.miner.instamine === "eager") {
1065+
if (!isExecutable) {
1066+
// users have been confused about why ganache "hangs" when sending a
1067+
// transaction with a "too-high" nonce. This message should help them
1068+
// understand what's going on.
1069+
options.logging.logger.log(
1070+
`Transaction "${hash}" has a too-high nonce; this transaction has been added to the pool, and will be processed when its nonce is reached. See https://github.com/trufflesuite/ganache/issues/4165 for more information.`
1071+
);
1072+
}
10621073
// in eager instamine mode we must wait for the transaction to be saved
10631074
// before we can return the hash
10641075
const { status, error } = await transaction.once("finalized");
@@ -1067,7 +1078,7 @@ export default class Blockchain extends Emittery<BlockchainTypedEvents> {
10671078
// vmErrorsOnRPCResponse is enabled.
10681079
if (
10691080
error &&
1070-
(status === "rejected" || this.#options.chain.vmErrorsOnRPCResponse)
1081+
(status === "rejected" || options.chain.vmErrorsOnRPCResponse)
10711082
)
10721083
throw error;
10731084
}

src/chains/ethereum/ethereum/tests/api/eth/greedyInstamining.test.ts

-100
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import getProvider from "../../helpers/getProvider";
2+
import assert from "assert";
3+
import { Logger } from "@ganache/ethereum-options/typings/src/logging-options";
4+
5+
describe("api", () => {
6+
describe("eth", () => {
7+
describe("instamine modes (eager/strict)", () => {
8+
describe("strict", () => {
9+
it("when in strict instamine mode, does not mine before returning the tx hash", async () => {
10+
const provider = await getProvider({
11+
miner: { instamine: "strict" }
12+
});
13+
const accounts = await provider.send("eth_accounts");
14+
15+
const hash = await provider.send("eth_sendTransaction", [
16+
{
17+
from: accounts[0],
18+
to: accounts[1],
19+
value: "0x1"
20+
}
21+
]);
22+
const receipt = await provider.send("eth_getTransactionReceipt", [
23+
hash
24+
]);
25+
assert.strictEqual(receipt, null);
26+
});
27+
});
28+
29+
describe("eager", () => {
30+
it("mines before returning the tx hash", async () => {
31+
const provider = await getProvider({
32+
miner: { instamine: "eager" }
33+
});
34+
const accounts = await provider.send("eth_accounts");
35+
36+
const hash = await provider.send("eth_sendTransaction", [
37+
{
38+
from: accounts[0],
39+
to: accounts[1],
40+
value: "0x1"
41+
}
42+
]);
43+
const receipt = await provider.send("eth_getTransactionReceipt", [
44+
hash
45+
]);
46+
assert.notStrictEqual(receipt, null);
47+
});
48+
49+
it("log a message about future-nonce transactions in eager mode", async () => {
50+
let logger: Logger;
51+
const logPromise = new Promise<boolean>(resolve => {
52+
logger = {
53+
log: (msg: string) => {
54+
const regex =
55+
/Transaction "0x[a-zA-z0-9]{64}" has a too-high nonce; this transaction has been added to the pool, and will be processed when its nonce is reached\. See https:\/\/github.com\/trufflesuite\/ganache\/issues\/4165 for more information\./;
56+
if (regex.test(msg)) resolve(true);
57+
}
58+
};
59+
});
60+
61+
const provider = await getProvider({
62+
logging: { logger },
63+
miner: { instamine: "eager" },
64+
chain: { vmErrorsOnRPCResponse: true }
65+
});
66+
const [from, to] = await provider.send("eth_accounts");
67+
const futureNonceTx = { from, to, nonce: "0x1" };
68+
const futureNonceProm = provider.send("eth_sendTransaction", [
69+
futureNonceTx
70+
]);
71+
72+
// send a transaction to fill the nonce gap
73+
provider.send("eth_sendTransaction", [{ from, to }]); // we don't await this on purpose.
74+
75+
const result = await Promise.race([futureNonceProm, logPromise]);
76+
// `logPromise` should resolve before the the hash gets returned
77+
// (logPromise returns true)
78+
assert.strictEqual(result, true);
79+
80+
// now our nonce gap is filled so the original tx is mined
81+
const receipt = await provider.send("eth_getTransactionReceipt", [
82+
await futureNonceProm
83+
]);
84+
assert.notStrictEqual(receipt, null);
85+
});
86+
87+
it("handles transaction balance errors, callback style", done => {
88+
getProvider({
89+
miner: { instamine: "eager" },
90+
chain: { vmErrorsOnRPCResponse: true }
91+
}).then(async provider => {
92+
const [from, to] = await provider.send("eth_accounts");
93+
const balance = parseInt(
94+
await provider.send("eth_getBalance", [from]),
95+
16
96+
);
97+
const gasCost = 99967968750001;
98+
// send a transaction that will spend some of the balance
99+
provider.request({
100+
method: "eth_sendTransaction",
101+
params: [
102+
{
103+
from,
104+
to
105+
}
106+
]
107+
});
108+
109+
// send another transaction while the previous transaction is still
110+
// pending. this transaction appears to have enough balance to run,
111+
// so the transaction pool will accept it, but when it runs in the VM
112+
// it won't have enough balance to run.
113+
provider.send(
114+
{
115+
jsonrpc: "2.0",
116+
id: "1",
117+
method: "eth_sendTransaction",
118+
params: [
119+
{
120+
from,
121+
to,
122+
value: `0x${(balance - gasCost).toString(16)}`
123+
}
124+
]
125+
},
126+
(e, r) => {
127+
assert(
128+
e.message.includes(
129+
"sender doesn't have enough funds to send tx"
130+
)
131+
);
132+
assert.strictEqual(e.message, (r as any).error.message);
133+
assert.strictEqual((r as any).error.code, -32000);
134+
assert.strictEqual(
135+
typeof (r as any).error.data.result,
136+
"string"
137+
);
138+
done();
139+
}
140+
);
141+
});
142+
});
143+
});
144+
});
145+
});
146+
});

src/chains/ethereum/ethereum/tests/forking/block.test.ts

+7
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,12 @@ describe("forking", function () {
8484
const block = await provider.send("eth_getBlockByNumber", ["0x0", true]);
8585
assert.deepStrictEqual(block, block0);
8686
});
87+
88+
it("should get transaction count by hash from the original chain", async () => {
89+
const block = await provider.send("eth_getBlockByNumber", ["0xB443", true]);
90+
const blockTransactionCountByHash = await provider.send("eth_getBlockTransactionCountByHash", [block.hash]);
91+
assert.deepStrictEqual(block.transactions.length, parseInt(blockTransactionCountByHash));
92+
});
93+
8794
});
8895
});

0 commit comments

Comments
 (0)