-
Notifications
You must be signed in to change notification settings - Fork 295
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
multi: Implement reject new script and tx vers. #2716
Conversation
5697f84
to
8c8d822
Compare
8c8d822
to
b3eac28
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewing first relevant commit.
mempool.go
needs to also be added the AFExplicitVerUpgrades
flag here though I guess you might wanna to deal with mempool in a separate PR, so as to remove the MaxTxVersion config knob.
This is also probably inconsequential, but I notice that miners running with --acceptnonstd
that happen to have a mempool tx with an incompatible tx version, might end up in a state where they keep trying to generate a block that can't be accepted anymore (once this upgrade activates). This can be dealt with in the template generation code or by just instructing miners to restart their nodes if this happens to them.
@@ -345,6 +357,28 @@ func (flags AgendaFlags) IsTreasuryEnabled() bool { | |||
func checkTransactionContext(tx *wire.MsgTx, params *chaincfg.Params, flags AgendaFlags) error { | |||
// Determine active agendas based on flags. | |||
isTreasuryEnabled := flags.IsTreasuryEnabled() | |||
explicitUpgradesActive := flags.IsExplicitVerUpgradesEnabled() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I double checked, and the only places that are calling checkTransactionContext
are indeed checkBlockContext()
(where the flags are correctly set according to the results of the vote) and on the exported version CheckTransaction()
where it's up to the caller to set the correct flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed second relevant commit and only have the same considerations re: script version in mempool and miners if they have txs in their mempool that become invalid when the new agenda activates.
Aye, I have a separate PR I was working on to deal with That said, it's a fair point it should probably be a part of this PR too in order to avoid what looks like missed handling. I'll get a commit added accordingly. |
b3eac28
to
bf5ca80
Compare
I've updated the PR to include two new commits which add the aforementioned |
bf5ca80
to
1fc856a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commit message in b979fd1
mentions renaming a test function but looks cut off.
That is actually in #2721 where it has already been updated. EDIT: I rebased over it now, so the correct message should be incorporated. |
1fc856a
to
a8d956a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested several combinations of the standard two-node simnet setup using current master/this PR applied/this PR + non-voted-agenda (to test an upgraded node while the agenda hasn't activated yet).
In particular, I tested scenarios involving sending (via rpc) and relaying txs across nodes running different versions, using tx version > 3
and script version > 0
(and spending from them). All scenarios worked as expected.
All in all, looking pretty good :P
I'll probably do a second pass review in a couple of days after other ppl have had a chance to also look at this, but it seems pretty close to ready.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great. I can definitely appreciate the benefits this will bring after working on revocation transaction changes for DCP0009. I’ll do another pass over it in the next few days in addition to some testing, but so far everything looks proper to me.
switch { | ||
case explicitUpgradesActive: | ||
maxAllowedTxVer = 3 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking through the process of a future consensus change once this is in place:
- Let's say we are introducing a consensus change that makes modifications to vote transactions
- With the explicit upgrades agenda active, we would know that transactions with a version greater than
3
are not being accepted - Therefore, we would want to bump the vote transaction version from
1
to4
, andmaxAllowedTxVer
would be set to4
here if this new agenda to change vote transactions was active - This would allow us to have this single agenda check here, and most other transaction-level checks could rely on checking that the vote transaction version is
4
to apply the new rules (which will be super nice!)
A couple of things felt a bit odd to me about this at first:
- Even though in the above example the vote transaction version is bumped to
4
, other transaction types will still actively use version1
-3
. And for those transaction types, version4
is also now valid, even though it may not be used and does not stipulate any changes to those transaction types. - The version always needs to be bumped from wherever it is at to beyond the upper limit to take advantage of this (e.g. in the example above vote transactions skip from version
1
to4
, even though there are no changes in any of the intermediate versions for vote transactions).
This effectively makes the max transaction version really just an update to the overall rule set for transactions, which will typically only be set on the transaction types that were impacted by the rule updates. That makes sense, and I think capturing these updates here in a single place for any new agendas will make it clear and easy to follow.
No suggested changes here just capturing my thought process to make sure I’m not missing anything and in case it is helpful for anyone else reviewing!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should note that I did consider applying max versions individually, but I decided against that because stake transactions are themselves just transactions that must be of a very specific form to be categorized as that "type" of transaction. Due to that, any changes that affect non-stake transactions will also affect stake transactions (most of the time anyway), so, having an overall rule set for transactions (which encompasses both stake and non-stake) makes the most sense.
// | ||
// It is also worth noting that this check only applies to regular | ||
// transactions because stake transactions are individually and | ||
// separately enforced to be a specific script version. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I double-checked as well that the script version is being enforced for all stake transaction types.
a8d956a
to
ec1a669
Compare
For reference, I added a separate prep commit that refactors the construction logic of the flags to use when checking transactions based on the active agendas into a single func and updated the code to use those flags instead of the local agenda determination funcs. That way, adding the new agenda in one place automatically applies it to all. The subsequent commits have been updated accordingly. The net effect is that now all places where the transaction check flags are constructed in |
c849a52
to
1f11643
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to go to me! I did another pass of reviewing and testing and only noticed a few comment typos.
1f11643
to
5b48b20
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice validation tests, all issues look to have been addressed as well.
This consolidates the logic for constructing the agenda flags to use for checking transactions into a separate method versus building them inline in multiple different places. This makes it easier to add new agendas in the future while keeping the flags consistent.
This implements the agenda for voting on rejecting new transaction versions until they have explicitly been enabled by a consensus rule change as defined in DCP0008 along with consensus tests. In particular, once the vote has passed and is active, transaction versions greater than 3 will no longer be accepted. This does not include the script version portion of the DCP as that will be done in a future commit. This implies that it is important for both this commit and the aforementioned future commit to be merged at the same time. Also note that this does not implement block version bumps in the mining and validation code that will ultimately be needed since another consensus vote is expected to land before voting begins. The following is an overview of the changes: - Introduce a convenience function for determining if the vote passed and is now active - Modify block validation to enforce the rejection of newer transaction versions in accordance with the state of the vote - Add tests for determining if the agenda is active for both mainnet and testnet - Add tests to ensure proper behavior for new transaction versions as follows: - New regular and stake transaction versions are rejected once the agenda is active - Existing regular and stake outputs created with newer tx versions are spendable before the agenda is active and remain spendable after it is active
This implements the agenda for voting on rejecting new script versions until they have explicitly been enabled by a consensus rule change as defined in DCP0008 along with consensus tests. In particular, once the vote has passed and is active, script versions greater than 0 will no longer be accepted. Note that this does not implement block version bumps in the mining and validation code that will ultimately be needed since another consensus vote is expected to land before voting begins. The following is an overview of the changes: - Modify block validation to enforce the rejection of newer script versions in accordance with the state of the vote - Add tests to ensure proper behavior for new script versions as follows: - Ensure stake transactions still require version 0 scripts regardless of the state of the agenda - Regular transactions with script versions newer than 0 are rejected once the agenda is active - Transaction outputs that have a non-zero output and script that would make the output unspendable if it were version 0 are spendable with a nil signature script both before the agenda is active and remain spendable after it is active
This adds enforcement of the newly introduced explicit version upgrade requirements when considering candidate transactions for acceptance to the mempool, relaying, and inclusion into block templates. This is acceptable because the aforementioned areas only enforce policy. Also of note is that the existing policy already rejected transactions via the standardness policy that will now be rejected at a consensus level. It also adds tests to ensure the new enforcement works as intended.
This removes the handling for a configurable maximum allowed transaction version via the standardness policy since it is now enforced via consensus rules instead. The following is an overview of the changes: - Remove the MaxTxVersion field from the Policy struct - Remove the max tx version checking logic from checkTransactionStandard - Remove the max tx version param from checkTransactionStandard - Update the transaction standardness tests accordingly - Update all callers accordingly
5b48b20
to
4aad374
Compare
This requires #2713, #2715, and #2721.This implements the agenda for voting on rejecting new transaction and script versions until they have explicitly been enabled by a consensus rule change as defined in DCP0008 along with consensus tests.
In particular, once the vote has passed and is active, transaction versions greater than 3 and script versions greater than 0 will no longer be accepted by consensus.
This PR also updates the
mempool
policy when considering candidate transactions for acceptance to the mempool, relaying, and inclusion into block templates to enforce the new version behavior at a consensus level versus via the standardness policy. In practice, this change means the following:mainnet
, there will be no externally observable difference since standardness rules are already enforced onmainnet
and they already prevent transactions which violate the new rulestestnet
(where non-standard transactions are allowed) themempool
policy will now match the existingmainnet
policy in terms of version handlingNote that this does not implement block version bumps in the mining and validation code that will ultimately be needed since another consensus vote is expected to land before voting begins.
The following is an overview of the changes:
nil
signature script both before the agenda is active and remain spendable after it is activemempool
policy to enforce the explicit version upgrade requirements via the consensus rules versus via the standardness rulesmempool
MaxTxVersion
field from thePolicy
structmempool
max tx version checking logic fromcheckTransactionStandard
mempool
max tx version param fromcheckTransactionStandard
mempool
transaction standardness tests accordinglymempool
changes accordingly