decred.org/dcrwallet/v3@v3.1.0/deployments/deployments.go (about) 1 // Copyright (c) 2018 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package deployments 6 7 import ( 8 "context" 9 10 "decred.org/dcrwallet/v3/errors" 11 "decred.org/dcrwallet/v3/rpc/client/dcrd" 12 "github.com/decred/dcrd/chaincfg/v3" 13 dcrdtypes "github.com/decred/dcrd/rpc/jsonrpc/types/v4" 14 "github.com/decred/dcrd/wire" 15 ) 16 17 // HardcodedDeployment specifies hardcoded block heights that a deployment 18 // activates at. If the value is negative, the deployment is either inactive or 19 // can't be determined due to the uniqueness properties of the network. 20 // 21 // Since these are hardcoded deployments, and cannot support every possible 22 // network, conditional logic should only be applied when a deployment is 23 // active, not when it is inactive. 24 type HardcodedDeployment struct { 25 MainNetActivationHeight int32 26 TestNet2ActivationHeight int32 27 TestNet3ActivationHeight int32 28 SimNetActivationHeight int32 29 } 30 31 // DCP0001 specifies hard forking changes to the stake difficulty algorithm as 32 // defined by https://github.com/decred/dcps/blob/master/dcp-0001/dcp-0001.mediawiki. 33 var DCP0001 = HardcodedDeployment{ 34 MainNetActivationHeight: 149248, 35 TestNet2ActivationHeight: 46128, 36 TestNet3ActivationHeight: 0, 37 SimNetActivationHeight: 0, 38 } 39 40 // DCP0002 specifies the activation of the OP_SHA256 hard fork as defined by 41 // https://github.com/decred/dcps/blob/master/dcp-0002/dcp-0002.mediawiki. 42 var DCP0002 = HardcodedDeployment{ 43 MainNetActivationHeight: 189568, 44 TestNet2ActivationHeight: 151968, 45 TestNet3ActivationHeight: 0, 46 SimNetActivationHeight: 0, 47 } 48 49 // DCP0003 specifies the activation of a CSV soft fork as defined by 50 // https://github.com/decred/dcps/blob/master/dcp-0003/dcp-0003.mediawiki. 51 var DCP0003 = HardcodedDeployment{ 52 MainNetActivationHeight: 189568, 53 TestNet2ActivationHeight: 151968, 54 TestNet3ActivationHeight: 0, 55 SimNetActivationHeight: 0, 56 } 57 58 // Active returns whether the hardcoded deployment is active at height on the 59 // network specified by params. Active always returns false for unrecognized 60 // networks. 61 func (d *HardcodedDeployment) Active(height int32, net wire.CurrencyNet) bool { 62 var activationHeight int32 = -1 63 switch net { 64 case wire.MainNet: 65 activationHeight = d.MainNetActivationHeight 66 case 0x48e7a065: // testnet2 67 activationHeight = d.TestNet2ActivationHeight 68 case wire.TestNet3: 69 activationHeight = d.TestNet3ActivationHeight 70 case wire.SimNet: 71 activationHeight = d.SimNetActivationHeight 72 } 73 return activationHeight >= 0 && height >= activationHeight 74 } 75 76 const ( 77 lockedinStatus = dcrdtypes.AgendaInfoStatusLockedIn 78 activeStatus = dcrdtypes.AgendaInfoStatusActive 79 ) 80 81 // DCP0010Active returns whether the consensus rules for the next block with the 82 // current chain tip height requires the subsidy split as specified in DCP0010. 83 // DCP0010 is always active on simnet, and requires the RPC syncer to detect 84 // activation on mainnet and testnet3. 85 func DCP0010Active(ctx context.Context, height int32, params *chaincfg.Params, 86 syncer interface{}) (bool, error) { 87 88 net := params.Net 89 rcai := int32(params.RuleChangeActivationInterval) 90 91 if net == wire.SimNet { 92 return true, nil 93 } 94 if net != wire.MainNet && net != wire.TestNet3 { 95 return false, nil 96 } 97 rpc, ok := syncer.(*dcrd.RPC) 98 if !ok { 99 return false, errors.E(errors.Bug, "DCP0010 activation check requires RPC syncer") 100 } 101 var resp dcrdtypes.GetBlockChainInfoResult 102 err := rpc.Call(ctx, "getblockchaininfo", &resp) 103 if err != nil { 104 return false, err 105 } 106 d, ok := resp.Deployments[chaincfg.VoteIDChangeSubsidySplit] 107 if !ok { 108 return false, nil 109 } 110 switch { 111 case d.Status == lockedinStatus && height == int32(d.Since)+rcai-1: 112 return true, nil 113 case d.Status == activeStatus: 114 return true, nil 115 default: 116 return false, nil 117 } 118 } 119 120 // DCP0012Active returns whether the consensus rules for the next block with the 121 // current chain tip height requires the version 2 subsidy split as specified in 122 // DCP0012. DCP0012 requires the RPC syncer to detect activation on mainnet, 123 // testnet3 and simnet. 124 func DCP0012Active(ctx context.Context, height int32, params *chaincfg.Params, 125 syncer interface{}) (bool, error) { 126 127 net := params.Net 128 rcai := int32(params.RuleChangeActivationInterval) 129 130 if net != wire.MainNet && net != wire.TestNet3 && net != wire.SimNet { 131 return false, nil 132 } 133 rpc, ok := syncer.(*dcrd.RPC) 134 if !ok { 135 return false, errors.E(errors.Bug, "DCP0012 activation check requires RPC syncer") 136 } 137 var resp dcrdtypes.GetBlockChainInfoResult 138 err := rpc.Call(ctx, "getblockchaininfo", &resp) 139 if err != nil { 140 return false, err 141 } 142 d, ok := resp.Deployments[chaincfg.VoteIDChangeSubsidySplitR2] 143 if !ok { 144 return false, nil 145 } 146 switch { 147 case d.Status == lockedinStatus && height == int32(d.Since)+rcai-1: 148 return true, nil 149 case d.Status == activeStatus: 150 return true, nil 151 default: 152 return false, nil 153 } 154 }