0

I'd like to be able to immediately get a struct value from a mapping after calling a function that updates the struct, however, when testing with Ganache, sometimes the event arrives to the listener before the struct has been updated in the contract. I've noticed that the issue is especially bad when trying to transfer value within the function that emits the event.

Here's a small demo contract to illustrate the issue.

pragma solidity ^0.5.8;

contract Names {

    uint lastId;
    mapping(uint => Name) public numberedNames;

    struct Name {
        string name;
    }

    constructor() public {
        lastId = 0;
    }

    event LogNewName(uint id, string name);
    event LogNameUpdate(uint id, string name);

    function setName(string memory name) public {
        numberedNames[lastId] = Name(name);
        emit LogNewName(lastId, name);
        lastId++;
    }

    function changeName(uint id, string memory name, uint transferRequest) public payable {
        Name storage existingName = numberedNames[id];
        existingName.name = name;
        msg.sender.transfer(transferRequest);
        emit LogNameUpdate(id, name);
    }

}

And here's what I'm trying do in node within the event listener.

async function listenerCallback(data) {
    await utils.pause(1000); // pause 1 second - adding this will prevent mappingStruct from being stale, but not an ideal solution
    const mappingStruct = await contract.methods.numberedNames(data.returnValues.id);
    console.log(mappingStruct)

    // update db based on event information
}

Again, if I have a transfer in the function (see the changeName function above), the value of mappingStruct will always be stale unless adding a delay. However, even if not transferring value, it is sometimes still stale.

Adding the delay complicates things in my case so it would be highly preferable to address this in the contract code if at all possible.

Any suggestions? Also, since this is my first Ethereum project, will this be an issue on the mainnet?

0

Usually a client will update its internal state before triggering events.

But still there is the possibility of a chain reorg between the event being triggered and the request for extra data.

Either you add a check for chain reorgs or send enough data in the event so you don't have to make the extra query.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.