Skip to content

Introduce deploymentstatus#19438

Merged
maflcko merged 12 commits intobitcoin:masterfrom
ajtowns:202007-deployment-refactor
Jul 1, 2021
Merged

Introduce deploymentstatus#19438
maflcko merged 12 commits intobitcoin:masterfrom
ajtowns:202007-deployment-refactor

Conversation

@ajtowns
Copy link
Contributor

@ajtowns ajtowns commented Jul 3, 2020

Introduces helper functions to make it easy to bury future deployments, along the lines of the suggestion from 11398 "I would prefer it if a buried deployment wouldn't require all code paths that check the BIP9 status to require changing".

This provides three functions: DeploymentEnabled() which tests if a deployment can ever be active, DeploymentActiveAt() which checks if a deployment should be enforced in the given block, and DeploymentActiveAfter() which checks if a deployment should be enforced in the block following the given block, and overloads all three to work both with buried deployments and versionbits deployments.

This adds a dedicated lock for the versionbits cache, which is acquired internally by the versionbits functions, rather than relying on cs_main. It also moves moves versionbitscache into deploymentstatus to avoid a circular dependency with validation.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jul 3, 2020

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Copy link
Contributor

@JeremyRubin JeremyRubin left a comment

Choose a reason for hiding this comment

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

Concept ACK and some lite code review feedback.

Copy link
Contributor

Choose a reason for hiding this comment

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

prefer enum class to prevent leaking names.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also helps with avoiding overlap with SignalledDeployment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Leaking the names is the point -- otherwise you'd need to change every use from Consensus::DeploymentPos::SEGWIT to Consensus::BuriedDeployment::SEGWIT. With C++20, you will be able to specify enum class DeploymentPos { .. }; using enum DeploymentPos; but that's a while away.

Comment on lines 17 to 21
Copy link
Contributor

Choose a reason for hiding this comment

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

prefer explicitly numbering these.

-255 is an extremely odd number, can you clarify why you picked it? It doesn't fit in a signed byte.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Explicitly numbering them risks accidentally repeating a number. No particular objection to a different starting point. Could perhaps make it enum DeploymentPos : uint8_t and enum BuriedDeployment : int16_t { DEPLOYMENT_CLTV = 256, // larger than largest possible DeploymentPos value.

(I guess 2**n is an "extremely even" number, so calling +/- 2**n-1 "extremely odd" makes a lot of sense...)

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe tighter to make this a templated function as we're never calling DeploymentHeight with a variable, only literal.

Then we get not just a warning, but a compiler error.

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 had tried that, but thought that it might be useful to be able to do for (dep = 0; dep < MAX_VERSIONBITS_DEPLOYMENTS; ++dep) { ... DeploymentActiveAt(pindex, consParams, dep) .. }. I think in all the cases where that currently comes up you want to know more fine grained details though. (Changing BuriedForkDescPushBack to take a BuriedDeployment instead of a height would make use of that, eg)

I don't think the type checking is any better with the template though, as unfortunately you can invoke DeploymentHeight<(BuriedDeployment)9000>() just as easily as DeploymentHeight((BuriedDeployment)9000) with both g++ and clang++.

Copy link
Contributor

Choose a reason for hiding this comment

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

This dispatch scares me a bit unless we use enum class -- enums could coerce poorly right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope; int (and the like) won't automatically coerce to enum, so with int x = Consensus::DEPLOYMENT_SEGWIT; return DeploymentActiveAt(pindex, params, x) you get errors:

validation.cpp:1921:12: error: no matching function for call to 'DeploymentActiveAt'
    return DeploymentActiveAt(pindex, consensusparams, x);
           ^~~~~~~~~~~~~~~~~~
./deploymentstatus.h:32:13: note: candidate function not viable: no known conversion from 'int' to 'Consensus::BuriedDeployment' for 3rd argument
inline bool DeploymentActiveAt(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::BuriedDeployment dep)
            ^
./deploymentstatus.h:37:13: note: candidate function not viable: no known conversion from 'int' to 'Consensus::DeploymentPos' for 3rd argument
inline bool DeploymentActiveAt(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos dep) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
            ^

(even if it did, which enum it coerced to is ambiguous between the two types, resulting in a failure like error: call to 'DeploymentActiveAt' is ambiguous)

@ajtowns ajtowns force-pushed the 202007-deployment-refactor branch from 5834cc8 to 6b08b76 Compare July 3, 2020 21:48
@ajtowns ajtowns force-pushed the 202007-deployment-refactor branch from 6b08b76 to 787040b Compare September 8, 2020 15:04
@ajtowns ajtowns force-pushed the 202007-deployment-refactor branch from 787040b to 1f1d51d Compare September 8, 2020 22:27
@ajtowns ajtowns force-pushed the 202007-deployment-refactor branch from 1f1d51d to 91572f3 Compare September 22, 2020 03:00
@michaelfolkson
Copy link

Concept ACK, Approach ACK.

Looked at this at the PR review club session back in March 2021 and changes since then appear to be minimal. This PR doesn't appear to be urgent for 22.0 as Taproot deployment won't be buried anytime soon but this PR has been open for a while so it would definitely be nice to get it in.

@ajtowns
Copy link
Contributor Author

ajtowns commented Jun 23, 2021

Including this in 22.0 makes it easier to switch taproot to being a buried deployment, which would allow removing the speedy trial code, which in turn may make it easier to backport new activation code for any new soft forks that may be ready for deployment prior to version 22 reaching end-of-life (perhaps some of the consensus cleanup ideas eg).

@maflcko
Copy link
Member

maflcko commented Jun 23, 2021

backport new activation code for any new soft forks that may be ready for deployment prior to version 22 reaching end-of-life

I think generally we only backport soft-forks to the previous major version. Though I have a slight preference to merge this for 22 to minimize potential conflicts when backporting (other) consensus changes.

Copy link
Contributor

@fjahr fjahr left a comment

Choose a reason for hiding this comment

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

re-utACK 01c156677e34e21591e71fb979a041f19c060018

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Could have given a default that provides more context like "unknown"

Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't matter too much, as it is dead code. Empty string might even make it easier to run CHECK_NONFATAL(!name.empty()); in rpc code.

Copy link
Member

Choose a reason for hiding this comment

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

Or just assert(false) for symmetry with the assert at the beginning of the function?

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: could have upgraded to static_cast<int>(Consensus::MAX_VERSION_BITS_DEPLOYMENTS)

Copy link
Member

Choose a reason for hiding this comment

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

u{Consensus::MAX_VERSION_BITS_DEPLOYMENTS} is even more preferable when this is changed. (with u being the underlying type)

Copy link
Member

Choose a reason for hiding this comment

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

See also #19438 (comment)

@maflcko
Copy link
Member

maflcko commented Jun 27, 2021

Needs rebase.

Feedback can be ignored or done in a follow-up if needed, to simplify re-review.

@ajtowns ajtowns force-pushed the 202007-deployment-refactor branch from 01c1566 to e14966e Compare June 28, 2021 03:17
@ajtowns
Copy link
Contributor Author

ajtowns commented Jun 28, 2021

Thanks @MarcoFalke ; rebased past #22156 ; leaving nit fixing 'til post 22.0

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-review e14966ee31f02e359896dbb72e2627b3ae12a314 🏙

Show signature and timestamp

Signature:

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

re-review e14966ee31f02e359896dbb72e2627b3ae12a314 🏙
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUgN8Qv9GgVO/0B/5pXOElsDfA01j0nQa49UyijPA+VnSucn3IODX70Qpreqsutf
LtBbFvY5YG7elclunOovo53MDHmtXHQasTqEyubDzlOn4sGAuUSHgbiqQEN1KUTE
gkdto79U3h7Fi8uUwwkEKpsKtaCPnUXHoqfa5OomM3K4Ku2r9FOEmCshP/JRNcy6
WlDKFZd5N+UAf+4wqwDr9Oo0WCde/vadC3vU6CB4EDNID2WIX6PIK412wF+3/Z/4
KjXkIBgIrggK/OHS2cXaGdRJuskc9EPZa+n6+PC1UxQHS3nWsTmNQRf9b97zDovh
PygV0L/fv8BVn3lH0DPh94IhsMTOJge07WPcPj2E3beGEDjFZJC12GgjZa+EMNBi
yKuwc2QucVhEfrUyjmIKgqtylpjYVNApdvgNHFTZGwDE8w/m9MndjkUPZDuUm3E7
C2IO9DGmjC8T4FsWuuogmvyF5/0QJ99924B7BWRiFM9hsbUEwG1akHgSQ8ez1YJK
yweuMjpk
=i3Iu
-----END PGP SIGNATURE-----

Timestamp of file with hash de786aee714e95ba66b851bc0e29b843b5f1124ce723a9bc15d6d531f0fb1477 -

Copy link
Member

Choose a reason for hiding this comment

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

24972d9f49:

Shouldn't this say:

const bool taproot_active{DeploymentActiveAfter(m_active_chainstate.m_chain.Tip(), args.m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_TAPROOT)};

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, it should, fixed.

ajtowns added 3 commits June 29, 2021 17:11
Provides DeploymentEnabled, DeploymentActiveAt, and DeploymentActiveAfter
helpers for checking the status of buried deployments. Can be overloaded
so the same syntax works for non-buried deployments, allowing future
soft forks to be changed from signalled to buried deployments without
having to touch the implementation code.

Replaces IsWitnessEnabled and IsScriptWitnessEnabled.
@ajtowns ajtowns force-pushed the 202007-deployment-refactor branch from e14966e to df308ab Compare June 29, 2021 22:03
@ajtowns
Copy link
Contributor Author

ajtowns commented Jun 29, 2021

Rebased past #21789

ajtowns added 9 commits June 30, 2021 08:18
Adds support for versionbits deployments to DeploymentEnabled,
DeploymentActiveAfter and DeploymentActiveAt. Also moves versionbitscache
from validation to deploymentstatus.
-BEGIN VERIFY SCRIPT-
sed -i -e 's/versionbitscache/g_versionbitscache/g' $(git grep -l versionbitscache)
-END VERIFY SCRIPT-
Rename BIP9SoftForkPushBack and BuriedSoftForkPushBack to SoftForkPushBack
and have the compiler figure out which one to use based on the deployment
type. Avoids the need to update the file when burying a deployment.
Moves the VersionBits* functions to be methods of the cache class,
and makes the cache and its lock private to the class.
This also changes ComputeBlockVersion to take the versionbits cache
mutex once, rather than once for each versionbits deployment.
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 e48826a 🥈

Checked with:
git range-diff bitcoin-core/master e14966ee31f02e359896dbb72e2627b3ae12a314 e48826a --word-diff-regex=. -U0

Show signature and timestamp

Signature:

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

re-ACK e48826ad87b4f92261f7433e84f48dac9bd9e5c3 🥈

Checked with:
git range-diff bitcoin-core/master e14966ee31f02e359896dbb72e2627b3ae12a314 e48826ad87b4f92261f7433e84f48dac9bd9e5c3 --word-diff-regex=. -U0
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUh+dAv+NVpZKf22BScmqPb4YLJH2snw87TwSnr6Ez2ocyL441p57JrElilouzMN
gklFgwx0RYY2WlGKtGVub1aa3gVLqmDbdWKi6sGxTJB+5tbQnaK4S5tEDKAWfPDu
q7xawsZ7mOKeyIJXlRrwMiipeziVGtuDW7pQ5OkfCfQevvCMmexdA/vwigKR9UbW
adVkvMNwkA1g8LLbfn3xMUGk3QnidnYyaJtP+55LK91kLMx/5fDgmEoj5kBFYu1s
8n5SE4UW06RfkUfAuPJT5TgM3IjxoHmO9bwQbdh27a/1yY+zTggjy9Ak8cWs3xAi
jr3NjAohqfp1EKKMP8/oGTUn7AHMUu/tUPzqWH0iTJ2NdGt8HHrT54qBSB7ryS/W
+rfMOv0G3quOWCd0jc5zQLHsaMndlItfPgRMWBgMQ255zo0hWBOs6HV9Xe1kuZgF
4jCLR/KvxoK9/e0ore9XqEDpyeABo0oRwzVSg0XrHIMWHSpB2qOZx1ycQwqnoaR4
Y722yBJ3
=PNtg
-----END PGP SIGNATURE-----

Timestamp of file with hash 51b700b2e20a4085313cce0dc833915df20496b87f40dbee5ed2e7651008877d -

@jnewbery
Copy link
Contributor

ACK e48826a

@gruve-p
Copy link
Contributor

gruve-p commented Jul 1, 2021

ACK e48826a

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.