Skip to content

Conversation

sdaftuar
Copy link
Member

Previously, we could release cs_main while leaving the block index in a state
that would fail CheckBlockIndex(), because setBlockIndexCandidates was not being
fully populated before releasing cs_main.

@sdaftuar
Copy link
Member Author

See #16444 (comment) for additional background.

// Instead, consider only non-active-chain blocks that have at
// least as much work as where we expect the new tip to end up.
if (!m_chain.Contains(candidate) &&
!CBlockIndexWorkComparator()(candidate, pindex->pprev) &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Won't this potentially omit candidates with equal work as pindex->pprev (depending on nSequenceId/pointer address)?

Copy link
Member Author

Choose a reason for hiding this comment

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

I believe this exactly matches the test in CheckBlockIndex():

if (!CBlockIndexWorkComparator()(pindex, m_chain.Tip()) && pindexFirstNeverProcessed == nullptr) {

Previously, we could release cs_main while leaving the block index in a state
that would fail CheckBlockIndex, because setBlockIndexCandidates was not being
fully populated before releasing cs_main.
@sdaftuar sdaftuar force-pushed the 2019-09-fix-invalidate-block-consistency branch from bfd4fde to 2a4e60b Compare September 10, 2019 18:55
@sdaftuar
Copy link
Member Author

The only remaining case I've thought of that is unaddressed is if a new block were to arrive while InvalidateBlock() is running that (a) builds off a chain tip that is not being invalidated and (b) has less work than the current tip at the time the block is received, then we might still end up in a state that is temporarily inconsistent. I left in the old code that cleans up before returning as a belt-and-suspenders to ensure that this case is handled the same as before.

As this is an essentially unobservable bug (outside of travis) to begin with, I'm not sure it would be worth fixing this any further beyond documenting the situation.

@TheBlueMatt
Copy link
Contributor

utACK 2a4e60b. I also discovered another issue in InvalidateBlock while reviewing, see #16856.

@Sjors
Copy link
Member

Sjors commented Sep 30, 2019

ACK 2a4e60b. Tested on top of #16899. Also tested invalidateblock with -checkblockindex=1.

The changed code is only called by the invalidateblock RPC.

Nit: maybe mention InvalidateBlock() as well in validation.h comment for CCriticalSection m_cs_chainstate.

@fjahr
Copy link
Contributor

fjahr commented Oct 1, 2019

ACK 2a4e60b. Ran tests, reviewed code, inspected behavior while manually testing invalidateblock.

@laanwj laanwj mentioned this pull request Oct 2, 2019
19 tasks
laanwj added a commit that referenced this pull request Oct 2, 2019
2a4e60b Fix block index inconsistency in InvalidateBlock() (Suhas Daftuar)

Pull request description:

  Previously, we could release `cs_main` while leaving the block index in a state
  that would fail `CheckBlockIndex()`, because `setBlockIndexCandidates` was not being
  fully populated before releasing `cs_main`.

ACKs for top commit:
  TheBlueMatt:
    utACK 2a4e60b. I also discovered another issue in InvalidateBlock while reviewing, see #16856.
  Sjors:
    ACK 2a4e60b. Tested on top of #16899. Also tested `invalidateblock` with `-checkblockindex=1`.
  fjahr:
    ACK 2a4e60b. Ran tests, reviewed code, inspected behavior while manually testing `invalidateblock`.

Tree-SHA512: ced12f9dfff0d413258c709921543fb154789898165590b30d1ee0cdc72863382f189744f7669a7c924d3689a1cc623efdf4e5ae3efc60054572c1e6826de612
@laanwj laanwj merged commit 2a4e60b into bitcoin:master Oct 2, 2019
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 2, 2019
2a4e60b Fix block index inconsistency in InvalidateBlock() (Suhas Daftuar)

Pull request description:

  Previously, we could release `cs_main` while leaving the block index in a state
  that would fail `CheckBlockIndex()`, because `setBlockIndexCandidates` was not being
  fully populated before releasing `cs_main`.

ACKs for top commit:
  TheBlueMatt:
    utACK 2a4e60b. I also discovered another issue in InvalidateBlock while reviewing, see bitcoin#16856.
  Sjors:
    ACK 2a4e60b. Tested on top of bitcoin#16899. Also tested `invalidateblock` with `-checkblockindex=1`.
  fjahr:
    ACK 2a4e60b. Ran tests, reviewed code, inspected behavior while manually testing `invalidateblock`.

Tree-SHA512: ced12f9dfff0d413258c709921543fb154789898165590b30d1ee0cdc72863382f189744f7669a7c924d3689a1cc623efdf4e5ae3efc60054572c1e6826de612
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Aug 18, 2020
Summary:
Future [[bitcoin/bitcoin#16849 | PR16849]] (D7204) introduces locking `m_cs_chainstate` to their version of `InvalidateBlock`. Our codepath for that is shared by `ParkBlock`, `InvalidateBlock` and `FinalizeBlock`, so having all three be members of `CChainState` (`FinalizeBlock` already is) makes sense.

Also made `UnwindBlock` private since it's not supposed to be called by just anyone, rather by stuff that knows what they're doing -, and moved `FinalizeBlock` implementation to be closer to the other two since that makes more sense.

Test Plan:
  cmake .. -DCMAKE_BUILD_TYPE=Debug -GNinja
  ninja check check-functional

Reviewers: #bitcoin_abc, deadalnix

Reviewed By: #bitcoin_abc, deadalnix

Differential Revision: https://reviews.bitcoinabc.org/D7203
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Aug 18, 2020
Summary:
Fix block index inconsistency in InvalidateBlock() (Suhas Daftuar)

Pull request description:

  Previously, we could release `cs_main` while leaving the block index in a state
  that would fail `CheckBlockIndex()`, because `setBlockIndexCandidates` was not being
  fully populated before releasing `cs_main`.

---

Note: Because of the way our version of "InvalidateBlock" is in the codepath for Park, Invalidate and FinalizeBlock, the lock for m_cs_chainstate needs to appear in additional places.

Backport of Core [[bitcoin/bitcoin#16849 | PR16849]]

Depends on D6956

Test Plan:
  cmake -DCMAKE_BUILD_TYPE=Debug -DNinja
  ninja check check-functional

Reviewers: #bitcoin_abc, deadalnix

Reviewed By: #bitcoin_abc, deadalnix

Subscribers: deadalnix

Differential Revision: https://reviews.bitcoinabc.org/D7204
UdjinM6 pushed a commit to UdjinM6/dash that referenced this pull request Oct 29, 2021
2a4e60b Fix block index inconsistency in InvalidateBlock() (Suhas Daftuar)

Pull request description:

  Previously, we could release `cs_main` while leaving the block index in a state
  that would fail `CheckBlockIndex()`, because `setBlockIndexCandidates` was not being
  fully populated before releasing `cs_main`.

ACKs for top commit:
  TheBlueMatt:
    utACK 2a4e60b. I also discovered another issue in InvalidateBlock while reviewing, see bitcoin#16856.
  Sjors:
    ACK 2a4e60b. Tested on top of bitcoin#16899. Also tested `invalidateblock` with `-checkblockindex=1`.
  fjahr:
    ACK 2a4e60b. Ran tests, reviewed code, inspected behavior while manually testing `invalidateblock`.

Tree-SHA512: ced12f9dfff0d413258c709921543fb154789898165590b30d1ee0cdc72863382f189744f7669a7c924d3689a1cc623efdf4e5ae3efc60054572c1e6826de612
pravblockc pushed a commit to pravblockc/dash that referenced this pull request Nov 18, 2021
2a4e60b Fix block index inconsistency in InvalidateBlock() (Suhas Daftuar)

Pull request description:

  Previously, we could release `cs_main` while leaving the block index in a state
  that would fail `CheckBlockIndex()`, because `setBlockIndexCandidates` was not being
  fully populated before releasing `cs_main`.

ACKs for top commit:
  TheBlueMatt:
    utACK 2a4e60b. I also discovered another issue in InvalidateBlock while reviewing, see bitcoin#16856.
  Sjors:
    ACK 2a4e60b. Tested on top of bitcoin#16899. Also tested `invalidateblock` with `-checkblockindex=1`.
  fjahr:
    ACK 2a4e60b. Ran tests, reviewed code, inspected behavior while manually testing `invalidateblock`.

Tree-SHA512: ced12f9dfff0d413258c709921543fb154789898165590b30d1ee0cdc72863382f189744f7669a7c924d3689a1cc623efdf4e5ae3efc60054572c1e6826de612
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 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.

7 participants