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

validation: Give m_block_index ownership of CBlockIndexs #24050

Merged
merged 6 commits into from
Mar 7, 2022

Conversation

dongcarl
Copy link
Contributor

@dongcarl dongcarl commented Jan 12, 2022

Part of: #24303
Split off from: #22564

Instead of having CBlockIndex's live on the heap, which requires manual
memory management, have them be owned by m_block_index. This means that
they will live and die with BlockManager.

The second commit demonstrates how this makes calls to Unload() to satisfy the address sanitizer unnecessary.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

Left some nits. Feel free to ignore any or all of them.

src/node/blockstorage.cpp Outdated Show resolved Hide resolved
src/validation.cpp Outdated Show resolved Hide resolved
src/validation.cpp Outdated Show resolved Hide resolved
src/node/blockstorage.h Outdated Show resolved Hide resolved
@dongcarl
Copy link
Contributor Author

Okay I'm still reserving my right to ignore future nits, but these one struck a soft spot in my heart so I incorporated them 😁

Copy link
Member

@jamesob jamesob left a comment

Choose a reason for hiding this comment

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

ACK 8fb03ca (jamesob/ackr/24050.1.dongcarl.validation_move_cblockin)

Good change! For what it's worth, my previous benchmarking may be a relevant consideration for reviewers: #22564 (comment)

Some of the intermediate commits could probably be squashed, but that doesn't bother me much either way.

I've compiled each commit and run unittests locally.

Show signature data

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

ACK 8fb03ca47c01907b98461b8d538e2691d7ef65af ([`jamesob/ackr/24050.1.dongcarl.validation_move_cblockin`](https://github.com/jamesob/bitcoin/tree/ackr/24050.1.dongcarl.validation_move_cblockin))

Good change! For what it's worth, my previous benchmarking may be a relevant consideration for reviewers: https://github.com/bitcoin/bitcoin/pull/22564#issuecomment-930377301

Some of the intermediate commits could probably be squashed, but that doesn't bother me much either way.

I've compiled each commit and run unittests locally.
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEGNRVI1NPYuZCSIrGepNdrbLETwUFAmHnJrIACgkQepNdrbLE
TwWLJhAAi3IfNFNZIaqTnTfMw8V9W8v2K2wNXT29tsj09JVTaJ5PGpQ9WoBbrkP+
cTtTvmlJ71X9VvRERPL0oz8A4YF1/QOPj9NJ+ZVE3NLg3z6rTbn5PFCqBNUYUvp/
a+qLshzpCsluQKs7B+70qpu0L589yYEcO6cKHVRVPLi8jrJxCc7/lEo2GdCjD2xJ
nxj0Pu+O+erN7zhVZ4evqOr6j+XSufHn6xiqm7DdGXzyafQzpPB3h5FJxVPZbh5p
PI5plMf5WcxPePd8ynE5v/wnKCZkaMhJm1cNC9D/MjmJUIPZyx8ngJoKPllgztHf
UzKZ0n7MBPHwFdsMGraKq0VCotD/ZxFGbeNtXaI0BLZfjA2Xyf1vaFFfNRg5uZHe
d45/Sa8uDQjVApxQtIbfRMGNFVms5pr8SrNuPvJ0EDIXtYXXuEvkVmX5lhkz39Sy
GO4/IbqBiT7md+dk7J7h5M6j3C5LnyiFWJzqS418//kk24/KSF6/kwGzXp1ASweY
H85Efa9xq8dr1KBiSw9wZ0U3RFpqOyz+/0ejzrBVxtMjd9x49RF4MRmakNPi/P4D
+SVBS0e0gr/FV0CW501tc5gZYMC3UK+whGcmaCT0LRjjQlpFv0M1sZZbA6CGdFYQ
zFR7x0aXcIZjByDECGMi9+T6c3Mi0yGa2ulc8uO7vo3DNLuTJOQ=
=f/Ec
-----END PGP SIGNATURE-----

Show platform data

Tested on Linux-5.10.0-10-amd64-x86_64-with-glibc2.31

Configured with ./configure LDFLAGS=-L/home/james/src/bitcoin/db4/lib/ CPPFLAGS=-I/home/james/src/bitcoin/db4/include/ CXXFLAGS=-fPIE -pipe -O2 -g -Wthread-safety-analysis -Wall -Werror=sign-compare -Wsign-compare -Werror=thread-safety-analysis --enable-wallet --enable-debug --with-daemon --enable-natpmp-default CXX=/usr/local/bin/clang++ CC=/usr/local/bin/clang --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental PYTHONPATH= --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental --no-create --no-recursion

Compiled with /usr/bin/ccache /usr/local/bin/clang++ -std=c++17 -mavx -mavx2 -mpclmul -fPIE -pipe -O2 -g -Wthread-safety-analysis -Wall -Werror=sign-compare -Wsign-compare -Werror=thread-safety-analysis -O0 -g3 -ftrapv -fdebug-prefix-map=$(abs_top_srcdir)=.  -Wstack-protector -fstack-protector-all -fcf-protection=full -fstack-clash-protection -msse4 -msha -msse4.1 -msse4.2  i

Compiler version: Debian clang version 13.0.1-++20220112082946+b9a243d1cac2-1~exp1~20220112203027.57

Copy link
Contributor

@ajtowns ajtowns left a comment

Choose a reason for hiding this comment

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

ACK 8fb03ca ; code review only. some more nits you may want to consider

src/node/blockstorage.cpp Outdated Show resolved Hide resolved
src/validation.cpp Outdated Show resolved Hide resolved
@@ -3428,7 +3428,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
if (hash != chainparams.GetConsensus().hashGenesisBlock) {
if (miSelf != m_blockman.m_block_index.end()) {
// Block header is already known.
CBlockIndex* pindex = miSelf->second;
CBlockIndex* pindex = &(miSelf->second);
Copy link
Contributor

Choose a reason for hiding this comment

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

Adding brackets to distinguish from (&miSelf)->second doesn't seem that useful to me...

@maflcko
Copy link
Member

maflcko commented Jan 19, 2022

For reference, the stuff is still on the heap. This only changes the layout a bit.

Master:

Screenshot from 2022-01-19 18-25-45

This:

Screenshot from 2022-01-19 18-27-02

@dongcarl dongcarl changed the title validation: Move CBlockIndexs from heap to m_block_index validation: Give m_block_index ownership of CBlockIndexs Jan 19, 2022
@dongcarl
Copy link
Contributor Author

Pushed 8fb03ca -> c68516d

  • Some more modernizations

Anything else this needs before it's ready for merge?

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

left some style nits. Feel fee to ignore any or all. I am happy to re-ACK if you don't.

review ACK c68516d 🍏

Show signature

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

review ACK c68516d662687699b399f8d12e22f2e985edae1a 🍏
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUiTPgv8CbaBOK51qXPuhdeM7/DZJAMYFCAPOYAsAHSD7mrO1PG/7wA5vUW2ffGY
U2yM/rLCnBBCITrcrOygU61k72HPwgGTQ7jG0zV5+A339cAbnpJBm5+O8ky5/+NJ
/88BlcGNOmmZwUnuRLOwWwILDvNKPb4SwwBYSEDCWVS3hWt8e26Kw08xwiemHKsG
jyAIUZy8o789VNw5Wt12UQLbTZ/6p0Ox77le7egFttnC/Bpea0IbOdCTZzWOCiZQ
PUGcl+YcXMZxEnV1n+3GWWWMQgOYRYLa4BGAPVeauQd3AWEIU1jwfGL3Sy0Mik24
3Ej/Qx9UCMMhv7DB96nBeaYWoY7txJhT6c2ZnmseggFuKdtxcvIpd/nWEsbdEH4S
3Tn0ZZHSFXhPA76ChmS8eHYid7NIxkXPff43bCAz8cERJ68ISm061gqi6RaD0Rxl
sWOrxIzJpDg0caTkaHo8p2ZPVqm+vaPsoxlBJiYoAGKvQzXz/EjzOazgPbEqk3ZK
5MZUwBRK
=Ofkd
-----END PGP SIGNATURE-----

src/node/blockstorage.h Show resolved Hide resolved
}
if (it->second == m_chainman.m_best_invalid) {
if (&it->second == m_chainman.m_best_invalid) {
Copy link
Member

Choose a reason for hiding this comment

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

first commit self-note: Luckily an almost identically looking diff wouldn't compile:

validation.cpp:3133:28: error: invalid operands to binary expression ('CBlockIndex' and 'CBlockIndex')
            if (it->second == *m_chainman.m_best_invalid) {
                ~~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

@@ -362,10 +362,10 @@ static int64_t AddTx(ChainstateManager& chainman, CWallet& wallet, uint32_t lock
CBlockIndex* block = nullptr;
if (blockTime > 0) {
LOCK(cs_main);
auto inserted = chainman.BlockIndex().emplace(GetRandHash(), new CBlockIndex);
auto inserted = chainman.BlockIndex().emplace(std::piecewise_construct, std::make_tuple(GetRandHash()), std::make_tuple());
Copy link
Member

Choose a reason for hiding this comment

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

first commit: Is there any reason/advantage to change this to std::piecewise_construct and not try_emplace, which automatically enables that. Or would that not work because the CBlockIndex{} rvalue can't be elided?

auto inserted{chainman.BlockIndex().try_emplace(GetRandHash(), CBlockIndex{})};

Comment on lines +199 to +207
// Return existing or create new
auto [mi, inserted] = m_block_index.try_emplace(hash);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Return existing or create new
auto [mi, inserted] = m_block_index.try_emplace(hash);
const auto [mi, inserted]{m_block_index.try_emplace(hash)};

In the third commit: I think try_emplace is self-explanatory and the comment can be removed

Comment on lines +220 to 228
CBlockIndex* pindex = &block_index;
vSortedByHeight.push_back(std::make_pair(pindex->nHeight, pindex));
Copy link
Member

Choose a reason for hiding this comment

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

nit in the for-loop commit: Any reason to keep this alias?

Suggested change
CBlockIndex* pindex = &block_index;
vSortedByHeight.push_back(std::make_pair(pindex->nHeight, pindex));
vSortedByHeight.emplace_back(block_index.nHeight, &block_index));

for (const std::pair<const uint256, CBlockIndex*>& item : m_block_index) {
CBlockIndex* pindex = item.second;
for (const auto& [_, block_index] : m_block_index) {
const CBlockIndex* pindex = &block_index;
Copy link
Member

Choose a reason for hiding this comment

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

same

@dongcarl
Copy link
Contributor Author

dongcarl commented Feb 4, 2022

Sorry, not going to make any more style/modernization-related changes, they can be followups.

Copy link
Member

@jamesob jamesob left a comment

Choose a reason for hiding this comment

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

ACK c68516d (jamesob/ackr/24050.2.dongcarl.validation_move_cblockin)

Still looks good. Re-reviewed the code, built new revision, ran unittests.

Show signature data

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

ACK c68516d662687699b399f8d12e22f2e985edae1a ([`jamesob/ackr/24050.2.dongcarl.validation_move_cblockin`](https://github.com/jamesob/bitcoin/tree/ackr/24050.2.dongcarl.validation_move_cblockin))

Still looks good. Re-reviewed the code, built new revision, ran unittests.

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEGNRVI1NPYuZCSIrGepNdrbLETwUFAmIEB80ACgkQepNdrbLE
TwX3sQ/+LiR9iKtlAAsH0iGxa5z5pm8BLqTba/1x6IznqZJaC1iztDFRSO+6G6bP
/q3paKXcBLgTBH8n4UQ/ymhmVPLrn4wTsPopDI9ygTOkXMPk3GUfVTqm64dPNaf6
CKMYffWzLsXI3qWUAm6HU3weEwaXNoX1O61rWzsIgrJhrJOX+GhQ6ph1JxMImBjO
4QHcRIh+cMoLEv1fajatdLfDKR8JSW9HDfWcB2n3kLqiZ/jbdN8PhagmZaDkS4b1
lWkTq+m5fpZA1qHQfUknWH+zamuPNorpBnahWmgs8G4bAxEKFeNJMq8a5KZBdy0G
hn1VNMyshtXnxNS4JkoxS+7hv4NBeIaSspwjChA26B18CvIoeRw/2vEKdyEEIJVH
A59cPIHL4hYe7ZJRxC756GzaReYGHS0Myz5FBJ4xEp6/lJbBIr8lrWY3oW7porrv
l50sH4L8ryk2Rhn5qHFhKZ7V1vPSJPLppnzFYyJSzQQlSSqq8NFddJHUv1oz5N2M
wHsRE0FpGlUzTlsn/iAyQdfML5TG1ZIHZvyBHSvbDFeLrvfawzeMRoUf/aSsE+T7
q1YNQf2cNHdxYUIFf+NoeYDZRfH81a71krQy2SuKI/WFDgn57EexQB2Qi8lhBSiG
r3jFuvFvWSihTJQ2Hqt5xbRfLRTgNbjJgNpPjRd+g/yI2rztmEI=
=GA3x
-----END PGP SIGNATURE-----

Show platform data

Tested on Linux-5.10.0-11-amd64-x86_64-with-glibc2.31

Configured with ./configure LDFLAGS=-L/home/james/src/bitcoin/db4/lib/ CPPFLAGS=-I/home/james/src/bitcoin/db4/include/ CXXFLAGS=-fPIE -pipe -O2 -g -Wthread-safety-analysis -Wall -Werror=sign-compare -Wsign-compare -Werror=thread-safety-analysis --enable-wallet --enable-debug --with-daemon --enable-natpmp-default CXX=/usr/local/bin/clang++ CC=/usr/local/bin/clang PYTHONPATH= --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental --disable-openssl-tests --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental --disable-openssl-tests --no-create --no-recursion

Compiled with /usr/bin/ccache /usr/local/bin/clang++ -std=c++17 -mavx -mavx2 -mpclmul -fPIE -pipe -O2 -g -Wthread-safety-analysis -Wall -Werror=sign-compare -Wsign-compare -Werror=thread-safety-analysis -O0 -g3 -ftrapv -fdebug-prefix-map=$(abs_top_srcdir)=.  -Wstack-protector -fstack-protector-all -fcf-protection=full -fstack-clash-protection -msse4 -msha -msse4.1 -msse4.2  i

Compiler version: Debian clang version 13.0.1-++20211215043002+d904698b53e4-1~exp1~20211215043040.32

// Because validation code takes pointers to the map's CBlockIndex objects, if
// we ever switch to another associative container, we need to either use a
// container that has stable addressing (true of all std associative
// containers), or make the key a `std::unique_ptr<CBlockIndex>`
Copy link
Member

Choose a reason for hiding this comment

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

Nice doc.

@maflcko maflcko added this to the 24.0 milestone Feb 14, 2022
@maflcko
Copy link
Member

maflcko commented Feb 14, 2022

Assigned 24.0, as this missed the 0.23 feature freeze

Instead of having CBlockIndex's live on the heap, which requires manual
memory management, have them be owned by m_block_index. This means that
they will live and die with BlockManager.

A change to BlockManager::LookupBlockIndex:
- Previously, it was a const member function returning a non-const CBlockIndex*
- Now, there's are const and non-const versions of
  BlockManager::LookupBlockIndex returning a CBlockIndex with the same
  const-ness as the member function:
    (e.g. const CBlockIndex* LookupBlockIndex(...) const)

See next commit for some weirdness that this eliminates.

The range based for-loops are modernize (using auto + destructuring) in
a future commit.
These manual calls to Unload() are no longer necessary because
CBlockIndex's no longer live in the heap as of the previous commit.
Credit to ajtowns for this suggestion, thanks!
@dongcarl
Copy link
Contributor Author

dongcarl commented Feb 22, 2022

Pushed c68516d -> 6c23c41

  • Added const version of BlockManager::LookupBlockIndex to account for changes in fbab43f
  • Removed a now-unnecessary CBlockIndex forward declaration

Note that I realized parts of libbitcoinkernel is made easier by this work and its followup, so will be adding it to the project.

@ajtowns
Copy link
Contributor

ajtowns commented Mar 2, 2022

ACK 6c23c41

Commenting out the non-const version of LookupBlockIndex and adding const annotations at call sites everywhere that's feasible has a lot of hits. Might be worth a followup post-merge.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

re-ACK 6c23c41 🎨

Show signature

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

re-ACK 6c23c415613d8b847e6f6a2f872be893da9f4384 🎨
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUjQHQwArZhANo4eHc9fHY/ogxBargWcUs82Jt+5QFFFQFB33PIjOCYNE1fpaPuf
y7SVbEdp0SvsMs2qOn86LptVA2UJQYaaYB+36/AlPo0f1tXRHmNZbFSnQicRGnYG
8Mf4S/NUS81e9Mg85rqXjTaCxeAkVtALazna7+wSE1xHcPx9VMy20OcBRye+BzkK
UmzVHIrtjA6/1lVWa7QBWo8S2se6l3GPIT7TARSuH1+tGGH3LRxJ47S5qYbTJciB
Ec1YBWiepcnq1QywMC9GXYIrYZmKPikmRhrpAIKyL3yQh76eksIFFg1qFLq6yD1d
QhKWt5PA4peyGYLhQYh6UUV1YDh5cXM1PEOur17tG6BPw3oX5+j8OsdVIfYur3V5
NM29D2T72nxaBYRrnXH+tIeY6Qz4PN+jKaZSqI3Qa8iaPounJnoryr8FN5SfKIS6
NYCmRCN/EYFC5TocfoWaEue6F69q4Y9AzWE20ko0UF2zOBtFgkv1L/+NDusi+TTc
B8Ozf9u4
=iXAq
-----END PGP SIGNATURE-----

@maflcko maflcko merged commit 5e49b2a into bitcoin:master Mar 7, 2022
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Mar 7, 2022
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Jan 20, 2023
Summary:
These manual calls to Unload() are no longer necessary because
CBlockIndex's no longer live in the heap as of the previous commit.

This is a partial backport of [[bitcoin/bitcoin#24050 | core#24050]]
bitcoin/bitcoin@531dce0

Depends on D12991

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D12992
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Jan 20, 2023
Summary:
Credit to ajtowns for this suggestion, thanks!

This is a partial backport of [[bitcoin/bitcoin#24050 | core#24050]]
bitcoin/bitcoin@dd79dad
bitcoin/bitcoin@6c23c41

Depends on D12992

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D12993
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Jan 20, 2023
Summary:
This concludes backport of [[bitcoin/bitcoin#24050 | core#24050]]
bitcoin/bitcoin@c05cf7a

Depends on D12993

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D12994
@bitcoin bitcoin locked and limited conversation to collaborators Mar 7, 2023
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