monosux/ethereum-block-by-date

TypeError: Cannot destructure property 'timestamp' of '(intermediate value)' as it is null.

Closed this issue ยท 14 comments

rzmay commented

This error seems to fire when recent timestamps are passed, in this case expected behavior would be to return the current block. I'm not entirely sure if this is actually the cause of the error as I haven't read the source code

Cause appears to be on line 79 of ethereum-block-by-date.js, which would only cause a problem if the call to getNextBlock on line 43 returns a null or invalid value.

I believe the issue here is that the block returned by getNextBlock is after the current block, in which case the web3.eth.getBlock() call on line 79 returns a null value that cannot be deconstructed. As I understand it the fix here is to return the minimum between the predicted block number and the current block number, e.g. changing line 77 to:

block = block == 'latest' ? await this.web3.eth.getBlockNumber() : Math.min(block, await this.web3.eth.getBlockNumber());

I can open a pull request to fix this if you'd like.

Relevant stack trace:

TypeError: Cannot destructure property 'timestamp' of '(intermediate value)' as it is null.
    at module.exports.getBlockWrapper (/node_modules/ethereum-block-by-date/lib/ethereum-block-by-date.js:90:7)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async module.exports.findBetter (/node_modules/ethereum-block-by-date/lib/ethereum-block-by-date.js:50:30)
    at async module.exports.getDate (/node_modules/ethereum-block-by-date/lib/ethereum-block-by-date.js:28:46)

Hi @rzmay,

thank you for the information! Do you have a code example, that causes the error?

rzmay commented

Thanks for the quick response! The code that causes the error is as follows:

const { block } = await dater.getDate(new Date(date), false);

Where an example of the date passed is 2022-03-16T21:06:36.603Z (which was fairly recent when the error was encountered). This was running on a local private network using ganache-cli. The error was also encountered after removing the false "block after" flag. The dater was constructed with a web3 provider.

Ok, got it, thanks. I will check it and fix.

rzmay commented

After a bit more investigation, I've found that I can't consistently recreate this error. My initial understanding that it occurred when passing recent timestamps has proven false. I've tried it both with recent timestamps, future timestamps, and past timestamps as well as dates that refer to a time before my local network was even running. Strangely enough, each of these attempts has produced the error at least once, but none of them have produced it consistently.

I'll keep investigating and I'll let you know if I can identify a pattern. Thank you again for looking into this issue!

Hi @rzmay,

Were you able to reproduce the error using a production environment? Some public network instead of your private network? If so, could you please share details such as network and web3 provider? Thanks!

Hi @rzmay,

Thank you for your research!

I found the issue and fixed it. Looks like the problem was with using getBlockNumber() and getBlock() together. Sometimes for the newest blocks getBlockNumber() returns a valid value, and getBlock() does not. So, I decided to get rid of getBlockNumber() and use only getBlock() in getBlockWrapper(). I published a new version of package 1.4.3, please update, and let me know if you still have the issue. Or any other issues!

See: 66f009d

@monosux hello, there still is an error
error message:
TypeError: Cannot destructure property 'number' of '(intermediate value)' as it is null.
| at module.exports.getBlockWrapper (/srv/node_modules/ethereum-block-by-date/lib/ethereum-block-by-date.js:89:7)
| at runMicrotasks ()
| at processTicksAndRejections (internal/process/task_queues.js:93:5)
| at async module.exports.findBetter (/srv/node_modules/ethereum-block-by-date/lib/ethereum-block-by-date.js:50:30)
| at async module.exports.getDate (/srv/node_modules/ethereum-block-by-date/lib/ethereum-block-by-date.js:28:46)
code example:
`
export class BlockByDateService {
private dater;

constructor(private readonly web3Service: Web3Service) {
    this.dater = new EthDater(web3Service.getWeb3());
}

public async getBlockByDate(date: string, reconnectCount = 3): Promise<number> {
    const blockAfter = true; // Block after, optional. Search for the nearest block before or after the given date. By default true.
    try {
        const res = await this.dater.getDate(date, blockAfter);
        return res.block;
    } catch (e) {
        if (reconnectCount === 0) {
            throw e;
        }
        return this.getBlockByDate(date, --reconnectCount);
    }
}

}`

Hi @TarasKalynii,

thanks for the information! Will check it!

@monosux
I'm trying to understand what is wrong and noticed that the "skip" variable is too big, and we try to get a block that does not exist.
Also, I'm working on 'https://polygon-mumbai.infura.io/v3/da8d4815fddd422bbd0526ab522495ba' it is the test network.

dater.getDate('2022-03-27T08:10:00.000Z', true) - will though error

image

@monosux hello, I created a merge request with fix, please review)

Hi @TarasKalynii,

Thank you for your fix! I updated the package, the current version with the fix is 1.4.4

I just saw this error with 1.4.4 fix:

image

Hi @tarunmangukiya,

could you provide a code example, that causes the error?

Hello,

I am having this issue as well on the version 1.4.5.

        var last_block = await dater.getDate(
          date, // Date, required. Any valid moment.js value: string, milliseconds, Date() object, moment() object.
          true // Block after, optional. Search for the nearest block before or after the given date. By default true.
        );

where date = "2022-08-17T09:02:00Z"

image

I am having a hard time to understand what is happening there as yesterday it worked like a charm. Relaunched my server and stopped working for the exact same date...

I am using the module with BSC.