Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VM, Blockchain: fix storing unsettled promises #1201

Closed
wants to merge 8 commits into from

Conversation

ryanio
Copy link
Contributor

@ryanio ryanio commented Apr 12, 2021

#1181

This PR resolves storing unsettled promises in VM, Blockchain by preferring to use VM.create and Blockchain.create instead of new VM and new Blockchain as this lets us safely run async init code.

VM: mcl is now initialized inside VM.init() and has no stored promise.
Blockchain: init is run during Blockchain.create() and has no stored promise.

Both classes have boolean _isInitialized and check internally to make sure they do not init more than once.

Sometimes in the client a Blockchain or VM is set up in a constructor. In this case, the init is added to the classes' open method.

@codecov
Copy link

codecov bot commented Apr 12, 2021

Codecov Report

Merging #1201 (3473e72) into master (e2a0a4d) will decrease coverage by 0.06%.
The diff coverage is 88.46%.

❗ Current head 3473e72 differs from pull request most recent head 2b91fe5. Consider uploading reports for the commit 2b91fe5 to get more accurate results
Impacted file tree graph

Flag Coverage Δ
block 86.73% <ø> (+0.13%) ⬆️
blockchain 82.90% <85.71%> (-0.53%) ⬇️
client 83.79% <100.00%> (-0.26%) ⬇️
common 94.39% <ø> (ø)
devp2p 83.64% <ø> (+0.31%) ⬆️
ethash 82.83% <ø> (ø)
tx 88.36% <ø> (+0.11%) ⬆️
vm 79.19% <75.00%> (-0.15%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

@ryanio ryanio force-pushed the fix-unsettled-promises branch from a5eb812 to 902add9 Compare April 12, 2021 23:53
@holgerd77
Copy link
Member

This PR has somewhat conflicting readyness settings, what's the status?

@ryanio
Copy link
Contributor Author

ryanio commented Apr 26, 2021

I don't think I can make any of the changes I would have liked in this PR without any breaking changes, since moving from stored to unstored promises is a breaking change itself (for example if anyone was using or relying on them).

I think we can put this PR on the back burner until we are ready to merge breaking changes for v6 where we can make some broader changes and refactor the async init code.

@holgerd77
Copy link
Member

@ryanio ok, have added to the v6 planning notes and added a "blocked" label here.

@ryanio ryanio linked an issue Aug 13, 2021 that may be closed by this pull request
ryanio added 3 commits August 13, 2021 15:14
 * make constructor private (prefer use of async `Blockchain.create`)
 * update usage, tests
 * move types to dedicated file
 * make constructor private (prefer use of async `VM.create`)
 * update usage, tests
@ryanio ryanio force-pushed the fix-unsettled-promises branch from 902add9 to a0e000c Compare August 13, 2021 23:22
@ryanio
Copy link
Contributor Author

ryanio commented Aug 13, 2021

Phew, rebased this, that was not trivial :)

Holger I know you decided against this approach since private constructors block inheritance, so I am going to think more about it, maybe we just make them deprecated and note they are not private for the reason of inheritance but their use is strongly discouraged over the async methods. (edit: ok I undid the private constructor and made sure both had deprecation messages)

@ryanio ryanio force-pushed the fix-unsettled-promises branch from 3b211e1 to 0651191 Compare August 14, 2021 00:15
@ryanio ryanio force-pushed the fix-unsettled-promises branch from 0651191 to 3473e72 Compare August 14, 2021 00:30
@holgerd77
Copy link
Member

Holger I know you decided against this approach since private constructors block inheritance, so I am going to think more about it, maybe we just make them deprecated and note they are not private for the reason of inheritance but their use is strongly discouraged over the async methods. (edit: ok I undid the private constructor and made sure both had deprecation messages)

That's what I also suggested yeah, but I have to admit that I am also still unsure. On the other hand it would be a huge win to have this somewhat ensured that devs are not unsafely calling into this. But I do am somewhat anxious on this that we might have not considered all use cases here and might put some unpractical restrictions on users by doing so.

Some additional thoughts I had here:

  1. We can actually also use protected instead of private. This might generally be the better fit, not sure why I didn't think about this yet. Just tested and works as expected:

grafik

  1. This change is actually a type "we-can-try-and-see-if-we-get-through-with-it" change. 😜 So on a breaking release it is actually both safe to introduce as well as easy to later remove. So if we are at least somewhat convinced that this is a good thing and assume that the positive outcome overweight the negatives we can actually try (then eventually version 1. with protected) and - while not pretty - we can still revert in some worst case scenario of a substantial amount of substantial negative community feedback.

* provided from the `common` will be used.
*/
genesisBlock?: Block
}
Copy link
Member

@holgerd77 holgerd77 Aug 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this huge type file coming from? Is this a forgotten artifact from the interface PR which also happened around that time? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah no I was just moving them from index.ts because it was getting so long. I will undo this though because I see the benefit of keeping it along with the source code now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I guess on Blockchain we likely also want to restructure the exports and use the index.ts file just for exporting things and move code and types to dedicated files, a bit as we are planning for the VM (see #1024 VM TODOs).

If you agree respectively have no reservations you might directly want to do in this PR since this is breaking already?

@ryanio
Copy link
Contributor Author

ryanio commented Aug 16, 2021

oh nice, protected seems great. I will add that.

@alcuadrado
Copy link
Member

IMO protected constructors with async create can be great, as long as all the operation of the class are async or it's expected to be used in an async context. It can lead to much cleaner code, while it may lead to the consumer having to do the lazy init() thing, but I guess is not probable and ok in this context.

@ryanio
Copy link
Contributor Author

ryanio commented Aug 16, 2021

@alcuadrado great, thanks!

that's weird, typescript is erroring out (on local and ci) when I added protected in 2b91fe5, I tried to google around and couldn't find an answer to this, I tried upgrading typescript to latest to see if there were any fixes as well and still same error:

> @ethereumjs/vm@5.5.2 build
> ../../config/cli/ts-build.sh

[Node build] Using tsconfig.prod.json
> tsc --build ./tsconfig.prod.json
[Node build] Working...
/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:35107
                else if (type.symbol.flags & (32 | 64)) {
                                     ^
TypeError: Cannot read property 'flags' of undefined
    at getBaseTypes (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:35107:38)
    at typeHasProtectedAccessibleBase (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:49112:29)
    at typeHasProtectedAccessibleBase (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:49140:20)
    at isConstructorAccessible (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:49157:25)
    at resolveNewExpression (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:49085:22)
    at resolveSignature (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:49357:28)
    at getResolvedSignature (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:49375:26)
    at checkCallExpression (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:49441:29)
    at checkExpressionWorker (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:51593:28)
    at checkExpression (/Users/ryanghods/dev/ethereumjs-monorepo/packages/vm/node_modules/typescript/lib/tsc.js:51510:38)

@holgerd77
Copy link
Member

Am I correct that we would now redo (respectively: re-point) this towards develop and - also - that this actually hasn't been reopened (and eventually already merged) towards develop yet?

@ryanio
Copy link
Contributor Author

ryanio commented Jan 11, 2022

this hasn't been updated or merged into anything yet, a good candidate i can pick up when we are ready to bring it in :)

@holgerd77 holgerd77 mentioned this pull request Feb 16, 2022
51 tasks
@ryanio
Copy link
Contributor Author

ryanio commented Mar 11, 2022

I will pick this up next week and start fresh with a new PR targeting develop.

@ryanio ryanio closed this Mar 24, 2022
@holgerd77 holgerd77 deleted the fix-unsettled-promises branch March 24, 2022 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unsettled promises shouldn't be stored.
3 participants