solana: Duplicate Signature Being Returned When Using `getSignaturesForAddress` method on web3
Problem
I’ve an internal project which makes requests to a private Solana RPC to get transaction signatures every few seconds. Every poll, I get new signatures with getSignaturesForAddress, sort them in descending order by blocktime (or by slot if blocktime is null). In the next poll, I make the query for getSignaturesForAddress again with until parameter set as the signature with highest block time from the previous poll. This should return me new signatures which have happened until that signature.
Now, multiple signatures can have the same blocktime. Does web3 guarantee that those signatures with the same blocktime are not returned?
We’ve been seeing duplicate signatures in next polls with this approach. Here’s the last sample run where duplicates happened:
- Made a request to get new signatures until signature 54nQjreuwRmawqo5xzuneGvfCYEDatgnGdQ288wK65VGvcnEM5RZfjRiSomRkP7oSgDZeKp6PnChezTaTtZZCKXu (block time - 1650132790). Signatures were returned.
- Then made another request to get signatures until 5oexSPS6EXp2HJpu9jw51Uj6fvNcsyag4jPByFveL1qCe9aapv4cpN78wAkTnrjhtqWkmfzcK3r99eH4KqRGY2ch (block time - 1650132809). Notice that the blocktime is after the signature from above.
- The signature 54nQjreuwRmawqo5xzuneGvfCYEDatgnGdQ288wK65VGvcnEM5RZfjRiSomRkP7oSgDZeKp6PnChezTaTtZZCKXu was in the returned results of the second query again which I didn’t expect.
Is this a bug or is this the intended behaviour? Any explanation would be very appreciated!
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 2
- Comments: 20 (8 by maintainers)
I think that I’m running into something similar to this. Sometimes,
getSignaturesForAddresswill return signatures that are actually before my until parameter. This makes pagination pretty difficult.Anecdotally, this happens when I’m fetching transactions that are “near the tip” eg…polling for new transactions. I haven’t seen this happen when I’m backfilling older transactions.
I’m using the
"confirmed"finality parameter. Maybe I should be using the “finalized” parameter to avoid this? Also, I’m using a GenesysGo endpoint.Hmm yeah it must be an RPC problem, can you bring it up with them to debug?
Happy to help diagnose the issue, I’ve created this issue to come up with a solution to avoid this problem: https://github.com/solana-labs/solana/issues/24620
For “until” requests, the RPC node will collect signatures until it hits the “until” signature. When your script gets the following response…
The issue seems to be that the “until” signature is not found at all so the RPC node will just return the 1000 most recent signatures for an address. Note that the most recent block time for that response was “8:21:40 p.m.:130360512” which is actually not as recent as the block time from the previous response. So this leads me to believe that the your requests are being handled by two different RPC nodes and sometimes your request is handled by a node which hasn’t finalized as recent of a block as the other node.
I think the best recommendation I have for you is to ignore responses for data older than what you have already retrieved and retry later. Otherwise using a single RPC node should work ok
I’ve been able to reduce repro this in a small snippet. Here is a little bit of code that polls Raydium’s address for new transactions.
This loop will happily plug away and find new transactions as they come in and log the following output as expected:
However, about once every 30 minutes, there’s an anomaly, where a bunch of older transactions will get returned as follows. Notice the 1000 transaction results that all appear to be the same.
Real time follow up: I still experience the same thing using “finalized”.
Ok, if you are able to reproduce again, please sure the results and we can take a look