MetaMask / metamask-extension

:globe_with_meridians: :electric_plug: The MetaMask browser extension enables browsing Ethereum blockchain enabled websites
https://metamask.io
Other
12k stars 4.91k forks source link

MetaMask web3 instance doesn't return events/logs #2393

Closed bwheeler96 closed 6 years ago

bwheeler96 commented 7 years ago

I can't get logs from my contract. The following code works fine with the default web3 implementation that comes with truffle:

contract.MeEvent({}, { fromBlock: 0 }).get((err, data) => console.log(data))

But when I run the same code in a browser using the MetaMask version of web3, nothing happens. The promise never returns, and nothing is ever even sent to the network.

For example in the truffle web3 instance, the following requests are logged by testrpc:

eth_newFilter
eth_getFilterLogs

But when using the MetaMask implementation, nothing is even submitted to the testrpc instance.

I read the compatibility guide and am following it pretty closely. I can send transactions and call contracts just fine. I simple can not filter events.

The web3 version MetaMask is injecting is 0.20.2 and the version that truffle builds with is 0.16.0. Hopefully web3 doesn't have any breaking changes in minor versions

bwheeler96 commented 7 years ago

As an update to this issue: The problem was caused by faulty network switching within MetaMask

See this stackoverflow: https://ethereum.stackexchange.com/questions/28747/cant-retrieve-event-logs-with-metamask-web3

I quit my browser and reopened my site, then everything worked. I'm happy to help out on either:

  1. Adding logic to throw or warn when this happens (a timeout could probably be useful)
  2. Fixing the network switching issue

Cheers,

Brian

nteymory commented 7 years ago

Also having this same problem on version 3.11.2

To be a bit more specific, MetaMask doesn't return any new events after the specified block number only when watching a specific contract address. If I watch without specifying a contract address, everything works fine

This works as expected, for events before and after someBlockNumber:

web3.eth.filter({fromBlock: someBlockNumber}, function(e, r) {});

These work for events on someBlockNumber, but not for any events created after someBlockNumber:

someContract.SomeEvent({}, {fromBlock: someBlockNumber}, function (e, r) {}); web3.eth.filter({fromBlock: someBlockNumber, address: someContract.address}, function(e, r) {});

Overtorment commented 7 years ago

Having same issue, my Dapp is not receiving events anymore (using Ropsten). About 3 weeks ago everything was working fine.

bwheeler96 commented 7 years ago

@Overtorment various combinations of quitting and reopening your browser, toggling networks back and forth, and other hack voodoo wand waving seem to do the trick. Good luck

GuigsEvt commented 7 years ago

Is there any news about this issue ? Because I am still stuck with Metamask not getting any events from my contracts..

nteymory commented 7 years ago

Still having the same problem on 3.12.0

GuigsEvt commented 7 years ago

Do you know if it is working on older version ?

pipex commented 7 years ago

I have the same issue. Events are not being received by my application when using metamask (it works fine using Web3 connected to local RPC or Mist). It does not matter if I'm using one of the test networks or I'm connected to a local RPC server through the extension.

rawadrifai commented 6 years ago

Is there a version of metamask that resolves this issue? Quitting and restarting my browser didn't do it. p.s. it works just fine without metamask (fallback to local node)

tmashuang commented 6 years ago

@rawadrifai try version 3.11.1 you would have to load it manually into the extensions list and there might be some other bugs in it as well. This was the version that fixes events/logs but introduced basic use errors.

rawadrifai commented 6 years ago

I have 3.12.0 and it's working now. thanks.

johncpalmer commented 6 years ago

I'm having a similar issue. If I set the fromBlock to be the block when my contract was created, I do not get any events back. However, if I use a block that is several thousand before the block when my contract was created, it magically works. Anyone know why? Very weird.

danfinlay commented 6 years ago

that bug was caused in part by us switching our filter polyfill logic to this module, if you can find the issue in that, you’d fix it in MetaMask: https://github.com/kumavis/eth-json-rpc-filters

rawadrifai commented 6 years ago

Guys we need to get this out of the chrome extension.. it's not very practical. Do you guys have progress on that?

kumavis commented 6 years ago

@rawadrifai you reported that its working on 3.12.0, but your latest comment suggests you are still having a problem - what are you experiencing

I have 3.12.0 and it's working now. thanks.

rawadrifai commented 6 years ago

@kumavis it's very flaky to be honest, especially with events. My last comment was asking for putting the functionality outside of a chrome extension. Maybe a native macOS and windows app?

We are developing dapps right now, and the metamask adoption is a limitation for many people. I don't know if something is cooking over at metamask, but I would think of a different solution that can operate in the background. Username/password that map to a keypair .. maybe.. and you can integrate that in your app. The main goal basically is not have the end user authenticate outside the app (the extension). I wish I had more clarity on the solution in my head.

buhrmi commented 6 years ago

Hi there,

I'm also having some issues with events in 3.12.0. Just trying to show a simple notification when a token has been transferred.

My code looks like this:

contract.events.Transfer({
  filter: {_to: myAddress}
})
.on('data', (event) => {
  console.log(event)
})

(repo: https://github.com/buhrmi/nuxt-dapp/blob/master/store/index.js#L58, contract i'm trying to watch: https://rinkeby.etherscan.io/token/0x695d5f6060a92d730382dd06e8c3fb1d4012a07d)

But I don't see any events appearing on the console even though the transaction has been mined. Is it a problem with my code? Any help would be appreciated. Using getPastEvents I get the correct events, but I don't want to add polling.

danfinlay commented 6 years ago

Could this be related to https://github.com/MetaMask/provider-engine/issues/188 ?

buhrmi commented 6 years ago

Okay, when I run it this way:

contract.events.MyEvent({..}, function(err, ev) {
  console.error(err)
}

I get Error: The current provider doesn't support subscriptions: MetamaskInpageProvider. Seems to be duplicate of https://github.com/MetaMask/metamask-extension/issues/2601

Is there something I can do to help out with that?

danfinlay commented 6 years ago

@buhrmi That is https://github.com/MetaMask/metamask-extension/issues/2350 that you’re experiencing, I think it’s different from this one. Could be fixed by writing a websocket subprovider, or worked around by using a pre-1.0 web3.js, or ethjs instead.

buhrmi commented 6 years ago

@danfinlay thanks. obviously getting it to work nicely together with web3.js 1.0 is what I'd prefer. Any starting point I should look at in order to implement it (only the websocket part, that is)? Not sure what a subprovider is

traycho-zz commented 6 years ago

I want to report my env. Using web3 1.0 , ropsten events are not fired. I tried using the ZeroClientProvider, the events are received but you have to implemented additional signer, metamask popup is not fired. If anybody has tried to used this provider and successfully sign transaction from metamask wallet let me know.

As per comment fom @danfinlay probably web3 1.0 is not the best to be used in this shape. Let's hope devs will fix this pretty soon.

danfinlay commented 6 years ago

To be clear, this issue is not about web3 1.0 compatibility. This is clear from the very first message. This issue is about events/logs being unreliable even with pre-web3 1.0. We don't have great reproduction steps for this at the moment, and the reproduction steps we do have are inconsistent in their results, but @kumavis has been doing some work on this issue.

If you're here to report that web3 1.0 doesn't work with MetaMask, please just +1 issue #2350, so you don't clutter this discussion, which should be investigating a different bug.

traycho-zz commented 6 years ago

@danfinlay I fully agree with your comment my mistake. I tried yesterday to use two web3 instances one with the ZeroClientProvider (only to receive events) and one coming from the metamask plugin. Do you think this could be used as workaround ?

masonforest commented 6 years ago

Hey Metamask team!

Just adding what I've found. Hopefully it'll be helpful.

Here's a JSFiddle of a testcase I came up with: https://jsfiddle.net/431m51ky/6/

When I visit that page with MetaMask enabled on mainnet and open the console I only see "starting app..." even after > 5 minutes. I'd expect to see alternating null and block hashes being printed.

One thing I noticed is that when I switch networks (from mainnet to ropsten for example and then back again) it starts printing block hashes as expected:

starting app...
(index):65 null
(index):66 0xdcb19f74eeb1438228ff56404530059968196b01df404f9729724f0288ed6391
(index):65 null
(index):66 0xa470f54ab8286e3d0fefcf575c64284d1e2db41d0f5dc14c0958bb465d20ea90
(index):65 null
(index):66 0x41e9b4404da54f8e4a3a2593e6d6f9ad69d3b4e38e0e81527f2566ae60691b51

Chrome Version: 62.0.3202.94 (Official Build) (64-bit) Metamask Version: 3.12.0

Thanks!

etheroji commented 6 years ago

Also seeing this in MetaMask 3.12.0

danfinlay commented 6 years ago

On our Gitter, a few people have reported this.

@andrejc wrote:

It's been happening a lot in an app that we built (http://melon.email). One reliable way to reproduce it is to open the app with Metamask set to Kovan, then switch to Mainnet, then switch back to Kovan and then continue through registration process

@yippee-ki-yay wrote:

Here's a small video showing the issue, at the end when I refresh it should automatically signed me in (but metamask doesnt fetch that latest register event even though it is on the blockchain) https://app.hyfy.io/share/abASGiqdhCU/#!/player

danfinlay commented 6 years ago

An interesting lead from @andrejc is that just switching the provider several times gets this issue. That may imply that our filter subprovider is not resetting correctly on provider change.

draconnus commented 6 years ago

Are there any updates on this issue? Its still there in latest version

eloudsa commented 6 years ago

I confirm that the problem is still there in 3.12.1. I have tried all workaround (disable/enable extensions, switch network, etc.), without success. I'm using dev environment deployed on localhost (Truffle Develop 4.0.1 or Ganache 1.0.1).

nteymory commented 6 years ago

I can also confirm that this still does not work in 3.12.1. However, I have discovered a workaround:

web3.eth.filter({address: <contract address>.toLowerCase(), fromBlock: fromBlock, toBlock: 'latest', topics: [<event address>.toLowerCase()]}, ...);

The toLowerCase() calls are required. Could this be a hint to the cause of the problem?

dabruhce commented 6 years ago

I also confirm @ 3.13.2

Fetching events works sometimes, but not often. Bouncing, and switching provider have fixed the issue a few times, but doesn't seem to fix it reliably.

karvex commented 6 years ago

I can confirm that 3.13.2 does not work with events/logs. I have tried to use the log both instantiating with EthJS and Web3.

old way : var localWeb3 = new Web3(window.web3.currentProvider) new way : const eth = new Eth(window.web3.currentProvider);

danfinlay commented 6 years ago

@karvex

Did you try reloading the page?

karvex commented 6 years ago

Hey @danfinlay! You are completly correct. Works after restarting my webbserver. Gonna try more and see the exact behaviour.

dabruhce commented 6 years ago

I could not make events work reliably using the metamask provider. Nor pin down why/how it works/doesn't. I'm not sure if it should or is suppose to be used for events tbh.

As a workaround, I set up a full node of my own on AWS and added another provider in my code that is used for events.

e.g.
const web3_provider = 'http://$mynode:8545';
let _web3 = new Web3();
_web3.setProvider(new Web3.providers.HttpProvider(web3_provider));

Also, notice there isn't an easy way to create a full node quickly.

There's docker-geth-lb but the geth instance takes ages to sync and I was having trouble with the parity instance dropping out of warp/snapshots at that version. Also, since its docker, the versions are not configurable. Needs better disk to keep in sync with the blockchain too.

There's a community AMI for parity, but if you want to use a different version you are out of luck.

Setting up an Ubuntu version manually is fairly straightforward and faster than building from source. Takes about 15-25 minutes to be up and completely in sync.

It's a bit slow and not ideal as it needs to build parity from source and sync the blockchain, but good if you want to change the parity version in a testing environment.

Properly configured this could be up and synced in about 10 minutes so I might add some features to make it faster and autoscale. Very hacked up, but its "usable" as a very crude workaround that should work in most AWS regions if you are willing to wait for an hour.

cloudformation-ethereum-parity-fullnode

also have this from earlier this year which is dockerized and faster, but would need alterations to run on ropsten. Up in about 10-20 minutes. eth-ec2-cloudformation-docker

nteymory commented 6 years ago

@tkntobfrk It appears as though there are at least two bugs related to this right now that manifest the same way:

  1. If you change your selected network with the metamask plugin, logs will completely stop working. Closing and reopening your tab won't fix it. Disabling and re-enabling the extension will not fix it. The only fix is to completely close all your chrome tabs and restart chrome. This does fix the problem.
  2. If you watch a contract event, you will not get any logs, regardless of whether you triggered the above bug or not. I suggested a work around above, and I can confirm it has consistently worked for me. From what I can tell, the problem simply seems to be a matter of casing on the contract address.

EDIT:

  1. Related but not exactly the same, recently (I think as of 3.13.2), the Kovan network on metamask seems to have gone haywire. This results in unpredictable log behaviour. So, I would avoid it for testing right now. See this issue: #2728.
ghost commented 6 years ago

I can confirm that Metamask 3.13.2 does not work with events/logs. For example at etheroll 'latest results' (events) loads on initial page load, but 'latest results' (events) do not load as the events occur if you stay on the page. This used to work fine in previous versions of Metamask.

smarx commented 6 years ago

Repro I had:

  1. Load a page that sets up an event filter (myContract.MyEvent(...)).
  2. Switch networks, and then switch back.
  3. Generate a matching event.
  4. Observe that the event handler function is never called.

Changing this line:

https://github.com/MetaMask/metamask-extension/blob/31564e0a86072ae2b49923dcf28983075308c432/app/scripts/metamask-controller.js#L440

to use this.provider._blockTracker instead fixed the issue for me.

I have very little understanding of this code, so I have no idea if my "fix" is at all correct. I tried to run npm test, but it didn't look like anything happened. My only testing was manual via a trivial DApp in the browser.

I suspect that the fix is hiding a more fundamental issue around the relationship between provider engines, block trackers, and filter middlewares. During my ~debugging~ fumbling about, it appeared to me that old event filters were hanging around longer than I would have expected (i.e. after switching networks), so I worry that the appropriate cleanup isn't happening.

I'd be happy to provide the simple DApp that I tested with or any other information that might help, so please don't hesitate to ask. I hope that even if this fix isn't the right one, it helps lead to a proper fix.

stevedub commented 6 years ago

Confirmed that @nt85 's workaround of using toLowerCase() on the contract address does allow for events to be read. Thanks brother!

karvex commented 6 years ago

I am using Metamask 3.13.2, ethereum-testrpc and EthJS. I can use the getLogs/getBlockByNumber without any problem, but the functions below doesn't work at all:

eth.filter.Filter() eth.filter.PendingTransactionFilter() eth.newFilter() contractInstance.< MyEvent > ()

Any idea? Is it Metamask or EthJS?

danfinlay commented 6 years ago

@karvex I believe this is an unrelated issue. EthJS has had some open events issues for quite a while, it's probably its single greatest weak point.

surfer77 commented 6 years ago

Anyone found a fix for the event not login? I am trying it on the ropsten network, all methods of my contract work well but when trying to get events they never fire.

smarx commented 6 years ago

@surfer77 As a workaround for the two issues in this thread, make sure your contract address is lowercase and restart the browser (with MetaMask already on Ropsten).

For actual fixes, see https://github.com/kumavis/eth-json-rpc-filters/issues/4 and https://github.com/MetaMask/metamask-extension/issues/2393#issuecomment-351291768, but I believe neither has actually been patched in MetaMask yet.

karvex commented 6 years ago

@smarx , but you are using testnet (Ropsten). Your workaround doesn't work with testrpc?

smarx commented 6 years ago

@karvex The question I was responding to was about Ropsten. In my testing, the same thing (restarting the browser while already pointing to the desired network) works with ganache-cli/testrpc.

kumavis commented 6 years ago

fixed the contract address case sensitivity issue identified by @smarx (not published to chrome store yet)

nteymory commented 6 years ago

I can confirm that this issue appears fixed in 3.13.3

smarx commented 6 years ago

The issue where switching networks leads to lost events still repros for me in 3.13.3. I also would have expected someone to close this issue if it were resolved. @danfinlay any update on this issue?

ChainSafeSystems commented 6 years ago

We have noticed this bug keeps appearing in newer versions. Our solution:

  1. Switch to desired Network
  2. Close chrome and re-open

We believe that there may be an issue if you switch networks while it's trying to connect (i.e. sometimes it takes a while to load and you switch) and part of the code hangs without realizing you switched. This would cause metamask to look for events from the contract address on another network.