I write a demo DApp website with this javascript
const web3 = new Web3(ethereum);
const contractAddr = "0x0Aa27e4B13D5c08A8767B36a0ACb76ED4549B7EA";
const abi = ...;
let inst = new web3.eth.Contract(abi, contractAddr);
web3.eth.subscribe('logs', {
address: contractAddr,
}, function (error, result) {
if (!error)
console.log(result);
else
console.log("default:", error);
})
.on("connected", function (subscriptionId) {
console.log(subscriptionId);
})
.on("data", function (log) {
console.log("data:", log);
})
.on("changed", function (log) {
console.log("changed:", log)
}).on("error", function (log) {
console.log("err:", log);
});
In the code I use ethereum
(which is window.ethereum
provided by MetaMask) as the Provider for Web3.js.
My MetaMask is connected to a private blockchain called node1
using Geth on localhost:8545
. In the meantime I have another Geth node called node2
.
At the beginning, node1
and node2
were not connected. I sent and mined a transaction to node1
to the contract at contractAddress
which would emit events and I indeed got console logs in the browser as a result of my subscription to 'logs'.
Then I let node2
mine more blocks than node1
and after that, I connected them. This will trigger node1
chain reorganization. After reorg, the reverted transaction was left in the txPool and I didn't mine any more blocks.
As is specified in web3.js documentation, I expected console.log("changed:", log)
to be executed but it didn't.
At the same time, I also used low-level Json-rpc method eth_getFilterChanges
and did get a log with "removed": true
field, which means the transaction was indeed reverted.
I think web3.js should have notice this and execute on('changed')
callback. But why does web3.js not work here? Since web3.js cannot subscribe logs directly using HTTP ethereum provider, and MetaMask uses HTTP connection to ethereum, does this problem have something to do with MetaMask?
BTW: I'm using web3.js v1.2.6