harmony-one / sdk

Javascript SDK of Harmony protocol.
MIT License
92 stars 43 forks source link

Contract event listener stops receiving events #106

Open trekze opened 2 years ago

trekze commented 2 years ago

Hi there.

Is it fair to say that the Harmony SDK should handle re-connects by itself when using the websocket API? See code below on how we listen for events on a smart contract. We've noticed at some point events stop coming through. We only deployed this yesterday, and it stopped overnight, so it may possibly be some kind of inactivity timeout?

Any guidance on options we should use to prevent timeouts, if needed, would be appreciated.

Thank you!

const HARMONY_WS = new WSProvider('wss://ws.s0.t.hmny.io');

const {
    ChainID,
    ChainType,
    hexToNumber,
    numberToHex,
    fromWei,
    Units,
    Unit,
} = require('@harmony-js/utils');

const wallet = new Wallet(
    new Messenger(
        HARMONY_WS,
        ChainType.Harmony,
        ChainID.HmyMainnet,
    ),
);
const factory = new ContractFactory(wallet);
const contractAddr = "0xfe1b516A7297eb03229A8B5AfAD80703911E81cB";
const contract = factory.createContract(contractJson, contractAddr);

contract.events
    .Transfer()
    .on('data', async (event) => {

  [... rest of code omitted ...]
trekze commented 2 years ago

Happened again last night.

Could someone please let us know what the correct steps are to help the SDK not lose connection to incoming events?

rac-sri commented 2 years ago

Looks like something that might happen during a congested network perhaps. As such, I was unable to replicate, ran this script for almost 2hrs.

const { Wallet } = require("@harmony-js/account");
const { WSProvider, Messenger } = require("@harmony-js/network");
const { ContractFactory } = require("@harmony-js/contract");
const {
  ChainID,
  ChainType,
  hexToNumber,
  numberToHex,
  fromWei,
  Units,
  Unit,
} = require("@harmony-js/utils");

const contractJson = [
  {
    inputs: [
      {
        indexed: true,
        type: "address",
        internalType: "address",
        name: "src",
      },
      {
        type: "address",
        internalType: "address",
        indexed: true,
        name: "dst",
      },
      {
        internalType: "uint256",
        indexed: false,
        name: "wad",
        type: "uint256",
      },
    ],
    anonymous: false,
    type: "event",
    name: "Transfer",
  },
];

const HarmonyWs = new WSProvider("wss://ws.s0.t.hmny.io");

const wallet = new Wallet(
  new Messenger(HarmonyWs, ChainType.Harmony, ChainID.HmyMainnet)
);

const factory = new ContractFactory(wallet);
const contractAddr = "0xcf664087a5bb0237a0bad6742852ec6c8d69a27a";
const contract = factory.createContract(contractJson, contractAddr);

contract.events.Transfer().on("data", async (e) => {
  console.log(e);
});

There is a function that you can call by doing HARMONY_WS.reconnect(), but ideally you shouldn't need it.

trekze commented 2 years ago

We will try calling .reconnect() every hour and see if that resolves the issue.

trekze commented 2 years ago

Can you try listening to events over 48 hours instead of 2 hours? It's not uncommon for it to work for a large portion of a day before the events stop coming through.

As an FYI, the other issue I've reported is way more important to us: https://github.com/harmony-one/sdk/issues/104#issuecomment-993311637