harmony-one / sdk

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

RangeError: Maximum call stack size exceeded (during getTransactionCount) #104

Open trekze opened 2 years ago

trekze commented 2 years ago

Hi

We're encountering another uncaught exception coming from the SDK. This time when we use the blochamin.getTransactionCount() API

Error: RangeError: Maximum call stack size exceeded
    at Messenger.<anonymous>
     (/path/crypto_royale/node_modules/@harmony-js/network/dist/messenger/messenger.js:82:35)
    at step (/path/crypto_royale/node_modules/tslib/tslib.js:143:27)
    at Object.throw (/path/crypto_royale/node_modules/tslib/tslib.js:124:57)
    at rejected (/path/crypto_royale/node_modules/tslib/tslib.js:115:69)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Here is try-catch block in which the exception occurs:

 try {
            let count = await hmy.blockchain.getTransactionCount({ address: MAIN_ACCOUNT })
            nonce = parseInt(count.result);
            while (nonce in transactionsInProgress) {
                nonce += 1;
            }
            transactionsInProgress[nonce] = true;
  } catch (err) {
            resolve({ success: false, error: `Nonce creation error` });
            return;
  }

Once this happens once, it keeps occuring until we restart the process.

Any thoughts/fixes/workarounds appreciated.

trekze commented 2 years ago

Any chance to get at least a reply on the above?

I've noticed the SDK hasn't had attention in recent months. Is Harmony moving away from maintaining it?

neeboo commented 2 years ago

Any chance to get at least a reply on the above?

I've noticed the SDK hasn't had attention in recent months. Is Harmony moving away from maintaining it?

May I ask why you use while loop in your code.

trekze commented 2 years ago

Any chance to get at least a reply on the above? I've noticed the SDK hasn't had attention in recent months. Is Harmony moving away from maintaining it?

May I ask why you use while loop in your code.

Why do you ask? The while loop has no bearing on the exception generated by .getTransactionCount that comes before it.

neeboo commented 2 years ago

Any chance to get at least a reply on the above? I've noticed the SDK hasn't had attention in recent months. Is Harmony moving away from maintaining it?

May I ask why you use while loop in your code.

Why do you ask? The while loop has no bearing on the exception generated by .getTransactionCount that comes before it.

Because if you are using ws api may cause the loop out of stack. So I want to figure out your purpose and come up with a workaround

trekze commented 2 years ago

Hi neebo. I'm still not sure what you mean. The while loop is being used to iterate through my own data structure. The call to hmy.blockchain.getTransactionCount is happening ONCE, before the while loop. and the call stack error is coming from inside the Harmony SDK. We are not calling the SDK in a loop.

neeboo commented 2 years ago

Hi neebo. I'm still not sure what you mean. The while loop is being used to iterate through my own data structure. The call to hmy.blockchain.getTransactionCount is happening ONCE, before the while loop. and the call stack error is coming from inside the Harmony SDK. We are not calling the SDK in a loop.

ok. Please change harmony endpoint to https instead of websocket to see if the error disappear

trekze commented 2 years ago

We're already using the https endpoint.

trekze commented 2 years ago

Any ideas?

rac-sri commented 2 years ago

@hmexx can you share more details, like how have you initialized your hmy. I tried your own code with several different addresses including both, EOA and Contract Addresses, and I cannot replicate the error you are getting

trekze commented 2 years ago

How long did you run it for? We have to restart our process every few days and we average a withdrawal every couple of minutes. So a good test would be 2000 transactions during a mixture of normal and congested times (so that the occasional SDK error is mixed with successful transactions).

Here is our hmy initialization code:

const HARMONY_API = process.env.HARMONY_API || 'https://api.s0.t.hmny.io';
const GAS_PRICE_GWEI = process.env.GAS_PRICE_GWEI || '11'
const DEVMODE = process.env.ROY_DEVELOPMENT == 'TRUE';
const { logger } = require('../helpers')
const {
    ChainID,
    ChainType,
    hexToNumber,
    numberToHex,
    fromWei,
    Units,
    Unit,
} = require('@harmony-js/utils');

const hmy = new Harmony(
    DEVMODE ? 'https://api.s0.pops.one/' : HARMONY_API, {
    chainType: ChainType.Harmony,
    chainId: DEVMODE ? ChainID.HmyTestnet :ChainID.HmyMainnet,
},
);
hmy.wallet.addByPrivateKey(MAIN_KEY)

const ROY_abi = require("./abi.json");
const ROY_contract_address = "0xfe1b516A7297eb03229A8B5AfAD80703911E81cB";
trekze commented 2 years ago

Is there no way for someone to audit the code in the place the exception is thrown to see what could be causing the RangeError ? Are the original developers of the SDK still around? My original post has the stack trace.

Error: RangeError: Maximum call stack size exceeded
    at Messenger.<anonymous>
     (/path/crypto_royale/node_modules/@harmony-js/network/dist/messenger/messenger.js:82:35)
    at step (/path/crypto_royale/node_modules/tslib/tslib.js:143:27)
    at Object.throw (/path/crypto_royale/node_modules/tslib/tslib.js:124:57)
    at rejected (/path/crypto_royale/node_modules/tslib/tslib.js:115:69)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
trekze commented 2 years ago

Some more information which should be very helpful in getting to the bottom of this.

We get the same Maximum call stack size error, regardless of which contract method is called.

We have a process that checks blockchain HRC20 balances, and these start failing 100% of the time after 5000 or so. This happens every single time. So it should be very easy to replicate.

Just run the following:

await contract.methods.balanceOf(address).call(); on a standard HRC20 smart contract

In a loop 20,000 times (to be on the safe side) and you should hit the bug.

neeboo commented 2 years ago

Some more information which should be very helpful in getting to the bottom of this.

We get the same Maximum call stack size error, regardless of which contract method is called.

We have a process that checks blockchain HRC20 balances, and these start failing 100% of the time after 5000 or so. This happens every single time. So it should be very easy to replicate.

Just run the following:

await contract.methods.balanceOf(address).call(); on a standard HRC20 smart contract

In a loop 20,000 times (to be on the safe side) and you should hit the bug.

Would you try adding a setTimeout to your loop and give the loop a proper exit?

trekze commented 2 years ago

We don't use a loop. The contract is called each time there is a withdrawal requested. And there's a delay between each call.

Can you try running the test I've described?

andy-uphold commented 5 months ago

I'm seeing this too. Any progress?

trekze commented 5 months ago

I'm seeing this too. Any progress?

Yes. The answer is do not use the harmony SDK for anything. No one does. We migrated to using ethers and since then no issues. It also means you can run your dapp on any EVM chain. On that note you may want to consider if harmony is the best choice.