Skip to content

Conversation

jtimon
Copy link
Contributor

@jtimon jtimon commented Aug 28, 2015

The genesis block is the truth: don't check it.
Apart from being a minimal optimization, this removes the necessity of "mining the genesis block" when new testchains are created. This is a necessary step for #6382 (which creates std::numeric_limits<uint64_t>::max() new testchains).

@dcousens
Copy link
Contributor

Apart from being a minimal optimization

How is this an optimization? You are now comparing the blocks hash against the genesis block every time ConnectBlock is called?

@jtimon
Copy link
Contributor Author

jtimon commented Aug 29, 2015

How is this an optimization?

By saving some checks for the genesis block.

You are now comparing the blocks hash against the genesis block every time ConnectBlock is called?

The check in ConnectBlock was already there, now CheckBlock is not called if the block being checked is the genesis block (ie the checks has just been moved below the genesis block check).

@jtimon
Copy link
Contributor Author

jtimon commented Aug 29, 2015

In any case, benchmarking welcomed.

@jtimon jtimon force-pushed the chainparams-genesis-no-check-0.12.99 branch from 13c5755 to b95a2f9 Compare November 11, 2015 22:52
@jtimon
Copy link
Contributor Author

jtimon commented Nov 11, 2015

Rebased and simplified. Looking at it again, @dcousens was right that many of the changes would have affected performance negatively. Besides they were (or at least they currently seem to be) unnecessary for #6382 (or for facilitating the creating of testchains in general by not requiring tester to "mine" the genesis block of their testchains: the genesis block is correct by definition).
Now it should be clear that we're just optimizing the genesis block case in ConnectBlock() without adding any work to the other cases, and we're only affecting negatively the performance of CBlockTreeDB::LoadBlockIndexGuts by comparing two hashes right before returning and error (only if CheckProofOfWork had previously failed), which I think is very acceptable.
So I don't think benchmarking this makes sense anymore.

@dcousens
Copy link
Contributor

utACK

@@ -203,7 +204,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
pindexNew->nStatus = diskindex.nStatus;
pindexNew->nTx = diskindex.nTx;

if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, Params().GetConsensus()))
if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams) &&
pindexNew->GetBlockHash() != consensusParams.hashGenesisBlock)
Copy link
Member

Choose a reason for hiding this comment

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

Is the genesis block expected to fail PoW?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not usually, but this is useful for creating new testchains (whether those testchains are merged in master or not) without having to spend costly PoW to "mine" a genesis block to hardcode.
For example, #6382 introduces std::numeric_limits<uint64_t>::max() new testchains whose genesis blocks are created dynamically (but not mined dynamically in chainparams.cpp) and will therefore fail PoW.
For any production chain, mining the genesis block is a meaningless cost, but for a testnet (specially regtest-like testchains) it is utterly absurd. Even for mainchain, Satoshi didn't need to mine the genesis block because it is correct by definition (or more accurately, it is part of the definition of how valid chains must be). Just in the same way, he could have decided to make the genesis subsidy spendable but he didn't (but changing that now would be a hardfork). The creator of the system worked in mysterious ways...

Copy link
Member

Choose a reason for hiding this comment

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

Fair enough.

@sipa
Copy link
Member

sipa commented Nov 12, 2015

ACK

@gmaxwell
Copy link
Contributor

Care to pass in the params from above like #6986?

@jtimon
Copy link
Contributor Author

jtimon commented Nov 17, 2015

@gmaxwell you mean passing it explicitly to CBlockTreeDB::LoadBlockIndexGuts()?

@gmaxwell
Copy link
Contributor

@jtimon Right. Do you agree it would be the correct and consistent thing to do?

@jtimon
Copy link
Contributor Author

jtimon commented Nov 17, 2015

Sure, using the local variable is in preparation for that at some point later (see #5970), but I'm happy to do it here directly.

@jtimon jtimon force-pushed the chainparams-genesis-no-check-0.12.99 branch from b95a2f9 to e4037dd Compare November 17, 2015 13:54
@jtimon
Copy link
Contributor Author

jtimon commented Nov 17, 2015

Updated with @gmaxwell 's nit solved.

@sipa
Copy link
Member

sipa commented Nov 28, 2015

Still ACK

@jtimon
Copy link
Contributor Author

jtimon commented Dec 18, 2015

still ping, I've been thinking about closing this and reopen it whith a test that makes sure a new non-mined chain wold work (that means another chain in master),

@jtimon jtimon closed this Dec 18, 2015
@dcousens
Copy link
Contributor

re-ACK e4037dd, @jtimon test sounds good too 👍

@jtimon jtimon reopened this Dec 18, 2015
@sipa
Copy link
Member

sipa commented Jan 6, 2016

From experience elsewhere: if you introduce a new chain with an "invalid" genesis block and this change, it will fail to reindex, as the check is still done in that case.

Suggested fix: see sipa@f7a1a47

@jtimon
Copy link
Contributor Author

jtimon commented Jan 7, 2016

Mhmm, why #6382 seems to be working just fine with reindex then? Have you actually reproduced the error you claim would appear?

This shouldn't be necessary, certainly not in CheckBlockHeader(). In AcceptBlockHeader, it won't be called for the genesis block, see https://github.com/bitcoin/bitcoin/blob/master/src/main.cpp#L3071
Maybe it is required on TestBlockValidity() or something else that calls CheckBlock() (which calls CheckBlockHeader()), but I would prefer to leave the genesis block check out of the consensus function CheckBlockHeader().

Probably a good test for this would be to create a new regtest-like chain with a genesis block that doesn't satisfy the proof of work and run it for a few blocks both with and without reindex from the python tests. But without #6907 and something like jtimon@98923c3 it seems like the testing would be much more than the change itself.

@laanwj
Copy link
Member

laanwj commented Jan 18, 2016

Let's try to get agreement here @sipa @jtimon

@sipa
Copy link
Member

sipa commented Jan 18, 2016 via email

@jtimon
Copy link
Contributor Author

jtimon commented Jan 19, 2016

Genesis blocks are valid by definition and should never be checked (whether they pass pow or not).
In any case, IIRC last time I tested #6382 it worked just fine even when reindexing the chain, therefore I disagree with sipa that this patch isn't enough. As said the very fact that we disagree on whether or not this is enough for its stated goal, means IMO that this should be introduced with tests that verify this is enough and will keep being enough in the future (make sure nobody undoes this without noticing).
I believe the best way to test this is through a new chain whose genesis block doesn't pass pow (regtest2 ?) And test boh with and without reindex.

Does that make sense?

Addionally, I don't plan to create a new chain without #6907 (and generic selection with -chain, also part of #6382 ),and that's why I'm closing this for now.
Anyone feel free to take over this if you can't wait for the factory. I've personally been wanting this factory for almost two years, I can wait more for #6907 to be merged (was supposed to happen before forking 0.12, I really hope it will happen before forking 0.13.

@jtimon jtimon closed this Jan 19, 2016
@sipa sipa reopened this Jan 21, 2016
@sipa
Copy link
Member

sipa commented Jan 21, 2016

I'm not against merging this! I was simply giving a suggestion for further work towards its stated goal.

@jtimon
Copy link
Contributor Author

jtimon commented Jan 21, 2016

And I'm saying I believe this is enough for fulfilling its stated goal, but the fact that we disagree means we should introduce tests here to make sure the goal is achieved (and later merges don't ruin it).
But as said I don't plan to write those tests until #6907. This was not merged before forking 0.12 so I'm not in a hurry anyway. As long as I reopen it before 0.13 is forked I'm happy closing it for now.
I can leave this opened as incomplete, but I wanted people interested in making new testchains easier (most of what #6382 was about) to focus on #6907 first. #6907 was supposed to be merged before 0.12 and is also more costly to maintain rebased, can we please do that first?

@jtimon jtimon closed this Jan 28, 2016
jtimon added a commit to jtimon/bitcoin that referenced this pull request Mar 11, 2016
…id (HF for bitcoin)

- Like in bitcoin#6597 (bitcoin), the genesis block shouldn't be checked
because it is a consensus rule in itself

- On the other hand, some elements like deterministic peg (because the
  21M reserve of pegged-coins needs to be created at some point) and
  multi-assets (because one cannot define new assets without existing
  utxos to be used as input for the asset definition transactions)
jtimon added a commit to jtimon/bitcoin that referenced this pull request Mar 11, 2016
…s asvalid (HF for bitcoin)

- Like in bitcoin#6597 (bitcoin), the genesis block shouldn't be checked
because it is a consensus rule in itself

- On the other hand, some elements like deterministic peg (because the
  21M reserve of pegged-coins needs to be created at some point) and
  multi-assets (because one cannot define new assets without existing
  utxos to be used as input for the asset definition transactions)
jtimon referenced this pull request in sipa/bitcoin Apr 6, 2016
Rebased by Pieter Wuille.
Cleanup by Matt Corallo.
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants