-
Notifications
You must be signed in to change notification settings - Fork 296
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: DCP0009 Auto revocations consensus change. #2720
Conversation
5244452
to
d072683
Compare
4071bf6
to
39e4436
Compare
Just added a |
For reference, in addition to the automated tests, I've also been testing this under various conditions in
|
ce616fe
to
b0cf7b2
Compare
What I usually do is just add a temporary definition to the simnet params, modify wallet to vote on the agenda, generate enough blocks to ensure the agenda activates, and then test things. I haven't done that with this PR yet, but I plan to this weekend. |
b0cf7b2
to
0b9760f
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.
Trying this out on simnet looks to work as intended, but mining blocks that include automatic revocations takes some time. There is tangible lag compared to blocks without revocations. Maybe just how it is?
I attempted to graph what what I see. My mining script looks like:
And what I could get from The zero pc usage at the beginning and start is before and after mining some blocks, I think it was 20,30,30 blocks respectively for these graphs. You can see where it looks like from here that dcrd just pauses for a while when the revocations take place. Perhaps something with my setup? Using this https://github.com/decred/dcrdex/tree/master/dex/testing/dcr |
0b9760f
to
a1767c0
Compare
I'm not seeing a delay or any significant difference in the time to generate blocks with auto revocations. Did you add any test code to miss votes or how are you handling that? Perhaps that is causing the issue or would otherwise help me reproduce this. |
9fca7cb
to
71776a0
Compare
Not handling... the tickets being revoked belong to wallets that aren't part of purchasing tickets needed to sustain block propagation. I'm just doing a very mechanical, purchase ticket with wallet and shut it down, progress the chain. Here is a log where you can see a couple seconds "pause":
Another one:
And what it normally looks like:
So I see a pause between |
Ok! It seems this is the same behavior as master! So... false alarm. Sorry about that. There is always a pause when revocations are present, perhaps something with my setup if you do not see them though. |
Okay, great! Thanks for the review and for confirming. I'm not sure where that pause is occurring on your side without more detailed logs, but given that the delay is right after |
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 overall thus far. The commits are well crafted, the core logic all appears correct, and the tests provide good coverage.
I still have some more review of the tests themselves to double check they're all testing what they claim to test fully and some manual testing to do, but I have reviewed the core validation logic carefully and wanted to go ahead and get the first part of the review out.
71776a0
to
ee8f44c
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.
I have gone through all of the tests to verify that are indeed testing what they claim. They look great overall. Just a few minor nits I noticed will going through that I've commented on inline.
ee8f44c
to
5686903
Compare
5686903
to
ae092f1
Compare
ae092f1
to
f192b83
Compare
f192b83
to
1210cc2
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 revoking with the existing semantics and the new ones and revoking a large number of tickets after moving to the new semantics.
Looking very tight!
Will take a second look after the updates you mentioned in the last inline comment.
1210cc2
to
d96dcf7
Compare
This adds a HeaderByHash method to the mining Config. This will be used as part of the automatic ticket revocations changes in a subsequent commit.
This adds a HeaderByHash method to the mempool Config. This will be used as part of the automatic ticket revocations changes in a subsequent commit.
This introduces automatic ticket revocations as defined in DCP0009, including: - Allowing tickets to be revoked by anyone instead of requiring a valid signature from the voting address - Requiring blocks to contain ticket revocation transactions for all tickets that become missed or expired as of that block An overview of the changes is as follows: - blockchain/scriptval.go - ValidateTransactionScripts, checkBlockScripts - Skip script validation for version 2 revocations if the automatic ticket revocations agenda is active - blockchain/stake/staketx.go, blockchain/stake/staketx_test.go - Introduce TxVersionAutoRevocations const for version 2 revocations - CalculateRewards, CalculateRevocationRewards - Add CalculateRevocationRewards to handle the required updates for revocations while leaving CalculateRewards as-is for votes - If the automatic ticket revocations agenda is active, and there is a remainder after distributing the returns, then select a uniformly pseudorandom output index to receive each remaining atom - Add additional tests to cover the new code paths - CheckSSRtx - Add checks to ensure that the input does not have a signature script and does not have a fee if the automatic ticket revocations agenda is active - Add additional tests to cover the new code paths - blockchain/validate.go, blockchain/validate_test.go - checkTransactionContext - Add rule that revocation transactions MUST be version 2 if the automatic ticket revocations agenda is active. - checkTicketRedeemers - Add rule that if the automatic ticket revocations agenda is active, then the block MUST contain revocation transactions for all tickets that will become missed or expired as of that block - Add rule that if the automatic ticket revocations agenda is active, then revocations can spend tickets that will become missed or expired as of that block (previously they could not be spent until the block following the block where they became missed or expired) - Update to accept the referenced ticket hashes rather than the overall block to simplify adding comprehensive unit tests for the function - calcTicketReturnAmounts - Update to calculate the amounts for all outputs rather than a single output - For revocations, if the automatic ticket revocations agenda is active, and there is a remainder after distributing the returns, then select a uniformly pseudorandom output index to receive each remaining atom - checkTicketRedeemerCommitments - Add rule that if the transaction is a version 2 revocation and the automatic ticket revocation agenda is active, then the fee MUST be zero - Use the updated calcTicketReturnAmounts function so that returns include the full amount, which allows for ensuring a truly zero fee - checkRevocationInputs - Add rule that if the automatic ticket revocations agenda is active, then revocations can spend tickets after ticket maturity + 1 blocks (in the block that they become missed or expired) rather than after ticket maturity + 2 blocks (in the block AFTER they become missed or expired) - internal/mempool/mempool.go, internal/mempool/mempool_test.go - Pass best block header to CheckTransactionInputs - Pass isAutoRevocationsEnabled to ValidateTransactionScripts - internal/mining/mining.go, internal/mining/mining_harness_test.go, internal/mining/mining_test.go, internal/mining/mining_view_test.go - Add a helper function, createRevocationFromTicket, to create a revocation transaction from a ticket hash - If the automatic ticket revocations agenda is active, then create version 2 revocation transactions for all tickets that will become missed or expired as of the block being created - Create and insert these revocations into the priority queue AFTER votes are done being added to ensure that revocations are added for votes that fail validation checks or are otherwise not included into the block - Pass best block header to CheckTransactionInputs - Pass isAutoRevocationsEnabled to ValidateTransactionScripts - internal/rpcserver/interface.go, internal/rpcserver/rpcserver.go, internal/rpcserver/rpcserverhandlers_test.go - handleCreateRawSSRtx - If the automatic ticket revocations agenda is active: - Validate that the fee is zero - Set the transaction version to 2 - Pass previous header bytes and isAutoRevocationsEnabled flag to CreateRevocationFromTicket in order to create version 2 revocation transactions properly with the updated rules - Add additional tests to cover the new code paths - server.go - Pass previous block header to CheckTransactionInputs - Pass isAutoRevocationsEnabled to ValidateTransactionScripts
This adds full test coverage for the calcTicketReturnAmounts function to ensure that ticket return amounts are calculated correctly under a variety of conditions.
This adds full test coverage for the checkTicketRedeemers function to ensure that all ticket redeemer consensus rule checks work as expected.
This adds tests to ensure that all of the validation rules associated with the automatic ticket revocations agenda work as expected.
This adds tests to ensure that creating new block templates works as expected when the automatic ticket revocations agenda is enabled.
This adds tests to ensure that revocations are accepted and rejected by the mempool as expected with the automatic ticket revocations agenda enabled.
d96dcf7
to
202dea7
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 update to remove revocations from the mempool
on block changes once the agenda is active look correct and I also tested it works as intended on simnet
by modifying the code a bit to get it into the state where it applies.
I should also note that technically speaking a revocation only really needs to be removed if it is no longer valid as opposed to just always removing it since, most of the time, it will still be valid given there is typically only a single output. However, given this case will only ever apply to revocations for a finite set of legacy tickets that are going to be manually revoked, unconditionally removing them is reasonable.
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 the last changes working as expected.
Another note re: always dropping the revocation is that this might make it slightly annoying to issue the revocations for the old tickets, since it means users will have to actively monitor (and potentially keep issuing the revocation) until it's successfully included in a block. Not a show stopper since it's just a temporary issue.
LGTM. Excellent work!
Agreed, that is a good point that @davecgh raised as well. I'll be writing the script to issue the revocations for the legacy tickets, which will take this into account (so no one else should have to deal with it). Thanks for the review! |
Requires #2719.This introduces automatic ticket revocations as defined in DCP0009. The high-level changes are:
Additional details and discussion can also be found in the Politeia Proposal for this change.
Consensus rule changes - Overview
The consensus changes introduced to support automatic ticket revocations are as follows:
2
ticket maturity + 1
blocks (in the block that they become missed or expired)ticket maturity + 2
blocks (in the block AFTER they become missed or expired)For further details see DCP0009.
Consensus rule changes - Detailed
This section outlines the changes in commit
multi: DCP0009 Auto revocations consensus change.
, which contains all of the consensus rule changes to support automatic ticket revocations:blockchain/scriptval.go
ValidateTransactionScripts
,checkBlockScripts
2
revocations if the automatic ticket revocations agenda is activeblockchain/stake/staketx.go
,blockchain/stake/staketx_test.go
TxVersionAutoRevocations
const for version2
revocationsCalculateRewards
,CalculateRevocationRewards
CalculateRevocationRewards
to handle the required updates for revocations while leavingCalculateRewards
as-is for votesCheckSSRtx
blockchain/validate.go
,blockchain/validate_test.go
checkTransactionContext
2
if the automatic ticket revocations agenda is activecheckTicketRedeemers
calcTicketReturnAmounts
checkTicketRedeemerCommitments
2
revocation and the automatic ticket revocation agenda is active, then the fee MUST be zerocalcTicketReturnAmounts
function so that returns include the full amount, which allows for ensuring a truly zero feecheckRevocationInputs
ticket maturity + 1
blocks (in the block that they become missed or expired) rather than afterticket maturity + 2
blocks (in the block AFTER they become missed or expired)internal/mempool/mempool.go
,internal/mempool/mempool_test.go
CheckTransactionInputs
isAutoRevocationsEnabled
toValidateTransactionScripts
internal/mining/mining.go
,internal/mining/mining_harness_test.go
,internal/mining/mining_test.go
,internal/mining/mining_view_test.go
2
revocation transactions for all tickets that will become missed or expired as of the block being createdCheckTransactionInputs
isAutoRevocationsEnabled
toValidateTransactionScripts
internal/rpcserver/interface.go
,internal/rpcserver/rpcserver.go
,internal/rpcserver/rpcserverhandlers_test.go
handleCreateRawSSRtx
isAutoRevocationsEnabled
flag toCreateRevocationFromTicket
in order to create version2
revocation transactions properly with the updated rulesserver.go
CheckTransactionInputs
isAutoRevocationsEnabled
toValidateTransactionScripts
Additional Test Coverage
There are several additional commits following the consensus change commit, which add comprehensive tests coverage for the updated consensus rules:
calcTicketReturnAmounts
checkTicketRedeemers
Impact to External Software
stake.CalculateRewards
has not changed, but should no longer be used for revocations and will return incorrect results for revocations when the automatic ticket revocations agenda is activestake.CalculateRevocationRewards
has been added should be used for revocations instead ofstake.CalculateRewards
stake.DetermineTxType
,stake.IsSSRtx
, andstake.CheckSSRtx
have been updated to take aisAutoRevocationsEnabled bool
param (as described in multi: Add isAutoRevocationsEnabled to CheckSSRtx. #2719)createrawssrtx
will now return an error if the automatic ticket revocations agenda is active and a non-zero fee is providedNote on the
isAutoRevocationsEnabled
flagOne additional thing to note about the consensus rule changes is that if the agenda activates, and there are no version
2
revocation transactions in blocks before the agenda activates, then most of the rules can be retroactively updated to be guarded by the revocation transaction version rather than the agenda being active. The guard clauses could be simplified to:2
2
revocation transactions (and would not need to check the agenda)This is desired because it doesn't require passing around whether the agenda is active, which itself is based on the blockchain global state, and instead could just be based on the transaction itself.