0

I am using web3.js library to interact with a smart contract, and am having issues with a race condition and not sure how to fix it. I am sending a transaction to the chain, and then waiting for the receipt before trying to read the state that transaction updates. However, upon receiving the receipt, the state is still not updated. I'm currently using an interval function to try to give time to pickup the change of state, but this feels like the wrong way to approach this, and I'm not sure what the better way to write it is.

content.ok is true once the transaction is mined and receipt returned. There is no issue with the condition being met.

if (content.ok) {
    await fetch("/log/info",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:`Reservation made for acccount ${accounts[0]}`})});
    console.log(content);
    let loopCount = 0;

    /* this interval function loops 10-20 times after the receipt is returned before it actually 
     * gets the updated value from the chain. This is confusing because I thought once the receipt 
     * was returned, the state should be updated, and thus the data readable, so this seems odd to 
     * me that the state data isn't updated for another 15 seconds ish after receipt. However, if I
     * refresh the page after receipt, it will pull the updated state data immediately with no
     * issues, so why does not refreshing the page take so long to get updated state data?
     */
    const interval = setInterval(async () => {
        const iporf = new ContractInterface();
        const timeLeft = await iporf.getTimeLeft(accounts[0]);
        loopCount++;
                    
        if (timeLeft > 0) {
            this.setState({ timeLeft: timeLeft });
            clearInterval(interval);
        }

        if (loopCount >= 30 && timeLeft <= 0) {
            clearInterval(interval);
            this.props.handleError("Unable to get time left on reservation. Data may not be valid.");
        }
    }, 1000);
}

Relevant log entries:

2021-08-11T14:32:30.566Z info: Attempting to reserve for account {account}
2021-08-11T14:32:30.574Z info: Reservation contract setup
2021-08-11T14:32:30.575Z info: Signing transaction
2021-08-11T14:32:30.599Z info: Transaction signed
2021-08-11T14:32:31.928Z info: Verifying reservation has been mined before purchase.
2021-08-11T14:32:32.988Z info: Getting amount of reservation for account {account}
2021-08-11T14:32:33.029Z info: Reservation amount: 0
2021-08-11T14:32:33.974Z info: Getting amount of reservation for account {account}
2021-08-11T14:32:34.003Z info: Reservation amount: 0
2021-08-11T14:32:34.973Z info: Getting amount of reservation for account {account}
2021-08-11T14:32:35.000Z info: Reservation amount: 0
...
2021-08-11T14:32:52.108Z info: Transaction receipt: {"blockHash":{hash},"blockNumber":1258,"contractAddress":null,"cumulativeGasUsed":68919,"from":{fromAddress},"gasUsed":68919,"effectiveGasPrice":"0x0","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":true,"to":{toAddress},"transactionHash":{hash},"transactionIndex":0}
2021-08-11T14:32:52.108Z info: Reservation made on chain.
2021-08-11T14:32:53.044Z info: Getting amount of reservation for account {account}
2021-08-11T14:32:53.067Z info: Reservation amount: 0
2021-08-11T14:32:53.161Z info: Getting time left on reservation
2021-08-11T14:32:53.196Z info: Time left: 0
2021-08-11T14:32:54.048Z info: Getting amount of reservation for account {account}
2021-08-11T14:32:54.073Z info: Reservation amount: 0
2021-08-11T14:32:54.177Z info: Getting time left on reservation
2021-08-11T14:32:54.208Z info: Time left: 0
...
2021-08-11T14:33:12.223Z info: Getting time left on reservation
2021-08-11T14:33:12.255Z info: Time left: 275

Getting the amount eventually timed out of it's interval. I don't understand why it's taking so long to get the value of the state variable. I'm not doing anything other than using web3.js to call the view method.

4
  • there is no way that the state is not updated after transaction was processed, you most likely have some bug in your code or contract
    – Nulik
    Aug 3 at 19:41
  • The issue is how long it takes for the update to be readable. On average (based on logs) it takes 10-20 seconds after the receipt is returned before the web3 library obtains the state value in a subsequent call. One transaction took 22 seconds to return a receipt, and then took another 20 seconds before the getter would return the state variable value. The getter functions aren't doing anything fancy, they're just returning the variable as a view method. Not sure how there can be a bug there. There could be a bug in the web3 library.
    – pdmoerman
    Aug 11 at 14:39
  • @pdmoeman it is more complex than just using web3. There could be a chain split, and the chian could be reverted and your transaction might be cancelled. Chain splits happen 2 - 3 times a day. During the chain split event, your web3 javascript code might suffer a disconnect from the node and you could lose the events. and the removed flag wont help. Welcome to blockchain technology
    – Nulik
    Aug 11 at 23:16
  • That may be the case for the Mainnet, but this is on a private chain that I'm currently testing with, and there is currently only one node.
    – pdmoerman
    Aug 16 at 15:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.