From 25c026e060b4c80c8311474a26259d83c94bc6dd Mon Sep 17 00:00:00 2001
From: Roy Lee <roylee17@gmail.com>
Date: Tue, 12 Jun 2018 21:11:42 -0700
Subject: [PATCH] [lbry] blockchain: change Block Subsidy algorithm

---
 blockchain/validate.go | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/blockchain/validate.go b/blockchain/validate.go
index f7831469..2fd5d7fd 100644
--- a/blockchain/validate.go
+++ b/blockchain/validate.go
@@ -40,7 +40,7 @@ const (
 
 	// baseSubsidy is the starting subsidy amount for mined blocks.  This
 	// value is halved every SubsidyHalvingInterval blocks.
-	baseSubsidy = 50 * btcutil.SatoshiPerBitcoin
+	baseSubsidy = 500 * btcutil.SatoshiPerBitcoin
 )
 
 var (
@@ -192,12 +192,42 @@ func isBIP0030Node(node *blockNode) bool {
 // At the target block generation rate for the main network, this is
 // approximately every 4 years.
 func CalcBlockSubsidy(height int32, chainParams *chaincfg.Params) int64 {
-	if chainParams.SubsidyReductionInterval == 0 {
-		return baseSubsidy
+	h := int64(height)
+	if h == 0 {
+		return btcutil.SatoshiPerBitcoin * 4e8
+	}
+	if h <= 5100 {
+		return btcutil.SatoshiPerBitcoin
+	}
+	if h <= 55000 {
+		return btcutil.SatoshiPerBitcoin * (1 + (h-5001)/100)
 	}
 
-	// Equivalent to: baseSubsidy / 2^(height/subsidyHalvingInterval)
-	return baseSubsidy >> uint(height/chainParams.SubsidyReductionInterval)
+	lv := (h - 55001) / int64(chainParams.SubsidyReductionInterval)
+	reduction := (int64(math.Sqrt((float64(8*lv))+1)) - 1) / 2
+	for !withinLevelBounds(reduction, lv) {
+		if ((reduction*reduction + reduction) >> 1) > lv {
+			reduction--
+		} else {
+			reduction++
+		}
+	}
+	subsidyReduction := btcutil.SatoshiPerBitcoin * reduction
+	if subsidyReduction >= baseSubsidy {
+		return 0
+	}
+	return baseSubsidy - subsidyReduction
+}
+
+func withinLevelBounds(reduction int64, lv int64) bool {
+	if ((reduction*reduction + reduction) >> 1) > lv {
+		return false
+	}
+	reduction++
+	if ((reduction*reduction + reduction) >> 1) <= lv {
+		return false
+	}
+	return true
 }
 
 // CheckTransactionSanity performs some preliminary checks on a transaction to