web3-1.0.0-beta.55 (also tested beta.52) subscribes to newHeads _after_ sending the transaction, which means web3 may miss emitted newHeads notifications. While it is unlikely for this race condition to be a problem on mainnet, or even test nets, it is pretty much guaranteed to be a problem when testing against Ganache.
When a sent transaction is mined via await web3.eth.sendTransaction, web3 should request the transaction's receipt and resolve the promise.
I suspect what happens is:
web3 sends the transaction to GanachetransactionHashweb3 receives the transactionHash then sends a newHeads subscription to GanachenewHeads notificationnewHeads subscription.web3 waits for forever.Previous versions (like beta.37 don't have this issue)
Full reproduction:
Run:
mkdir test
cd ./test
npm init -y
npm install [email protected] [email protected] -E
Save this code as test.js:
const Ganache = require("ganache-core");
const Web3 = require("web3");
const server = Ganache.server();
server.listen(8545, async () => {
const provider = new Web3.providers.WebsocketProvider("ws://localhost:8545");
const options = { transactionConfirmationBlocks: 1 };
const web3 = new Web3(provider, null, options);
const accounts = await web3.eth.getAccounts();
const transactionReceipt = await web3.eth.sendTransaction({ from: accounts[0], to: accounts[1], value: 1 });
// never gets here.
console.log(transactionReceipt);
// shut down the Ganache server
server.close();
});
Run:
node test.js
The application hangs.
A clumsy workaround (passer-bys: do NOT use this in your testing code!):
const Ganache = require("ganache-core");
const Web3 = require("web3");
const server = Ganache.server();
server.listen(8545, async () => {
const provider = new Web3.providers.WebsocketProvider("ws://localhost:8545");
const options = { transactionConfirmationBlocks: 1 };
const web3 = new Web3(provider, null, options);
const accounts = await web3.eth.getAccounts();
const transactionReceiptPromise = web3.eth.sendTransaction({ from: accounts[0], to: accounts[1], value: 1 });
// web3 newHeads race-condition workaround:
await new Promise(resolve => setTimeout(resolve, 500)); // 500 is arbitrary
await web3.currentProvider.send("evm_mine"); // force another block to be mined
const transactionReceipt = await transactionReceiptPromise;
// This works now!
console.log(transactionReceipt);
// shut down the Ganache server
server.close();
});
1.0.0-beta.5510.16.0[email protected]Deactivating of automine is currently the workaround for it:

I will add an additional check before the newHeads subscription gets started for being compatible with Ganache.
Most helpful comment
Deactivating of automine is currently the workaround for it:

I will add an additional check before the
newHeadssubscription gets started for being compatible with Ganache.