bnb-chain / go-sdk

Apache License 2.0
205 stars 97 forks source link

Websocket subscription gets closed after a few minutes #187

Closed tajelp closed 1 year ago

tajelp commented 1 year ago

Hello there, I am trying to get transactions data in real-time with the official go sdk. Everything is okay except for the fact that the wss seems to get interrupted after a few minutes, so I am not able to get new data anymore and I would have to constantly restart the script. Here's the relevant code:

package main

import (
    "encoding/base64"
    "encoding/json"
    "fmt"
    "github.com/bnb-chain/go-sdk/client/rpc"
    "github.com/bnb-chain/go-sdk/types"
    "github.com/bnb-chain/go-sdk/types/tx"
    ctypes "github.com/bnb-chain/go-sdk/common/types"
    "github.com/bnb-chain/go-sdk/keys"
    "time"
    "reflect"
)

type EventData struct {
    Tx string `json:"tx"`
}

type Input struct {
    Address string `json:"address"`
    Coins   []struct {
        Denom  string `json:"denom"`
        Amount int64  `json:"amount"`
    } `json:"coins"`
}

type Output struct {
    Address string `json:"address"`
    Coins   []struct {
        Denom  string `json:"denom"`
        Amount int64  `json:"amount"`
    } `json:"coins"`
}

type Msg struct {
    Inputs  []Input  `json:"inputs"`
    Outputs []Output `json:"outputs"`
}

type DecodedTx struct {
    Msg        []Msg `json:"msg"`
    Signatures []struct {
        PubKey      string `json:"pub_key"`
        Signature   string `json:"signature"`
        AccountNum  int64  `json:"account_number"`
        Sequence    int64  `json:"sequence"`
    } `json:"signatures"`
    Memo   string      `json:"memo"`
    Source int64       `json:"source"`
    Data   interface{} `json:"data"`
}

type Coins []Coin

type Coin struct {
    Denom  string `json:"denom"`
    Amount int64  `json:"amount"`
}

func scanMempool() {
        BNBClient = rpc.NewRPCClient("dataseed1.binance.org:80", ctypes.ProdNetwork)
    query := "tm.event = 'Tx'"
    events, err := BNBClient.Subscribe(query, 100)
    if err != nil {
        fmt.Println("Error while subscribing", err)
        return
    }

    for event := range events {
        fmt.Printf("[%s] new event\n", time.Now().UTC().Format("2006-01-02 15:04:05 GMT"))
        eventDataBytes, err := json.Marshal(event.Data)
        if err != nil {
            fmt.Println("Error converting TMEventData to bytes:", err)
            continue
        }

        var eventData EventData
        err = json.Unmarshal(eventDataBytes, &eventData)
        if err != nil {
            fmt.Println("Error unmarshaling event data:", err)
            continue
        }

        txBytes, err := base64.StdEncoding.DecodeString(eventData.Tx)
        if err != nil {
            fmt.Println("error:", err)
            continue
        }

        txs := []string{
            string(txBytes),
        }

        codec := types.NewCodec()
        parsedTxs := make([]tx.StdTx, len(txs))

        for i := range txs {
            err := codec.UnmarshalBinaryLengthPrefixed([]byte(txs[i]), &parsedTxs[i])
            if err != nil {
                fmt.Println("Failed to unmarshal transaction:", err)
                continue
            }

            // Extract and print the inputs and destination address
            for _, tx := range parsedTxs {
                txBytes, err := json.Marshal(tx)
                if err != nil {
                    fmt.Println("Failed to marshal transaction:", err)
                    continue
                }

                var decodedTx DecodedTx
                err = json.Unmarshal(txBytes, &decodedTx)
                if err != nil {
                    fmt.Println("Failed to unmarshal decoded transaction:", err)
                    continue
                }

                for _, msg := range decodedTx.Msg {
                    for _, input := range msg.Inputs {
                        fmt.Println("Input Address:", input.Address)
                        for _, coin := range input.Coins {
                            fmt.Println("Coin Denom:", coin.Denom)
                            fmt.Println("Coin Amount:", coin.Amount)
                        }
                    }

                    for _, output := range msg.Outputs {
                        fmt.Println("Output Address:", output.Address)
                    }
                }
                fmt.Println("-")
            }
        }
    }
}

And here's a sample output:

[2023-08-15 12:03:06 GMT] new event
Input Address: bnb1fnd0k5l4p3ck2j9x9dp36chk059w977pszdgdz
Coin Denom: DOGE-B67
Coin Amount: 40557400000
Output Address: bnb1rw2q5m33e90h9yuzsjuquh2xhffy9qga5v8p04
-
[2023-08-15 12:03:13 GMT] new event
Input Address: bnb1xrfwzlu9c5208lhtn7ywt0mjrhjh4nt4fjyqxy
Coin Denom: BNB
Coin Amount: 1186198
Output Address: bnb1a777eq69f2rmjqxllk2fy9sj93narq9z7knetg
-
[2023-08-15 12:03:26 GMT] new event
Input Address: bnb1fnd0k5l4p3ck2j9x9dp36chk059w977pszdgdz
Coin Denom: BNB
Coin Amount: 3700525
Output Address: bnb1q5mjgexmxfdtk86x9erm6de9lx5jruhw7295lh
-
[2023-08-15 12:03:39 GMT] new event
Input Address: bnb1tel566az93u7g6sc0jg49rxwdvk4yqz96ggnad
Coin Denom: BUSD-BD1
Coin Amount: 170000000000
Output Address: bnb17dntvsztw8pyul7904cstg9rs50dv96r2elmpc
-
[2023-08-15 12:03:50 GMT] new event
-
[2023-08-15 12:03:50 GMT] new event
-

Then I get no more events, all stuck. Why? Can somebody help me, please?

tajelp commented 1 year ago

Here's the go.mod:

module EvnetbndGocode

go 1.17

require github.com/bnb-chain/go-sdk v1.3.2

require (
        github.com/mattn/go-sqlite3 v1.14.17 // indirect
        gopkg.in/resty.v1 v1.12.0 // indirect
)

require (
        github.com/bartekn/go-bip39 v0.0.0-20171116152956-a05967ea095d // indirect
        github.com/beorn7/perks v1.0.1 // indirect
        github.com/bgentry/speakeasy v0.1.0 // indirect
        github.com/bnb-chain/ics23 v0.1.0 // indirect
        github.com/bnb-chain/node v0.10.7 // indirect
        github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
        github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
        github.com/cespare/xxhash/v2 v2.1.2 // indirect
        github.com/cosmos/cosmos-sdk v0.47.3 // indirect
        github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d // indirect
        github.com/cosmos/ledger-go v0.9.2 // indirect
        github.com/davecgh/go-spew v1.1.1 // indirect
        github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
        github.com/etcd-io/bbolt v1.3.3 // indirect
        github.com/fsnotify/fsnotify v1.4.9 // indirect
        github.com/go-kit/kit v0.9.0 // indirect
        github.com/go-logfmt/logfmt v0.5.1 // indirect
        github.com/gogo/protobuf v1.3.2 // indirect
        github.com/golang/protobuf v1.5.2 // indirect
        github.com/golang/snappy v0.0.4 // indirect
        github.com/google/btree v1.0.0 // indirect
        github.com/gorilla/mux v1.7.3 // indirect
        github.com/gorilla/websocket v1.5.0 // indirect
        github.com/hashicorp/golang-lru v0.5.3 // indirect
        github.com/hashicorp/hcl v1.0.0 // indirect
        github.com/inconshreveable/mousetrap v1.0.0 // indirect
        github.com/jmhodges/levigo v1.0.0 // indirect
        github.com/libp2p/go-buffer-pool v0.0.2 // indirect
        github.com/magiconair/properties v1.8.1 // indirect
        github.com/mattn/go-isatty v0.0.10 // indirect
        github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
        github.com/mitchellh/go-homedir v1.1.0 // indirect
        github.com/mitchellh/mapstructure v1.1.2 // indirect
        github.com/pelletier/go-toml v1.4.0 // indirect
        github.com/pkg/errors v0.9.1 // indirect
        github.com/pmezard/go-difflib v1.0.0 // indirect
        github.com/prometheus/client_golang v1.14.0 // indirect
        github.com/prometheus/client_model v0.3.0 // indirect
        github.com/prometheus/common v0.37.0 // indirect
        github.com/prometheus/procfs v0.8.0 // indirect
        github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 // indirect
        github.com/rs/cors v1.6.0 // indirect
        github.com/spf13/afero v1.2.2 // indirect
        github.com/spf13/cast v1.3.0 // indirect
        github.com/spf13/cobra v0.0.5 // indirect
        github.com/spf13/jwalterweatherman v1.1.0 // indirect
        github.com/spf13/pflag v1.0.3 // indirect
        github.com/spf13/viper v1.4.0 // indirect
        github.com/stretchr/testify v1.8.1 // indirect
        github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
        github.com/tendermint/btcd v0.1.1 // indirect
        github.com/tendermint/go-amino v0.15.0 // indirect
        github.com/tendermint/iavl v0.12.4 // indirect
        github.com/tendermint/tendermint v0.35.9 // indirect
        github.com/zondax/hid v0.9.0 // indirect
        github.com/zondax/ledger-cosmos-go v0.9.9 // indirect
        golang.org/x/crypto v0.5.0 // indirect
        golang.org/x/net v0.7.0 // indirect
        golang.org/x/sys v0.5.0 // indirect
        golang.org/x/text v0.7.0 // indirect
        google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 // indirect
        google.golang.org/grpc v1.31.0 // indirect
        google.golang.org/protobuf v1.28.1 // indirect
        gopkg.in/yaml.v2 v2.4.0 // indirect
        gopkg.in/yaml.v3 v3.0.1 // indirect; indirectclient := client.New("wss://stream.binance.org:9443/ws")
)

replace (
        github.com/cosmos/cosmos-sdk => github.com/bnb-chain/bnc-cosmos-sdk v0.26.3
        github.com/tendermint/go-amino => github.com/bnb-chain/bnc-go-amino v0.14.1-binance.2
        github.com/tendermint/iavl => github.com/bnb-chain/bnc-tendermint-iavl v0.12.0-binance.5
        github.com/tendermint/tendermint => github.com/bnb-chain/bnc-tendermint v0.32.3-bc.10
        github.com/zondax/ledger-cosmos-go => github.com/bnb-chain/ledger-cosmos-go v0.9.10-0.20230201065744-d644bede1667
        github.com/zondax/ledger-go => github.com/bnb-chain/ledger-go v0.9.1
        golang.org/x/crypto => github.com/tendermint/crypto v0.0.0-20190823183015-45b1026d81ae
)