-
Notifications
You must be signed in to change notification settings - Fork 5k
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
WebsocketProvider with fromBlock
doesnt return events from the past
#3389
Comments
@frozeman - Could you help me with this please? I found your commit from 2016 :D where the part with deleting Here is the commit: 23f428b |
@VladoDemcak Thanks for opening and investigating - will look at this today along with #3379. |
@VladoDemcak I've tried to build a reproduction for this in #3391 but it looks like everything works... The case replicates what you've described here, (using Geth stable (1.9), mining at 2 second intervals):
The Travis CI output for it is here. Does that example +/- model your request correctly? |
i also have this issue of the in my case i'm connected to the Portis provider on Rinkeby, but i'm passing a |
@cgewecke Thanks for your effort. I've tested it on kovan network and it doesn't return any events from the past when I create subscription for I deployed my custom There are several transactions in multiple blocks eg: 1699289, 16992925, 16993448 ... (at least 6 blocks) I have found very interesting behavior please see below: Steps to reproduce the issue:
and nothing else
example.js: const Web3 = require('web3');
const abi = [
{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"constant": true,
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "subtractedValue",
"type": "uint256"
}
],
"name": "decreaseAllowance",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "addedValue",
"type": "uint256"
}
],
"name": "increaseAllowance",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
]
const web3 = new Web3("wss://kovan.infura.io/ws/v3/INFURA_KEY");
const run = async () => {
const contract = new web3.eth.Contract(abi, '0xaA8f1B72Ac1c9769D25a9251A982fb4a6c296Bf1');
// uncomment code below
// await contract.getPastEvents('Transfer', {
// fromBlock: 0,
// toBlock: 'latest'
// });
contract.events.Transfer({fromBlock: 0})
.on('data', (event) => console.log(event));
}
run()
.then(() => {
console.log("listening...")
}); |
I observe this problem on:
|
@VladoDemcak Are you able to provide a super simple example using just a node.js script and ganache (or as a mocha test)? Something similar to the tests we have in the test suite here? #3391 also worked for ganache on my end... Infura's websockets are known to be quite fragile. There are lots of dropped connections and sometimes swallowed errors. (A PR is open at #3190 to try to remedy this in several ways). Tbh, if you're interested in storing events for a deployed contract via Infura the most robust solution is likely to set up an interval poll, and run |
@cgewecke I will try to create some super simple example but everything is in Could you please verify/answer following:
I found it works when |
@VladoDemcak I haven't run a One way forward might be to express this problem in terms of Web3's E2E tests which try to be as minimal as possible...then work backwards to your specific case and identify the differences. You should be able to clone Web3, install and run the E2E client tests using the commands listed in the main For example:
|
@cgewecke Thanks. yes I saw the my current suspicion is that in
In my case I deploy my contract via truffle and the instance is created based on abi and
|
I've prepared repo where you should be able to replicate the problem. Please follow instructions in README. https://github.com/VladoDemcak/eth-subscribe-debug I think your tests work because there is the instance of contract which is used also for subscribing. And this instance has some attributes (or is in different state) which is necessary for subscription. Important thing is that I observe the issue with The interesting part is that when I execute It looks like there is a hidden implementation in On this link you can see 3 There are several differences between the contract objects. E.g working contracts (with prefix "working" in this gist ) are different in fields like: BUT when I compare non-working contract with working contract there are differences in fields: Next .. I will try to find more .... But please if you know how to fix this (e.g with some attribute or something) please let me know. ========== edit:even when i execute:
or
before calling subscription with |
@teawaterwire Can you share your code? |
Ai!! That's really weird. Thanks for making the repo, will take a look tomorrow and see if anything jumps out. |
@cgewecke were you able to replicate the issue on your side? |
@VladoDemcak Yes I was, thanks for making such a great reproduction. Still investigating and your suggestion about whether the socket is connected seems like it would make sense. However, I'm seeing the initial request for In sum, you cannot initiate an event subscription as the first communication you have with the client and get all the past logs as expected. Very mysterious, especially the different responses from the client...smh. |
Exactly! Thanks for re-testing. If you will find any solution let me know and I'll test it. Meanwhile I will try to do something as well. |
@VladoDemcak When I wrap the ...it works. It must be a race condition caused by latency setting up the initial Websocket connection. By the time the first request gets made, the param's been deleted. |
@cgewecke Thanks for this in-depth analysis, great 😄, will close here. |
@holgerd77 why did you close the issue? Are you guys going to fix it somewhere? |
@VladoDemcak Sorry, I might have misread the last comment from @cgewecke, will re-open for now. |
@holgerd77 @cgewecke Guys, I honestly appreciate all your effort you put into this. Do you have any plans to fix it any time soon? I am asking if we should stay with the |
@VladoDemcak I will open a PR with a fix today, but it may be a few weeks before Web3 is published again. Would probably use the work-around for the time being, sorry. |
@cgewecke @holgerd77 if i may ask I would have one question which is not exactly related to the issue but cannot find any answer. When I create subscription for e.g contract For Example.
Can I get the event ONLY after 5 confirmations? Is there any way how to achieve this functionality without creating custom queue for received events and computing number of confirmation blocks? |
Maybe I am facing the same issue as described here: #3379.
Current behaviour
When I am subscribed I get only events from last block. Eg if there are events in block 0,1,2,3 and I set
fromBlock
: 0 and the current block is 3 I get only events from block 3 and not from 0.Expected behaviour
Once I am subscribed and I specify
fromBlock
: 0, I should get all events from block 0, 1 ... latest.I've created the post on stackoverflow as well so more details about the problem I am facing is described here.
I am using
WebsocketProvider
andquorum-v2.4.0
andweb3js 1.2.6
. So I am connected like this:When I create subscription for my contract it looks like below. I specify
fromBlock
because I want to get all events from block 0 when I am creating subscription.However it doesn't return events from block 0 even though there are some events. It returns only the events from last block. So if current block is 10 and there was an event in block 9 it returns only this event but doesnt return event from block 8,7,6...0.
After some time of investigating the issue I have found there is a weird part of the implementation in subscription.js where
fromBlock
is removed withdelete
keyword. Check the snipped fromsubscription.js
below.Since this code deletes the
fromBlock
from params it is missing in WebsocketProvider.prototype.send.Because of this delete part the payload in send function in
WebsocketProvider
doesnt call RPC withfromBlock
parameter (request is withoutfromBlock
) and I assume it is considered aslatest
so it doesn't return events from past:After deleting
fromBlock
param the request looks like this:When I comment out the part where
fromBlock
is being deleted the payload is:and this second example correctly returns the events from block 0 not only the new.
The text was updated successfully, but these errors were encountered: