From bf4972d068f1c11298e50dfe2941469d6f258dfe Mon Sep 17 00:00:00 2001 From: Jonathan Chappelow Date: Sat, 17 Jun 2023 12:10:42 -0500 Subject: [PATCH] update for dcp0012 (subsidy split r2) --- cmd/dcrdata/go.mod | 2 +- cmd/dcrdata/internal/api/apiroutes.go | 12 ++- cmd/dcrdata/internal/api/insight/apiroutes.go | 2 + cmd/dcrdata/internal/api/insight/converter.go | 14 +++- cmd/dcrdata/internal/explorer/explorer.go | 2 + .../internal/explorer/explorerroutes.go | 3 +- cmd/dcrdata/main.go | 2 + db/dcrpg/go.mod | 2 +- db/dcrpg/pgblockchain.go | 73 ++++++++++++++++++- txhelpers/subsidy.go | 36 +++++---- txhelpers/subsidy_test.go | 20 ++--- txhelpers/txhelpers.go | 28 +++++++ 12 files changed, 163 insertions(+), 33 deletions(-) diff --git a/cmd/dcrdata/go.mod b/cmd/dcrdata/go.mod index 7e09bd194..d8ba5d90d 100644 --- a/cmd/dcrdata/go.mod +++ b/cmd/dcrdata/go.mod @@ -12,6 +12,7 @@ replace ( require ( github.com/caarlos0/env/v6 v6.10.1 github.com/decred/dcrd/blockchain/stake/v5 v5.0.0 + github.com/decred/dcrd/blockchain/standalone/v2 v2.2.0 github.com/decred/dcrd/chaincfg/chainhash v1.0.4 github.com/decred/dcrd/chaincfg/v3 v3.2.0 github.com/decred/dcrd/dcrutil/v4 v4.0.1 @@ -86,7 +87,6 @@ require ( github.com/decred/dcrd/addrmgr/v2 v2.0.1 // indirect github.com/decred/dcrd/blockchain/stake/v3 v3.0.0 // indirect github.com/decred/dcrd/blockchain/stake/v4 v4.0.0 // indirect - github.com/decred/dcrd/blockchain/standalone/v2 v2.2.0 // indirect github.com/decred/dcrd/blockchain/v4 v4.0.2 // indirect github.com/decred/dcrd/certgen v1.1.1 // indirect github.com/decred/dcrd/connmgr/v3 v3.1.0 // indirect diff --git a/cmd/dcrdata/internal/api/apiroutes.go b/cmd/dcrdata/internal/api/apiroutes.go index bc784fda0..5dd518871 100644 --- a/cmd/dcrdata/internal/api/apiroutes.go +++ b/cmd/dcrdata/internal/api/apiroutes.go @@ -22,6 +22,7 @@ import ( "sync" "time" + "github.com/decred/dcrd/blockchain/standalone/v2" "github.com/decred/dcrd/chaincfg/chainhash" "github.com/decred/dcrd/chaincfg/v3" "github.com/decred/dcrd/dcrutil/v4" @@ -71,6 +72,8 @@ type DataSource interface { AddressRowsCompact(address string) ([]*dbtypes.AddressRowCompact, error) Height() int64 IsDCP0010Active(height int64) bool + IsDCP0011Active(height int64) bool + IsDCP0012Active(height int64) bool AllAgendas() (map[string]dbtypes.MileStone, error) GetTicketInfo(txid string) (*apitypes.TicketInfo, error) PowerlessTickets() (*apitypes.PowerlessTickets, error) @@ -1271,8 +1274,13 @@ func (c *appContext) blockSubsidies(w http.ResponseWriter, r *http.Request) { } } - useDCP0010 := c.DataSource.IsDCP0010Active(idx) - work, stake, tax := txhelpers.RewardsAtBlock(idx, uint16(numVotes), c.Params, useDCP0010) + ssv := standalone.SSVOriginal + if c.DataSource.IsDCP0012Active(idx) { + ssv = standalone.SSVDCP0012 + } else if c.DataSource.IsDCP0010Active(idx) { + ssv = standalone.SSVDCP0010 + } + work, stake, tax := txhelpers.RewardsAtBlock(idx, uint16(numVotes), c.Params, ssv) rewards := apitypes.BlockSubsidies{ BlockNum: idx, BlockHash: hash, diff --git a/cmd/dcrdata/internal/api/insight/apiroutes.go b/cmd/dcrdata/internal/api/insight/apiroutes.go index 6b76e6c66..92a85215a 100644 --- a/cmd/dcrdata/internal/api/insight/apiroutes.go +++ b/cmd/dcrdata/internal/api/insight/apiroutes.go @@ -44,6 +44,8 @@ type BlockDataSource interface { GetTransactionHex(txid *chainhash.Hash) string Height() int64 DCP0010ActivationHeight() int64 + DCP0011ActivationHeight() int64 + DCP0012ActivationHeight() int64 InsightAddressTransactions(addr []string, recentBlockHeight int64) (txs, recentTxs []chainhash.Hash, err error) SendRawTransaction(txhex string) (string, error) SpendDetailsForFundingTx(fundHash string) ([]*apitypes.SpendByFundingHash, error) diff --git a/cmd/dcrdata/internal/api/insight/converter.go b/cmd/dcrdata/internal/api/insight/converter.go index d6d9edf37..3c92394c1 100644 --- a/cmd/dcrdata/internal/api/insight/converter.go +++ b/cmd/dcrdata/internal/api/insight/converter.go @@ -7,6 +7,7 @@ package insight import ( "math" + "github.com/decred/dcrd/blockchain/standalone/v2" "github.com/decred/dcrd/dcrutil/v4" chainjson "github.com/decred/dcrd/rpc/jsonrpc/types/v4" @@ -157,10 +158,19 @@ func (iapi *InsightApi) DcrToInsightBlock(inBlocks []*chainjson.GetBlockVerboseR if dcp0010Height == -1 { dcp0010Height = math.MaxInt64 } + dcp0012Height := iapi.BlockData.DCP0012ActivationHeight() + if dcp0012Height == -1 { + dcp0012Height = math.MaxInt64 + } RewardAtBlock := func(blocknum int64, voters uint16) float64 { - useDCP0010 := blocknum >= dcp0010Height - work, stake, tax := txhelpers.RewardsAtBlock(blocknum, voters, iapi.params, useDCP0010) + var ssv standalone.SubsidySplitVariant = standalone.SSVOriginal + if blocknum >= dcp0012Height { + ssv = standalone.SSVDCP0012 + } else if blocknum >= dcp0010Height { + ssv = standalone.SSVDCP0010 + } + work, stake, tax := txhelpers.RewardsAtBlock(blocknum, voters, iapi.params, ssv) return dcrutil.Amount(work + stake*int64(voters) + tax).ToCoin() } diff --git a/cmd/dcrdata/internal/explorer/explorer.go b/cmd/dcrdata/internal/explorer/explorer.go index 4744a4b11..bfbbaf9e8 100644 --- a/cmd/dcrdata/internal/explorer/explorer.go +++ b/cmd/dcrdata/internal/explorer/explorer.go @@ -108,6 +108,8 @@ type explorerDataSource interface { GetHeight() (int64, error) TxHeight(txid *chainhash.Hash) (height int64) DCP0010ActivationHeight() int64 + DCP0011ActivationHeight() int64 + DCP0012ActivationHeight() int64 BlockSubsidy(height int64, voters uint16) *chainjson.GetBlockSubsidyResult GetExplorerFullBlocks(start int, end int) []*types.BlockInfo CurrentDifficulty() (float64, error) diff --git a/cmd/dcrdata/internal/explorer/explorerroutes.go b/cmd/dcrdata/internal/explorer/explorerroutes.go index 34c6a0731..2cf68169c 100644 --- a/cmd/dcrdata/internal/explorer/explorerroutes.go +++ b/cmd/dcrdata/internal/explorer/explorerroutes.go @@ -2468,7 +2468,8 @@ func (exp *explorerUI) StatsPage(w http.ResponseWriter, r *http.Request) { // Subsidies dcp0010Height := exp.dataSource.DCP0010ActivationHeight() - ultSubsidy := txhelpers.UltimateSubsidy(exp.ChainParams, dcp0010Height) + dcp0012Height := exp.dataSource.DCP0012ActivationHeight() + ultSubsidy := txhelpers.UltimateSubsidy(exp.ChainParams, dcp0010Height, dcp0012Height) bestBlockHeight, err := exp.dataSource.GetHeight() if err != nil { log.Errorf("GetHeight failed: %v", err) diff --git a/cmd/dcrdata/main.go b/cmd/dcrdata/main.go index be34933e3..bfc68f06a 100644 --- a/cmd/dcrdata/main.go +++ b/cmd/dcrdata/main.go @@ -1098,6 +1098,8 @@ func _main(ctx context.Context) error { // Update the current chain state in the ChainDB. chainDB.UpdateChainState(blockData.BlockchainInfo) log.Infof("Current DCP0010 activation height is %d.", chainDB.DCP0010ActivationHeight()) + log.Infof("Current DCP0011 activation height is %d.", chainDB.DCP0011ActivationHeight()) + log.Infof("Current DCP0012 activation height is %d.", chainDB.DCP0012ActivationHeight()) if err = explore.Store(blockData, msgBlock); err != nil { return fmt.Errorf("Failed to store initial block data for explorer pages: %w", err) diff --git a/db/dcrpg/go.mod b/db/dcrpg/go.mod index 2af30ea76..09f2a1f14 100644 --- a/db/dcrpg/go.mod +++ b/db/dcrpg/go.mod @@ -7,6 +7,7 @@ replace github.com/decred/dcrdata/v8 => ../../ require ( github.com/davecgh/go-spew v1.1.1 github.com/decred/dcrd/blockchain/stake/v5 v5.0.0 + github.com/decred/dcrd/blockchain/standalone/v2 v2.2.0 github.com/decred/dcrd/chaincfg/chainhash v1.0.4 github.com/decred/dcrd/chaincfg/v3 v3.2.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 @@ -29,7 +30,6 @@ require ( github.com/cespare/xxhash v1.1.0 // indirect github.com/dchest/siphash v1.2.3 // indirect github.com/decred/base58 v1.0.5 // indirect - github.com/decred/dcrd/blockchain/standalone/v2 v2.2.0 // indirect github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect github.com/decred/dcrd/database/v3 v3.0.1 // indirect diff --git a/db/dcrpg/pgblockchain.go b/db/dcrpg/pgblockchain.go index e21a3e464..37ba0245d 100644 --- a/db/dcrpg/pgblockchain.go +++ b/db/dcrpg/pgblockchain.go @@ -18,6 +18,7 @@ import ( "time" "github.com/decred/dcrd/blockchain/stake/v5" + "github.com/decred/dcrd/blockchain/standalone/v2" "github.com/decred/dcrd/chaincfg/chainhash" "github.com/decred/dcrd/chaincfg/v3" "github.com/decred/dcrd/dcrec/secp256k1/v4" @@ -4722,6 +4723,66 @@ func (pgb *ChainDB) IsDCP0010Active(height int64) bool { return height >= activeHeight } +// DCP0011ActivationHeight indicates the height at which the blake3pow +// agenda will activate, or -1 if it is not determined yet. +func (pgb *ChainDB) DCP0011ActivationHeight() int64 { + if _, ok := txhelpers.Blake3PowStakeVer(pgb.chainParams); !ok { + return 0 // activate at genesis if no deployment defined in chaincfg.Params + } + + agendaInfo, found := pgb.ChainInfo().AgendaMileStones[chaincfg.VoteIDBlake3Pow] + if !found { + log.Warn("The changesubsidysplit agenda is missing.") + return 0 + } + + switch agendaInfo.Status { + case dbtypes.ActivatedAgendaStatus, dbtypes.LockedInAgendaStatus: + return agendaInfo.Activated // rci already added for lockedin + } + return -1 // not activated, and no future activation height known +} + +// IsDCP0011Active indicates if the "blake3pow" consensus deployment is +// active at the given height according to the current status of the agendas. +func (pgb *ChainDB) IsDCP0011Active(height int64) bool { + activeHeight := pgb.DCP0011ActivationHeight() + if activeHeight == -1 { + return false + } + return height >= activeHeight +} + +// DCP0012ActivationHeight indicates the height at which the +// changesubsidysplitr2 agenda will activate, or -1 if it is not determined yet. +func (pgb *ChainDB) DCP0012ActivationHeight() int64 { + if _, ok := txhelpers.SubsidySplitR2StakeVer(pgb.chainParams); !ok { + return 0 // activate at genesis if no deployment defined in chaincfg.Params + } + + agendaInfo, found := pgb.ChainInfo().AgendaMileStones[chaincfg.VoteIDChangeSubsidySplitR2] + if !found { + log.Warn("The changesubsidysplit agenda is missing.") + return 0 + } + + switch agendaInfo.Status { + case dbtypes.ActivatedAgendaStatus, dbtypes.LockedInAgendaStatus: + return agendaInfo.Activated // rci already added for lockedin + } + return -1 // not activated, and no future activation height known +} + +// IsDCP0012Active indicates if the "blake3pow" consensus deployment is +// active at the given height according to the current status of the agendas. +func (pgb *ChainDB) IsDCP0012Active(height int64) bool { + activeHeight := pgb.DCP0012ActivationHeight() + if activeHeight == -1 { + return false + } + return height >= activeHeight +} + // CurrentCoinSupply gets the current coin supply as an *apitypes.CoinSupply, // which additionally contains block info and max supply. func (pgb *ChainDB) CurrentCoinSupply() (supply *apitypes.CoinSupply) { @@ -4732,13 +4793,14 @@ func (pgb *ChainDB) CurrentCoinSupply() (supply *apitypes.CoinSupply) { } dcp0010Height := pgb.DCP0010ActivationHeight() + dcp0012Height := pgb.DCP0012ActivationHeight() hash, height := pgb.BestBlockStr() return &apitypes.CoinSupply{ Height: height, Hash: hash, Mined: int64(coinSupply), - Ultimate: txhelpers.UltimateSubsidy(pgb.chainParams, dcp0010Height), + Ultimate: txhelpers.UltimateSubsidy(pgb.chainParams, dcp0010Height, dcp0012Height), } } @@ -5708,8 +5770,13 @@ func trimmedTxInfoFromMsgTx(txraw *chainjson.TxRawResult, ticketPrice int64, msg // BlockSubsidy gets the *chainjson.GetBlockSubsidyResult for the given height // and number of voters, which can be fewer than the network parameter allows. func (pgb *ChainDB) BlockSubsidy(height int64, voters uint16) *chainjson.GetBlockSubsidyResult { - dcp0010Active := pgb.IsDCP0010Active(height) - work, stake, tax := txhelpers.RewardsAtBlock(height, voters, pgb.chainParams, dcp0010Active) + ssv := standalone.SSVOriginal + if pgb.IsDCP0012Active(height) { + ssv = standalone.SSVDCP0012 + } else if pgb.IsDCP0010Active(height) { + ssv = standalone.SSVDCP0010 + } + work, stake, tax := txhelpers.RewardsAtBlock(height, voters, pgb.chainParams, ssv) stake *= int64(voters) return &chainjson.GetBlockSubsidyResult{ PoW: work, diff --git a/txhelpers/subsidy.go b/txhelpers/subsidy.go index d5b9d0c23..eb90e9b67 100644 --- a/txhelpers/subsidy.go +++ b/txhelpers/subsidy.go @@ -17,6 +17,7 @@ import ( type netHeight struct { net uint32 dcp10height int64 + dcp12height int64 } type subsidySumCache struct { @@ -41,19 +42,23 @@ func (ssc *subsidySumCache) store(nh netHeight, total int64) { var ultimateSubsidies = subsidySumCache{m: map[netHeight]int64{}} // UltimateSubsidy computes the total subsidy over the entire subsidy -// distribution period of the network, given a known height at which the subsidy -// split change goes into effect (DCP0010). If the height is unknown, provide -1 -// to perform the computation with the original subsidy split for all heights. -func UltimateSubsidy(params *chaincfg.Params, subsidySplitChangeHeight int64) int64 { +// distribution period of the network, given a known height at which the first +// and second subsidy split change go into effect (DCP0010 and DCP0012). If the +// height is unknown, provide -1 to perform the computation with the original +// subsidy split for all heights. +func UltimateSubsidy(params *chaincfg.Params, dcp0010Height, dcp0012Height int64) int64 { // Check previously computed ultimate subsidies. - nh := netHeight{uint32(params.Net), subsidySplitChangeHeight} + nh := netHeight{uint32(params.Net), dcp0010Height, dcp0012Height} result, ok := ultimateSubsidies.load(nh) if ok { return result } - if subsidySplitChangeHeight == -1 { - subsidySplitChangeHeight = math.MaxInt64 + if dcp0010Height == -1 { + dcp0010Height = math.MaxInt64 + } + if dcp0012Height == -1 { + dcp0012Height = math.MaxInt64 } votesPerBlock := params.VotesPerBlock() @@ -62,9 +67,14 @@ func UltimateSubsidy(params *chaincfg.Params, subsidySplitChangeHeight int64) in subsidyCache := networkSubsidyCache(params) subsidySum := func(height int64) int64 { - useDCP0010 := height >= subsidySplitChangeHeight - work := subsidyCache.CalcWorkSubsidyV2(height, votesPerBlock, useDCP0010) - vote := subsidyCache.CalcStakeVoteSubsidyV2(height, useDCP0010) * int64(votesPerBlock) + var ssv standalone.SubsidySplitVariant = standalone.SSVOriginal + if height >= dcp0012Height { + ssv = standalone.SSVDCP0012 + } else if height >= dcp0010Height { + ssv = standalone.SSVDCP0010 + } + work := subsidyCache.CalcWorkSubsidyV3(height, votesPerBlock, ssv) + vote := subsidyCache.CalcStakeVoteSubsidyV3(height, ssv) * int64(votesPerBlock) // With voters set to max (votesPerBlock), treasury bool is unimportant. treasury := subsidyCache.CalcTreasurySubsidy(height, votesPerBlock, false) return work + vote + treasury @@ -130,10 +140,10 @@ func networkSubsidyCache(p *chaincfg.Params) *standalone.SubsidyCache { // at for the specified block index, assuming a certain number of votes. The // stake reward is for a single vote. The total reward for the block is thus // work + stake * votes + tax. -func RewardsAtBlock(blockIdx int64, votes uint16, p *chaincfg.Params, useDCP0010 bool) (work, stake, tax int64) { +func RewardsAtBlock(blockIdx int64, votes uint16, p *chaincfg.Params, ssv standalone.SubsidySplitVariant) (work, stake, tax int64) { subsidyCache := networkSubsidyCache(p) - work = subsidyCache.CalcWorkSubsidyV2(blockIdx, votes, useDCP0010) - stake = subsidyCache.CalcStakeVoteSubsidyV2(blockIdx, useDCP0010) + work = subsidyCache.CalcWorkSubsidyV3(blockIdx, votes, ssv) + stake = subsidyCache.CalcStakeVoteSubsidyV3(blockIdx, ssv) treasuryActive := IsTreasuryActive(p.Net, blockIdx) tax = subsidyCache.CalcTreasurySubsidy(blockIdx, votes, treasuryActive) return diff --git a/txhelpers/subsidy_test.go b/txhelpers/subsidy_test.go index 16ab3a671..e053a7c8c 100644 --- a/txhelpers/subsidy_test.go +++ b/txhelpers/subsidy_test.go @@ -13,7 +13,7 @@ import ( func TestUltimateSubsidy(t *testing.T) { // Mainnet wantMainnetSubsidy := int64(2099999999800912) - totalSubsidy := UltimateSubsidy(chaincfg.MainNetParams(), -1) + totalSubsidy := UltimateSubsidy(chaincfg.MainNetParams(), -1, -1) if totalSubsidy != wantMainnetSubsidy { t.Errorf("Bad total subsidy; want %d, got %d", @@ -21,7 +21,7 @@ func TestUltimateSubsidy(t *testing.T) { } // verify cache - totalSubsidy2 := UltimateSubsidy(chaincfg.MainNetParams(), -1) + totalSubsidy2 := UltimateSubsidy(chaincfg.MainNetParams(), -1, -1) if totalSubsidy != totalSubsidy2 { t.Errorf("Bad total subsidy; want %d, got %d", totalSubsidy, totalSubsidy2) @@ -29,7 +29,7 @@ func TestUltimateSubsidy(t *testing.T) { // Mainnet with dcp0010 activating at 638976 wantMainnetSubsidy = int64(2100000000015952) - totalSubsidyDCP0010 := UltimateSubsidy(chaincfg.MainNetParams(), 638976) + totalSubsidyDCP0010 := UltimateSubsidy(chaincfg.MainNetParams(), 638976, -1) if totalSubsidyDCP0010 != wantMainnetSubsidy { t.Fatalf("Bad total subsidy; want %d, got %d", @@ -38,7 +38,7 @@ func TestUltimateSubsidy(t *testing.T) { // Testnet wantTestnetSubsidy := int64(526540305161472) - totalTNSubsidy := UltimateSubsidy(chaincfg.TestNet3Params(), -1) + totalTNSubsidy := UltimateSubsidy(chaincfg.TestNet3Params(), -1, -1) if totalTNSubsidy != wantTestnetSubsidy { t.Errorf("Bad total subsidy; want %d, got %d", @@ -46,21 +46,21 @@ func TestUltimateSubsidy(t *testing.T) { } // verify cache - totalTNSubsidy2 := UltimateSubsidy(chaincfg.TestNet3Params(), -1) + totalTNSubsidy2 := UltimateSubsidy(chaincfg.TestNet3Params(), -1, -1) if totalTNSubsidy != totalTNSubsidy2 { t.Errorf("Bad total subsidy; want %d, got %d", totalTNSubsidy, totalTNSubsidy2) } // re-verify mainnet cache - totalSubsidy3 := UltimateSubsidy(chaincfg.MainNetParams(), -1) + totalSubsidy3 := UltimateSubsidy(chaincfg.MainNetParams(), -1, -1) if totalSubsidy != totalSubsidy3 { t.Errorf("Bad total subsidy; want %d, got %d", totalSubsidy, totalSubsidy3) } // re-verify mainnet cache (dcp0010) - totalSubsidy4 := UltimateSubsidy(chaincfg.MainNetParams(), 638976) + totalSubsidy4 := UltimateSubsidy(chaincfg.MainNetParams(), 638976, -1) if totalSubsidyDCP0010 != totalSubsidy4 { t.Errorf("Bad total subsidy; want %d, got %d", totalSubsidyDCP0010, totalSubsidy4) @@ -69,16 +69,16 @@ func TestUltimateSubsidy(t *testing.T) { func BenchmarkUltimateSubsidy(b *testing.B) { // warm up - totalSubsidy := UltimateSubsidy(chaincfg.MainNetParams(), -1) + totalSubsidy := UltimateSubsidy(chaincfg.MainNetParams(), -1, -1) // verify cache - totalSubsidy2 := UltimateSubsidy(chaincfg.MainNetParams(), -1) + totalSubsidy2 := UltimateSubsidy(chaincfg.MainNetParams(), -1, -1) if totalSubsidy != totalSubsidy2 { b.Errorf("Bad total subsidy; want %d, got %d", totalSubsidy, totalSubsidy2) } for i := 0; i < b.N; i++ { - totalSubsidy = UltimateSubsidy(chaincfg.MainNetParams(), -1) + totalSubsidy = UltimateSubsidy(chaincfg.MainNetParams(), -1, -1) } if totalSubsidy != totalSubsidy2 { diff --git a/txhelpers/txhelpers.go b/txhelpers/txhelpers.go index 21a40942e..eca0bbbd7 100644 --- a/txhelpers/txhelpers.go +++ b/txhelpers/txhelpers.go @@ -75,6 +75,34 @@ func SubsidySplitStakeVer(params *chaincfg.Params) (uint32, bool) { return 0, false } +// Blake3PowStakeVer locates the "blake3pow" agenda item in the consensus +// deployments defined in the provided chain parameters. If found, the +// corresponding stake version is returned. +func Blake3PowStakeVer(params *chaincfg.Params) (uint32, bool) { + for stakeVer, deployments := range params.Deployments { + for i := range deployments { + if deployments[i].Vote.Id == chaincfg.VoteIDBlake3Pow { + return stakeVer, true + } + } + } + return 0, false +} + +// SubsidySplitR2StakeVer locates the "changesubsidysplitr2" agenda item in the +// consensus deployments defined in the provided chain parameters. If found, the +// corresponding stake version is returned. +func SubsidySplitR2StakeVer(params *chaincfg.Params) (uint32, bool) { + for stakeVer, deployments := range params.Deployments { + for i := range deployments { + if deployments[i].Vote.Id == chaincfg.VoteIDChangeSubsidySplitR2 { + return stakeVer, true + } + } + } + return 0, false +} + // DCP0010ActivationHeight indicates the height at which the // "changesubsidysplit" consensus change activates for the provided // getblockchaininfo result.