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

[ETCM-1044] add best block hash into storage #1077

Merged
merged 11 commits into from
Aug 11, 2021

Conversation

AurelienRichez
Copy link
Contributor

Description

This was originally from a spike (ETCM-1051), but I ended up implementing ETCM-1044 while poking at the code.

Make getBestBlock use getBlockByHash.

For this I added the best block hash along with the bestBlockNumber, so that when we want to get the best block number we can just get it from its hash and not from the block number mapping.

@AurelienRichez AurelienRichez marked this pull request as draft July 26, 2021 15:18
@@ -27,6 +38,16 @@ class AppStateStorage(val dataSource: DataSource) extends TransactionalKeyValueS
def getBestBlockNumber(): BigInt =
getBigInt(Keys.BestBlockNumber)

def getBestBlockInfo(): BestBlockInfo =
BestBlockInfo( // FIXME default value for hash ?
get(Keys.BestBlockHash).map(v => ByteString(Hex.decode(v))).getOrElse(ByteString.empty),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't really know if there is a decent value to return when the hash is not there. This is a case of "should not happen" because we always have a genesis when running the application. But it does happen during tests.

Copy link
Contributor

@strauss-m strauss-m Aug 3, 2021

Choose a reason for hiding this comment

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

Is it because the tests setting are incomplete (missing genesis, empty storage, other ?), and is it considered ok ?

As for the default value, I would eventually go the Option way.

But it raises the issue of how to handle the default value (be it the actual empty ByteString or a None). If every piece of code handling the potential missing hash is unable to cope with it, it may be worth making it mandatory to have a proper genesis each time, and raise a hard-error at a single point during the getBestBlockData()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is it because the tests setting are incomplete (missing genesis, empty storage, other ?), and is it considered ok ?

I think the reason is that it is not strictly necessary to actually have a genesis in storage for some test because of the mocking, and setting up a real genesis / making it mandatory in the design was not done as a consequence. In this particular case as 0 was a pretty decent default value (it is the genesis number after all) it was not really visible. But now storing the genesis hash makes the problem more apparent.

This inconsistency does not really happen outside of tests because the application loads genesis on startup, so it's "mostly" ok.

As for the default value, I would eventually go the Option way.

I would personally prefer to have a design that makes this inconsistency impossible as you said to be sure that we have a genesis (probably having the Storage take some information about the genesis in its constructor). I'm not sure about the impact this would have though as for instance ETS requires us to change the genesis at runtime.

Returning an option would mean that we would have to handle the None case everywhere, which really only means the the application is in an inconsistent state (In which case the application should probably crash).

Copy link
Contributor

Choose a reason for hiding this comment

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

Would it help to have to genesis block available by other means (eg. passed in as parameter) instead of from storage? That might actually be the more straightforward approach: genesis data is loaded from config when the node starts and is then written to the database. So loading it from the database is a bit of a detour.

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, what I think about is having some information about genesis passed as a parameter. Not only for the app state storage, but also in other storage such as bodies and headers. This way we can ensure that the genesis is there and remove some options in the code (like in getBestBlock).

I think that doing it in this PR would be too big of a change even if we only do the AppStateStorage part. I created this followup ticket to detail what would need to be done : https://jira.iohk.io/browse/ETCM-1090.

@AurelienRichez AurelienRichez changed the title [ETCM-1044] [WIP] add best block hash into storage [ETCM-1044] add best block hash into storage Jul 27, 2021
@AurelienRichez AurelienRichez marked this pull request as ready for review July 27, 2021 08:31
@AurelienRichez AurelienRichez force-pushed the feature/ETCM-1044-add-bestBlockHash branch 5 times, most recently from 2904794 to 4d3aa02 Compare August 2, 2021 07:32
@AurelienRichez AurelienRichez force-pushed the feature/ETCM-1044-add-bestBlockHash branch 3 times, most recently from 6e8e48b to 4f5f20a Compare August 2, 2021 15:22
@AurelienRichez AurelienRichez force-pushed the feature/ETCM-1044-add-bestBlockHash branch from 4f5f20a to 0a5edb8 Compare August 4, 2021 08:20
@jvdp
Copy link
Contributor

jvdp commented Aug 5, 2021

Do we still need to store best block number when we could fetch the header by hash and read the number from there?

@AurelienRichez AurelienRichez force-pushed the feature/ETCM-1044-add-bestBlockHash branch 3 times, most recently from 6ebd60a to ab47a79 Compare August 9, 2021 13:17
@AurelienRichez
Copy link
Contributor Author

Do we still need to store best block number when we could fetch the header by hash and read the number from there?

Yes, we should be able to get rid of the block number in the app state storage. It is used in a few places right now so it cannot be done in one step. I'm still not sure that we should do it though, but I don't see any reason to not favor consistency right now so I'll create a ticket for this.

@AurelienRichez AurelienRichez force-pushed the feature/ETCM-1044-add-bestBlockHash branch 2 times, most recently from 68e270b to 223df14 Compare August 9, 2021 15:35
@AurelienRichez AurelienRichez force-pushed the feature/ETCM-1044-add-bestBlockHash branch from 223df14 to a9d4190 Compare August 10, 2021 08:47
Aurélien Richez added 5 commits August 10, 2021 12:17
rename putBestBlockData to putBestBlockInfo

avoid using magic number for block number in test
@AurelienRichez AurelienRichez force-pushed the feature/ETCM-1044-add-bestBlockHash branch 3 times, most recently from ec740a6 to e6d128c Compare August 10, 2021 11:28
@AurelienRichez AurelienRichez force-pushed the feature/ETCM-1044-add-bestBlockHash branch from e6d128c to beb908b Compare August 10, 2021 12:48
@AurelienRichez AurelienRichez force-pushed the feature/ETCM-1044-add-bestBlockHash branch from f71d59a to 6b3202f Compare August 11, 2021 13:17
@AurelienRichez AurelienRichez merged commit 526eb96 into develop Aug 11, 2021
@AurelienRichez AurelienRichez deleted the feature/ETCM-1044-add-bestBlockHash branch August 11, 2021 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants