Skip to content

Conversation

TheBlueMatt
Copy link
Contributor

CChainState should eventually, essentially, be our exposed "libconsensus", but we're probably a few releases away, so the real goal is to clarify our internal interfaces. The main split was a big step, but validation.cpp is still a somewhat ranomly-mixed bag of functions that are pure functions which validate inputs (which should probably either merge with their callers or move into another file in consensus/), read/write data from disk, manipulate our current chain state (which moves into CChainState), and do mempool transaction validation.

Obviously this is only a small step, but some effort is made to clean up what functions the functions in CChainState call, and obviously as things are added its easy to keep clear "CChainState::* cannot call anything except via callbacks through CValidationInterface, pure functions, or disk read/write things". Right now there are some glaring violations in mempool callbacks, and general flushing logic needs cleaning up (FlushStateToDisk maybe shouldnt be called, and there should be an API towards setDirtyBlockIndex, but I'll leave that for after @sipa's current changesets land).

@TheBlueMatt
Copy link
Contributor Author

Obviously the end goal here is to take revenge for #771 :)

@@ -3511,9 +3538,9 @@ CBlockIndex * InsertBlockIndex(uint256 hash)
return pindexNew;
}

bool static LoadBlockIndexDB(const CChainParams& chainparams)
bool CChainState::Load(CBlockTreeDB& blocktree)
Copy link
Contributor

@jtimon jtimon Apr 27, 2017

Choose a reason for hiding this comment

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

The CChainParams are still needed (or at least Consensus::Params) see #9176

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably better to move the CheckProofOfWord check into CChainParams::InsertBlockIndex (or the lambda). As eventually CChainParams should be a local variable inside CChainState, any objections to leaving this for later?

Copy link
Contributor

Choose a reason for hiding this comment

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

What lambda?
Anyway, if we plan not to do #9176 and moving the check instead, then there's no point in passing Consensus::Params to CChainState::Load if it's going to be only temporary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

eg the CheckProofOfWork call that is currently in LoadBlockIndexGuts can just go in the insertBlockIndex lambda function and the call to that should be a fully-filled CBlockIndex instead of that getting filled by LoadBlockIndexGuts.

return CDiskBlockPos();
}
if (dbp == NULL) {
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is the only use of chainparams, perhaps it is better to just pass chainparams.MessageStart() directly instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seems somewhat strange for CChainState to care at all about the existance of MessageStart(), no?

Copy link
Contributor

Choose a reason for hiding this comment

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

Strange or not, it does care about ut. It seems more strange for this new function to take the whole CChainParams class only for one getter, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well CChainState doesn't care about MessageStart(), it only cares that the write function figures out what it needs to do, if that means using Messagestart() thats between the write function and chainparams, not CChainState's business. Eventually the write function should be a virtual function inside an interface class and that class can hold the chainparams locally with CChainState only having a Consensus::Params.

Copy link
Contributor

Choose a reason for hiding this comment

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

CChainState::Load definitely cares about MessageStart(). But we disagree on next steps, I won't insist further.

@@ -1446,8 +1446,12 @@ bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint
return true;
}

bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex *pindex)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think UndoReadFromDisk can be static.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is already in an anonymous namespace, which I believe is equivalent.

CDiskBlockPos _pos;
if (!FindUndoPos(state, pindex->nFile, _pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
return error("ConnectBlock(): FindUndoPos failed");
if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, If this is the only use of chainparams, perhaps it is better to just pass chainparams.MessageStart() directly instead.

return false;
}
};
};
Copy link
Contributor

Choose a reason for hiding this comment

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

There was a PR uniforming comments for ending namespaces. Also, according to our style, we don't indent on namespaces: https://github.com/bitcoin/bitcoin/blob/master/src/.clang-format#L32

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

AbortNode(state, "Failed to write block");
CDiskBlockPos blockPos = WriteBlockToDisk(block, pindex->nHeight, chainparams, dbp);
if (blockPos.IsNull()) {
state.Error("AcceptBlock(): Failed to find position to write new block to disk");
Copy link
Contributor

Choose a reason for hiding this comment

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

strprintf("%s: Failed to find position to write new block to disk", __func__)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

if (dbp != NULL)
blockPos = *dbp;
if (!FindBlockPos(blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) {
error("AcceptBlock(): FindBlockPos failed");
Copy link
Contributor

Choose a reason for hiding this comment

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

strprintf("%s: FindBlockPos failed", __func__)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@jtimon
Copy link
Contributor

jtimon commented Apr 27, 2017

utACK (beyond nits, most of them not very important):

  • Make DisconnectBlock unaware of where undo data resides on disk e32dc53af14aa28d936da9c9b5a80b5fe522ad18
  • Create initial CChainState to hold chain state information 20aa3811df65e39d60572876ab2850eea6194429
  • Move block writing out of AcceptBlock 33aad08c6e7b0a9e291163c39538bee00be7e953
  • Move some additional variables into CChainState private 0acb237f752c0cf7fd783e8c09c0cb55203a6a83

Still trying to understand: Make ConnectBlock unaware of txindex/undo data disk locations f2e9d9a5d8d57b277634c5f822134aab7fc05b7b

Copy link
Member

@instagibbs instagibbs left a comment

Choose a reason for hiding this comment

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

not-expert utACK aside from fTxIndex question


if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
Copy link
Member

Choose a reason for hiding this comment

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

just noting: previously the following two lines are hit even if this conditional isn't true(and pindex->GetUndoPos().IsNull() is). No idea if this is a behavior change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, it may be, though not sure you could ever tickle it. I went ahead and duplicated the setDirtyBlockIndex.insert() call inside of WriteUndoDataForBlock.

pos.nTxOffset += ::GetSerializeSize(*tx, SER_DISK, CLIENT_VERSION);
}

if (fTxIndex)
Copy link
Member

Choose a reason for hiding this comment

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

Why do any of this if fTxIndex is false?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because it used to be? Anyway, fixed in new commit.

@TheBlueMatt
Copy link
Contributor Author

Removed InsertBlockIndex from validation.h since it was moved into CChainState (there were no external callers already).

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK c431484b612c68d4faf7f8d6af858729f2b9a56d.

No major comments, just a lot of suggestions, which you should feel free to ignore if not worth implementing.

I do think it would be nice if you added another commit which deleted the
mapBlockIndex chainActive pindexBestInvalid mapBlocksUnlinked global references. It would make CChainState start to look more like a normal class.

{
CDiskBlockPos pos = pindex->GetUndoPos();
if (pos.IsNull())
return error("%s: Undo data not available", __func__);
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Make DisconnectBlock unaware of where undo data resides on disk"

Note slight change in behavior here. "no undo data available" is now "Undo data not available"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reverted the string change.

Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Make DisconnectBlock unaware of where undo data resides on disk"

String changed back again. Did you maybe rebase an older version of this PR? It seems like some of the changes you made between https://github.com/bitcoin/bitcoin/commits/c431484b612c68d4faf7f8d6af858729f2b9a56d and https://github.com/bitcoin/bitcoin/commits/120743a83f26923cd9ef4db068fd6c9b8b8ea4dd got reverted.

@@ -1624,6 +1624,43 @@ void static FlushBlockFile(bool fFinalize = false)

bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);

static bool WriteUndoDataForBlock(const CBlockUndo& blockundo, CValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams)
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Make ConnectBlock unaware of txindex/undo data disk locations"

MaybeWriteUndoDataForBlock might be a more descriptive name.

vPos.reserve(block.vtx.size());
for (const CTransactionRef& tx : block.vtx)
{
vPos.push_back(std::make_pair(tx->GetHash(), pos));
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Make ConnectBlock unaware of txindex/undo data disk locations":

This is just moved code, but could get rid of make_pair using emplace_back here. Could also get rid of pos variable using vPos.back().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Clarified in the commit message instead, thanks for pointing this out (the intent is to not do the actual reading from disk calls inside of CChainState). Will leave other cleanups for later PRs.

@@ -98,6 +98,7 @@ class CChainState {
bool Load(CBlockTreeDB& blocktree);

private:
/** Create a new block index entry for a given block hash */
Copy link
Contributor

Choose a reason for hiding this comment

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

Should squash the two "Create initial CChainState to hold chain state information" commits.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, no idea how that came about, thanks.

*
* It generally provides access to the current chain tree, as well as functions
* to provide it new data, which it will appropriately validate and incorporate
* in its state as neccessary.
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Create initial CChainState to hold chain state information"

Spelling "necessary"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

{
if (!pblocktree->LoadBlockIndexGuts(InsertBlockIndex))
if (!blocktree.LoadBlockIndexGuts([this](uint256 hash){ return this->InsertBlockIndex(hash); }))
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Create initial CChainState to hold chain state information"

Probably should pass hash by const reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, not actually 100% sure why that compiled...

std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
CBlockIndex *pindexBestInvalid;

bool Load(CBlockTreeDB& blocktree);
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Create initial CChainState to hold chain state information"

Maybe Load and InsertBlockIndex should be static while they aren't (yet?) accessing any class members.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Load adds to mapBlocksUnlinked and InsertBlockIndex into mapBlockIndex. In the next PR mapBlockIndex and chainActive will be const when accessed via the global references, so would prefer to leave it.

@@ -3278,6 +3324,8 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation
if (fCheckForPruning)
FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files

CheckBlockIndex(chainparams.GetConsensus());
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move a bunch of chainstate-manipulation functions into CChainState"

CheckBlockIndex call added accidentally here? Behavior change should probably go in a separate commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was to replace the one removed from ProcessNewBlock. Should be +/- equivalent to the old version, I believe?

CBlockIndex *pindex = AddToBlockIndex(block);
CValidationState state;
if (!ReceivedBlockTransactions(block, state, pindex, blockPos, consensusParams)) {
return error("LoadBlockIndex(): genesis block not accepted");
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move a bunch of chainstate-manipulation functions into CChainState":

LoadBlockIndex should be ReceiveGenesisBlock or __func__ now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed


bool ReceiveGenesisBlock(const CBlock &block, const CDiskBlockPos& blockPos, const Consensus::Params& consensusParams);

void UnloadBlockIndex();
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move a bunch of chainstate-manipulation functions into CChainState"

Maybe this method should just be called Unload to be consistent with the Load method (which was previously LoadBlockIndexDB)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed Load to LoadBlockIndex instead.

@TheBlueMatt TheBlueMatt force-pushed the 2016-12-cconsensus branch 2 times, most recently from df00f69 to 120743a Compare May 3, 2017 00:20
@TheBlueMatt
Copy link
Contributor Author

As for removing the global references to member parts of CChainState...that's probably a ways out. First step is to clarify the internal stuff within validation.cpp and make external accesses to it const, then I'll expose the class itself (unless you feel particularly inclined to build the scripted diff before I get to it - need #10189 first, probably.

@ryanofsky
Copy link
Contributor

utACK 120743a83f26923cd9ef4db068fd6c9b8b8ea4dd

@TheBlueMatt
Copy link
Contributor Author

Rebased.

@TheBlueMatt TheBlueMatt force-pushed the 2016-12-cconsensus branch from 120743a to 895c0bd Compare June 6, 2017 01:34
Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

Started re-reviewing this, but it looks like there was a problem with the rebase and some changes were lost.

{
CDiskBlockPos pos = pindex->GetUndoPos();
if (pos.IsNull())
return error("%s: Undo data not available", __func__);
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Make DisconnectBlock unaware of where undo data resides on disk"

String changed back again. Did you maybe rebase an older version of this PR? It seems like some of the changes you made between https://github.com/bitcoin/bitcoin/commits/c431484b612c68d4faf7f8d6af858729f2b9a56d and https://github.com/bitcoin/bitcoin/commits/120743a83f26923cd9ef4db068fd6c9b8b8ea4dd got reverted.

*
* Eventually, the API here is targeted at being exposed externally as a
* consumable libconsensus library, so any functions added must only call
* external functions via callbacks, or to read/write data from disk.
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Create initial CChainState to hold chain state information"

CChainState comment updates made previously seem to be lost, pindexBestInvalid initialization is gone, LoadBlockIndex() got changed back to Load(), and InsertBlockIndex() documentation is gone.

@TheBlueMatt TheBlueMatt force-pushed the 2016-12-cconsensus branch from 895c0bd to 5f2135f Compare June 9, 2017 17:25
@TheBlueMatt
Copy link
Contributor Author

Indeed, rebased the copy that was on my workstation and not my laptop, re-rebased.

@TheBlueMatt TheBlueMatt force-pushed the 2016-12-cconsensus branch from 5f2135f to 5eb9eed Compare June 9, 2017 17:28
@sipa
Copy link
Member

sipa commented Jun 13, 2017

Nice, concept ACK

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK 5eb9eede5804b9c25b50429006a005a75a95da0f. Confirmed only changes since last review were fixing rebase conflicts, adding {} around some if statements, restoring a deleted comment.

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

Started looking at this to re-ack, but it looks like the wrong version of the branch got rebased and pushed again. I think if you just rebase 5eb9eede5804b9c25b50429006a005a75a95da0f top of current master, that should fix it.

*
* Eventually, the API here is targeted at being exposed externally as a
* consumable libconsensus library, so any functions added must only call
* external functions via callbacks, or to read/write data from disk.
Copy link
Contributor

Choose a reason for hiding this comment

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

Thread #10279 (comment)

Newer comment got reverted somehow. It was:

/**
 * CChainState stores and provides an API to update our local knowledge of the
 * current best chain and header tree.
 *
 * It generally provides access to the current block tree, as well as functions
 * to provide new data, which it will appropriately validate and incorporate in
 * its state as necessary.
 *
 * Eventually, the API here is targeted at being exposed externally as a
 * consumable libconsensus library, so any functions added must only call
 * other class member functions, pure functions in other parts of the consensus
 * library, callbacks, or read/write-to-disk functions (eventually this will
 * also be via callbacks).
 */

@TheBlueMatt
Copy link
Contributor Author

Rebased properly this time, with the various 0.15 changes.

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK 3b78b2d. All my comments are minor, feel free to ignore.


if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move txindex/undo data disk location stuff out of ConnectBlock"

It seems RaiseValidity call used to happen in the case pindex->GetUndoPos().IsNull() && pindex->IsValid(BLOCK_VALID_SCRIPTS) but now doesn't happen anymore.

Guessing this is not an issue but wanted to point out the change.

CDiskBlockPos blockPos;
if (dbp != nullptr)
blockPos = *dbp;
if (!FindBlockPos(blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != nullptr)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move block writing out of AcceptBlock"

You aren't changing this, but a harder to screw up interface to FindBlockPos might take an optional<CDiskBlockPos>& argument, instead of CDiskBlockPos& and fKnown arguments.

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'll leave interface changes for later - eventually I'd like to move the disk-writing/reading stuff out of validation.cpp, then it'll be easy to play with interfaces that wont even be exposed (plus the functions will reside beside each other, so harder to mess up).

@@ -3103,6 +3103,25 @@ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, CValidatio
}

/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
static CDiskBlockPos WriteBlockToDisk(const CBlock& block, int nHeight, const CChainParams& chainparams, const CDiskBlockPos* dbp) {
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move block writing out of AcceptBlock"

Might call this SaveBlockToDisk or since it doesn't actually write to disk if it's already written.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SaveBlockToDisk it is, that is much less confusing.

AbortNode(state, "Failed to write block");
CDiskBlockPos blockPos = WriteBlockToDisk(block, pindex->nHeight, chainparams, dbp);
if (blockPos.IsNull()) {
state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__));
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move block writing out of AcceptBlock":

This seems misleading since the error can also happen if the internal WriteBlockToDisk call fails. Maybe the new WriteBlockToDisk should just call state.Error itself, or return the error strings it already generates. Returning an error might also make sense because in both WriteBlockToDisk calls, the returned blockpos isn't actually used for anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The goal here is that SaveBlockToDisk falls outside the scope of our consensus logic, and, thus, should have no idea about CValidationStates. The errors when writing to disk are entirely separate (and logged themselves, so its not like its going to result in materially different useability here).

* consumable libconsensus library, so any functions added must only call
* other class member functions, pure functions in other parts of the consensus
* library, callbacks, or read/write-to-disk functions (eventually this will
* also be via callbacks).
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Create initial CChainState to hold chain state information"

Maybe mention:

  • Things that methods in this class should not be accessing. Presumably mempool & network?
  • Examples of where this class is currently doing something that it shouldn't and will be cleaned up later.

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 clarified that callbacks should all be via the validation interface. I think that is sufficiently restirctive? Anything not in those categories is clearly not kosher, not sure what specific examples should be given without trawling through the code there again.

CChain chainActive;
BlockMap mapBlockIndex;
std::multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
CBlockIndex *pindexBestInvalid = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Create initial CChainState to hold chain state information"

Since you're creating backwards compatible aliases for these variables anyway, it seems like you could easily give them updated names that follow the style guide (e.g. m_best_invalid_block).

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 wanted this PR to not conflict needlessly with every change to validation.cpp, so avoided doing so for now. In the future we should do that, agreed, but I dont want to rebase this PR every few days.



bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params);
} chainstate;
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move a bunch of chainstate-manipulation functions into CChainState"

Maybe g_chainstate

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

return true;
}

bool RewindBlockIndex(const CChainParams& params) {
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move a bunch of chainstate-manipulation functions into CChainState"

Two RewindBlockIndex functions with the same name & params but slightly different behavior seems not great.

Maybe should have RewindBlockIndexDB / CChainState::RewindBlockIndex, analogous to LoadBlockIndexDB / CChainState::LoadBlockIndex.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They dont (really) have different behavior, just the public wrapper version does a DB flush, but that isnt strictly required (I believe). But, really, CChainState/validation should have no concept of the DB backend in use/the disk, hence the reason for the flush outside, its just a thin wrapper functions to expose it publicly.

Copy link
Member

Choose a reason for hiding this comment

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

Agree with @ryanofsky. Especially since the other wrappers just forward to g_chainstate. Why not just flush in init after the RewindBlockIndex call?

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'd be fine with a flush in init, but it seems weird given its kinda a validation-disk-storage-layer thing, and I hate adding more low-level logic in init.

void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) {
chainActive.SetTip(pindexNew);
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "Move some additional variables into CChainState private"

This seems like a strange change. Maybe assert chainActive tip is pindexNew here? pindexNew argument is otherwise no longer used in this function.

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 think it feels strange mostly because UpdateTip is (now) poorly named - all it does is fire warnings, log messages, and a few notifications for mining longpolling. Eventually it should be a CValidationInterface listener (or its notifications should be routed through it. I went ahead and used pindexNew in place of chainActive.Tip() everywhere here.

@ryanofsky
Copy link
Contributor

Should this be merged? It has utACKs from jtimon, instagibbs, and me, and a concept ACK from sipa.

@TheBlueMatt
Copy link
Contributor Author

Addressed @ryanofsky's nits and noted where I disagreed.

@TheBlueMatt
Copy link
Contributor Author

Rebased.

@laanwj
Copy link
Member

laanwj commented Dec 12, 2017

utACK 22fddde

@laanwj laanwj merged commit 22fddde into bitcoin:master Dec 12, 2017
laanwj added a commit that referenced this pull request Dec 12, 2017
…er step towards clarifying internal interfaces

22fddde Avoid calling GetSerializeSize on each tx in a block if !fTxIndex (Matt Corallo)
2862aca Move some additional variables into CChainState private (Matt Corallo)
fd4d80a Create initial CChainState to hold chain state information (Matt Corallo)
e104f0f Move block writing out of AcceptBlock (Matt Corallo)
50701ba Move txindex/undo data disk location stuff out of ConnectBlock (Matt Corallo)
93a34cf Make DisconnectBlock unaware of where undo data resides on disk (Matt Corallo)

Pull request description:

  CChainState should eventually, essentially, be our exposed "libconsensus", but we're probably a few releases away, so the real goal is to clarify our internal interfaces. The main split was a big step, but validation.cpp is still a somewhat ranomly-mixed bag of functions that are pure functions which validate inputs (which should probably either merge with their callers or move into another file in consensus/), read/write data from disk, manipulate our current chain state (which moves into CChainState), and do mempool transaction validation.

  Obviously this is only a small step, but some effort is made to clean up what functions the functions in CChainState call, and obviously as things are added its easy to keep clear "CChainState::* cannot call anything except via callbacks through CValidationInterface, pure functions, or disk read/write things". Right now there are some glaring violations in mempool callbacks, and general flushing logic needs cleaning up (FlushStateToDisk maybe shouldnt be called, and there should be an API towards setDirtyBlockIndex, but I'll leave that for after @sipa's current changesets land).

Tree-SHA512: 69b8ec191b36b19c9492b4dee74c8057621fb6ec98ad219e8da0b2ed5c3ad711b10b5af9ff1117e8807ccf88918eeeab573be8448baecc9a59f099c53095985b
@theuni
Copy link
Member

theuni commented Dec 12, 2017

post-merge utACK 22fddde. Very nice!

PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Apr 2, 2020
…e another step towards clarifying internal interfaces

22fddde Avoid calling GetSerializeSize on each tx in a block if !fTxIndex (Matt Corallo)
2862aca Move some additional variables into CChainState private (Matt Corallo)
fd4d80a Create initial CChainState to hold chain state information (Matt Corallo)
e104f0f Move block writing out of AcceptBlock (Matt Corallo)
50701ba Move txindex/undo data disk location stuff out of ConnectBlock (Matt Corallo)
93a34cf Make DisconnectBlock unaware of where undo data resides on disk (Matt Corallo)

Pull request description:

  CChainState should eventually, essentially, be our exposed "libconsensus", but we're probably a few releases away, so the real goal is to clarify our internal interfaces. The main split was a big step, but validation.cpp is still a somewhat ranomly-mixed bag of functions that are pure functions which validate inputs (which should probably either merge with their callers or move into another file in consensus/), read/write data from disk, manipulate our current chain state (which moves into CChainState), and do mempool transaction validation.

  Obviously this is only a small step, but some effort is made to clean up what functions the functions in CChainState call, and obviously as things are added its easy to keep clear "CChainState::* cannot call anything except via callbacks through CValidationInterface, pure functions, or disk read/write things". Right now there are some glaring violations in mempool callbacks, and general flushing logic needs cleaning up (FlushStateToDisk maybe shouldnt be called, and there should be an API towards setDirtyBlockIndex, but I'll leave that for after @sipa's current changesets land).

Tree-SHA512: 69b8ec191b36b19c9492b4dee74c8057621fb6ec98ad219e8da0b2ed5c3ad711b10b5af9ff1117e8807ccf88918eeeab573be8448baecc9a59f099c53095985b
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Apr 2, 2020
…e another step towards clarifying internal interfaces

22fddde Avoid calling GetSerializeSize on each tx in a block if !fTxIndex (Matt Corallo)
2862aca Move some additional variables into CChainState private (Matt Corallo)
fd4d80a Create initial CChainState to hold chain state information (Matt Corallo)
e104f0f Move block writing out of AcceptBlock (Matt Corallo)
50701ba Move txindex/undo data disk location stuff out of ConnectBlock (Matt Corallo)
93a34cf Make DisconnectBlock unaware of where undo data resides on disk (Matt Corallo)

Pull request description:

  CChainState should eventually, essentially, be our exposed "libconsensus", but we're probably a few releases away, so the real goal is to clarify our internal interfaces. The main split was a big step, but validation.cpp is still a somewhat ranomly-mixed bag of functions that are pure functions which validate inputs (which should probably either merge with their callers or move into another file in consensus/), read/write data from disk, manipulate our current chain state (which moves into CChainState), and do mempool transaction validation.

  Obviously this is only a small step, but some effort is made to clean up what functions the functions in CChainState call, and obviously as things are added its easy to keep clear "CChainState::* cannot call anything except via callbacks through CValidationInterface, pure functions, or disk read/write things". Right now there are some glaring violations in mempool callbacks, and general flushing logic needs cleaning up (FlushStateToDisk maybe shouldnt be called, and there should be an API towards setDirtyBlockIndex, but I'll leave that for after @sipa's current changesets land).

Tree-SHA512: 69b8ec191b36b19c9492b4dee74c8057621fb6ec98ad219e8da0b2ed5c3ad711b10b5af9ff1117e8807ccf88918eeeab573be8448baecc9a59f099c53095985b
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Apr 6, 2020
…e another step towards clarifying internal interfaces

22fddde Avoid calling GetSerializeSize on each tx in a block if !fTxIndex (Matt Corallo)
2862aca Move some additional variables into CChainState private (Matt Corallo)
fd4d80a Create initial CChainState to hold chain state information (Matt Corallo)
e104f0f Move block writing out of AcceptBlock (Matt Corallo)
50701ba Move txindex/undo data disk location stuff out of ConnectBlock (Matt Corallo)
93a34cf Make DisconnectBlock unaware of where undo data resides on disk (Matt Corallo)

Pull request description:

  CChainState should eventually, essentially, be our exposed "libconsensus", but we're probably a few releases away, so the real goal is to clarify our internal interfaces. The main split was a big step, but validation.cpp is still a somewhat ranomly-mixed bag of functions that are pure functions which validate inputs (which should probably either merge with their callers or move into another file in consensus/), read/write data from disk, manipulate our current chain state (which moves into CChainState), and do mempool transaction validation.

  Obviously this is only a small step, but some effort is made to clean up what functions the functions in CChainState call, and obviously as things are added its easy to keep clear "CChainState::* cannot call anything except via callbacks through CValidationInterface, pure functions, or disk read/write things". Right now there are some glaring violations in mempool callbacks, and general flushing logic needs cleaning up (FlushStateToDisk maybe shouldnt be called, and there should be an API towards setDirtyBlockIndex, but I'll leave that for after @sipa's current changesets land).

Tree-SHA512: 69b8ec191b36b19c9492b4dee74c8057621fb6ec98ad219e8da0b2ed5c3ad711b10b5af9ff1117e8807ccf88918eeeab573be8448baecc9a59f099c53095985b
UdjinM6 added a commit to dashpay/dash that referenced this pull request Apr 11, 2020
* Merge bitcoin#10279: Add a CChainState class to validation.cpp to take another step towards clarifying internal interfaces

22fddde Avoid calling GetSerializeSize on each tx in a block if !fTxIndex (Matt Corallo)
2862aca Move some additional variables into CChainState private (Matt Corallo)
fd4d80a Create initial CChainState to hold chain state information (Matt Corallo)
e104f0f Move block writing out of AcceptBlock (Matt Corallo)
50701ba Move txindex/undo data disk location stuff out of ConnectBlock (Matt Corallo)
93a34cf Make DisconnectBlock unaware of where undo data resides on disk (Matt Corallo)

Pull request description:

  CChainState should eventually, essentially, be our exposed "libconsensus", but we're probably a few releases away, so the real goal is to clarify our internal interfaces. The main split was a big step, but validation.cpp is still a somewhat ranomly-mixed bag of functions that are pure functions which validate inputs (which should probably either merge with their callers or move into another file in consensus/), read/write data from disk, manipulate our current chain state (which moves into CChainState), and do mempool transaction validation.

  Obviously this is only a small step, but some effort is made to clean up what functions the functions in CChainState call, and obviously as things are added its easy to keep clear "CChainState::* cannot call anything except via callbacks through CValidationInterface, pure functions, or disk read/write things". Right now there are some glaring violations in mempool callbacks, and general flushing logic needs cleaning up (FlushStateToDisk maybe shouldnt be called, and there should be an API towards setDirtyBlockIndex, but I'll leave that for after @sipa's current changesets land).

Tree-SHA512: 69b8ec191b36b19c9492b4dee74c8057621fb6ec98ad219e8da0b2ed5c3ad711b10b5af9ff1117e8807ccf88918eeeab573be8448baecc9a59f099c53095985b

* fix

Signed-off-by: Pasta <pasta@dashboost.org>

* fix

Signed-off-by: Pasta <pasta@dashboost.org>

* More of 10279

Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
@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.

8 participants