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

blockchain: Save iterator head to last successfuly executed even on errors #2680

Merged
merged 5 commits into from
May 5, 2023

Conversation

g11tech
Copy link
Contributor

@g11tech g11tech commented May 5, 2023

On further debugging and testing another case of vmHead corruption was observed:

  1. client was executing 749796-749896 range but got an interrup signal and 749890 failed

  2. next time client started vmHead was already updated to 749896 and execution started from block 749897 which obviously would fail
    image

The synopsis of the issue:

In vmExecution iterator, block error was being ignored leading to incorrect vmHead forward movement. So the right thing to do was to throw error.
However in blockchain, iterator head was not being properly saved to last successfully executed if onBlock callbacks errored.

This PR addressed both the issues and also moves out iterator error handling out side of the vm iterator callback for further simplicity.

if (releaseLockOnCallback === true) {
this._lock.release()
}
try {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

lots of diff here is because of formatting change introduced because of this try

throw new Error(
'cannot get iterator head: blockchain has no getTotalDifficulty function'
)
this.vmPromise = blockchain
Copy link
Contributor Author

Choose a reason for hiding this comment

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

again most of diff here is because of formatting changed because of introduction to the catch to the iterator promise below

@codecov
Copy link

codecov bot commented May 5, 2023

Codecov Report

❗ No coverage uploaded for pull request base (develop-v7@e4075b5). Click here to learn what that means.
The diff coverage is n/a.

Additional details and impacted files

Impacted file tree graph

Flag Coverage Δ
block 90.30% <0.00%> (?)
blockchain 90.47% <0.00%> (?)
client 86.88% <0.00%> (?)
common 95.76% <0.00%> (?)
devp2p 91.80% <0.00%> (?)
ethash ∅ <0.00%> (?)
evm 79.35% <0.00%> (?)
rlp ∅ <0.00%> (?)
statemanager 88.53% <0.00%> (?)
trie 90.30% <0.00%> (?)
tx 95.50% <0.00%> (?)
vm 84.39% <0.00%> (?)

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

Copy link
Contributor

@acolytec3 acolytec3 left a comment

Choose a reason for hiding this comment

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

Left a couple of questions to clarify my understanding of what the new catch blocks do but looks fine so far as it goes.

Is there any way to easily test that this works?

}
}
return blocksRanCounter
} finally {
Copy link
Contributor

Choose a reason for hiding this comment

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

To make sure I understand what's going on here, this outer try...finally block just makes sure save the current head and then throws the triggering error out to the client so it can exit gracefully?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes correct! this.heads['vm'] always have the last successfuly executed block

true
)
// Ensure to catch and not throw as this would lead to unCaughtException with process exit
.catch(async (error) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we catch the error here, what error is thrown that tells the client to exit?

Copy link
Contributor Author

@g11tech g11tech May 5, 2023

Choose a reason for hiding this comment

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

no error is to be thrown for client to exit, when client catches Ctrl + C it stops execution which causes this iterator to throw error and the catch here logs and returns actualExecuted or null If the error is thrown here, it seems to be going in territory of unCaughtException

Problem to solve here is to cleanly exit which is the aim of the PR

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, right, this is just handling an error that occurs when the client is already in the process of exiting. Makes sense.

@g11tech
Copy link
Contributor Author

g11tech commented May 5, 2023

Left a couple of questions to clarify my understanding of what the new catch blocks do but looks fine so far as it goes.

Is there any way to easily test that this works?

yes : first run client with just sync: ./node_modules/.bin/ethereumjs --network mainnet --execution false

after it has synced couple thousand blocks, just not test with execution and keep doing Ctrl C and restart to

./node_modules/.bin/ethereumjs --network mainnet --sync none

@acolytec3
Copy link
Contributor

There are a couple of reorg related blockchain tests failing so I wonder if there's some minor parentheses or bracket that got moved around the reorg logic.

@g11tech
Copy link
Contributor Author

g11tech commented May 5, 2023

There are a couple of reorg related blockchain tests failing so I wonder if there's some minor parentheses or bracket that got moved around the reorg logic

fixed an edge case 👍

Copy link
Contributor

@acolytec3 acolytec3 left a comment

Choose a reason for hiding this comment

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

Lgtm!

@acolytec3 acolytec3 merged commit 264848e into develop-v7 May 5, 2023
@holgerd77 holgerd77 deleted the g11tech/fix-vmhead-corruption branch June 6, 2023 08:30
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.

2 participants