Skip to content
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

I receive the same data from network twice after connection hang up error! #52

Closed
BartolomeoItaliano opened this issue Dec 30, 2021 · 12 comments

Comments

@BartolomeoItaliano
Copy link

BartolomeoItaliano commented Dec 30, 2021

Hi!

I have got small dapp which tracks transactions on EOS network and it is very important for me to not receive over your library duplicated data and I am pretty sure I do.

After library hangs connection for a moment with error:

{
  type: 'error',
  errors: [
    {
      message: 'graphql: hammer search result: rpc error: code = Unknown desc = Internal server error (trace_id: 
      56c9fe4be60757f244e32b37e56ce125)'
    }
  ],
  terminal: true
}

I receive the same data I already received before error being thrown.
This is very dangerous for my app. I plan to receive and send from my contract money in form of EOS and other tokens to users.
Please advice what to do.

@maoueh
Copy link
Contributor

maoueh commented Jan 1, 2022

Please provide full logs so I can see more what is happening.

@BartolomeoItaliano
Copy link
Author

It happens very rarely once per few days or even rarer I will try to provide you proper logs, but it can take.

@BartolomeoItaliano
Copy link
Author

BartolomeoItaliano commented Jan 12, 2022

dfuse-issue-logs.txt

I think I already see the problem in logs when this Internal server error is called stream is restarted with the initial cursor.
Please confirm, if I am right and if you gonna handle it somehow or what can I do on my side now.

@matthewdarwin
Copy link

You need to send the latest cursor you received on reconnect.

@BartolomeoItaliano
Copy link
Author

But reconnect is automatic. It's your library which handles it.
How can I handle it?

@BartolomeoItaliano
Copy link
Author

I know I might provided you with logs in poor format.
Here I attach them in txt file.
dfuse-issue-logs.txt

@maoueh
Copy link
Contributor

maoueh commented Jan 13, 2022

@BartolomeoItaliano Three things is required for proper tracking of chain and ensure no duplicated trx is found:

  • It's required to mark the cursor on the stream to save the active cursor, the active cursor is used to re-connect
  • It's required to have a $cursor variable in the GraphQL document, it you have an active cursor, it's automatically used and passed to the GraphQL variables
  • If you deal with head blocks that can fork, you need to deal with the undo: true flag which is set when a transaction is part of a forked block and must be reverted.

From the logs you have, you seems to have the cursor inlined inside your GraphQL document:

2022-01-11T16:18:02.393Z dfuse:socket:graphql Sending message { id: 'dc-cff18860357fa-0', type: 'start', payload: { query: '\n' + '             
 subscription {\n' + '                
 searchTransactionsForward(query: "receiver:eosio.token action:transfer data.to:eosgamesdepo",\n' + '                 
 cursor: "yzs7YNIzWmXlCrbClmtHQ_e7JpQ9BV9vUgPlIBEVg97_9HWW2J6uAjAgPBXVkP_53EPrS1yk1o7IF3l_9pZU79Xvw7wyuHU4FHMvl4_sqby6e_umbV9KIr1mV-2EMN-NCDveYAzycrUF",\n' + ' 
                 irreversibleOnly: false) {\n' + '                  cursor\n' + '                  undo\n' + '                  trace {\n' + '                  
                   matchingActions {\n' + '                      json\n' + '                    }\n' + '                  }\n' + '                }\n' + '            
                    }\n' + '            ', variables: { cursor: '' } } } through socket.
                    ```
                    
You should do something more like this:

subscription($cursor: String!) { searchTransactionsForward(query: "...", cursor: $cursor) ...


This should work as expected and re-connect at the right location.

@maoueh
Copy link
Contributor

maoueh commented Jan 13, 2022

See the commit function which is called when each data is received and and calls mark here

@BartolomeoItaliano
Copy link
Author

BartolomeoItaliano commented Jan 15, 2022

One more question, in case I use query with cursor provided like this:
subscription($cursor: String!) { searchTransactionsForward(query: "...", cursor: $cursor) ...

How can I provide query with initial cursor when I am restarting whole appllication?

@BartolomeoItaliano
Copy link
Author

Ok, here I found some good example:
https://docs.dfuse.io/ethereum/public-apis/tutorials/searching-transactions/

@maoueh
Copy link
Contributor

maoueh commented Jan 17, 2022

subscription($cursor: String!) { searchTransactionsForward(query: "...", cursor: $cursor) ...

You pass it in your initial variables. See https://github.com/dfuse-io/client-js/blob/master/examples/advanced/common/graphql-never-miss-a-beat.ts#L152

@BartolomeoItaliano
Copy link
Author

BartolomeoItaliano commented May 6, 2022

For people with this problem in the future.
Here is proper stream setup:

https://github.com/dfuse-io/client-js/blob/HEAD/examples/basic/eosio/stream-transfers-graphql.ts

Like @maoueh said you need to set initial parameters and then after each message mark their change, otherwise still initial params would be used for reconection:
stream.mark({ cursor: data.cursor })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants