-
Notifications
You must be signed in to change notification settings - Fork 668
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
Feat/coinbase pay to contract #3164
Conversation
…ress for a block, not the address that receives the coinbase
…inbase variant. Add the codec logic for it. Add epoch 2.1 gating in the static transaction validation logic so that a block that gets preprocessed before 2.1 with a pay-to-contract coinbase will not be treated as valid (which stops a 2.1-series node from even accepting such a block into the staging DB before the feature is supported).
…tely from the miner address, and update the reward disbursment code to send the block reward to this address if it is given. Expand the unit tests to cover this case.
…tic transaction validation logic so that we never store a pay-to-contract block mined before 2.1. Also, API sync with the new coinbase payload type. In addition, when rejecting a block during pre-processing mask NotFound errors so that the code path returns InvalidStacksBlock.
…ner rewards table
…t the contract, not the miner, receives the expected block rewards
…ses, and update all uses of the coinbase type variant to include the optional contract ID
…ract blocks before epoch 2.1
…o a particular smart contract
… the config file, and the current epoch is 2.1
…-contract blocks after epoch 2.1 starts, if configured to do so
Codecov Report
@@ Coverage Diff @@
## next #3164 +/- ##
==========================================
- Coverage 84.19% 83.78% -0.42%
==========================================
Files 268 268
Lines 212573 213534 +961
==========================================
- Hits 178981 178902 -79
- Misses 33592 34632 +1040
Continue to review full report at Codecov.
|
… it has a microblock parent stream and crosses an epoch boundary) should be an InvalidStacksBlock error, not a NotFoundError
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.
lgtm!
src/chainstate/stacks/db/mod.rs
Outdated
@@ -132,6 +132,7 @@ pub struct StacksAccount { | |||
#[derive(Debug, Clone, PartialEq)] | |||
pub struct MinerPaymentSchedule { | |||
pub address: StacksAddress, | |||
pub recipient_contract: Option<QualifiedContractIdentifier>, |
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.
Is there any use for specifying a different StacksAddress
as the recipient, rather than a contract? As in, what if miner Alice wanted coinbase rewards to go to Bob even if Bob isn't a contract?
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 thought about this too, but I can't think of a compelling use-case. If Alice wanted to pay Bob the block reward, then why can't Alice just fund Bob's block-commit transaction?
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.
Because they don't share keys -- like one situation could be that the coinbase rewards are going to a "cold" Stacks wallet, which you wouldn't want to use as the miner address (because the miner address must be hot).
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.
Gotcha. I've made it so that the coinbase can pay to either a contract or a standard principal.
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 me, I had mostly superficial comments, plus wanted to discuss whether or not we should allow the coinbase to specify a general principal
or only contracts.
Removing myself since there'll be two approvals when kantai's comments are addressed. |
… is always set henceforth (even if there is no alternative recipient, this value is set to the miner address)
…ither a standard or contract principal
…tive contract or standard principal
…s alterantive block reward recipients
…rnative recipient, via the StacksMessasgeCodec trait implementation for clarity::vm::Value.
…dules, grouped by functional requirements tested
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.
LGTM!
Thanks for the approvals! Let's get #3180 merged to this PR, and then I'll merge this all into |
EDIT: this PR now supports building coinbase transactions that pay to either a smart contract or an alternative standard principal. The latter permits the miner to pay to a cold storage address automatically.
This PR implements #3101 by altering the
TransactionPayload::Coinbase(..)
type variant to include an optionalsmart contract addressalternative recipient address, be it a contract or standard principal address. If given, the encoded transaction payload will have ID0x05
, and will include a serializedsmart contract identifierprincipal. When processed in epoch 2.1, the block reward will be transferred to thissmart contractaddress instead of the miner. In addition, I have updated the node software to accept acontract or standard address under thepay_to_contract
contract[miner]
heading calledblock_reward_address
, which if given, will cause the node to createpay-to-contractalternative recipient coinbases for blocks mined after epoch 2.1 (the node ignores this field in epoch 2.05 and earlier).I have added test coverage for:
The code includes the relevant feature gating to ensure that a
pay-to-contractpay-to-alt-principal block can only be successfully preprocessed in epoch 2.1. This prevents a Stacks 2.1-series node from accepting apay-to-contractpay-to-alt-principal block at all before epoch 2.1 goes live. But, this differs slightly from how a 2.05-series node will handle such a block -- the 2.05-series node will not even be able to decode it, thereby making any attempt to push such a block to it fail with either an HTTP 400 (if sent via HTTP) or a temporary ban (if sent via p2p). I can make the 2.1-series node just as strict by adding feature gates to the p2p and HTTP endpoints, but I'm not sure it will make an appreciable difference in safety. Also, I'm not sure it's a good idea to make 2.1-series nodes ban each other for this, since if it turns out there's an off-by-one error somewhere in the gating logic that causes nodes to produce these blocks before they're supported, the nodes could accidentally all ban each other, leading to a catastrophic network partition. Open to feedback on this.