Skip to content

Instantly share code, notes, and snippets.

@daira
Created November 12, 2022 00:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daira/50ef266bef50c291d2adb8506a9dae11 to your computer and use it in GitHub Desktop.
Save daira/50ef266bef50c291d2adb8506a9dae11 to your computer and use it in GitHub Desktop.
INCORRECTLY calculate the Zcash supply after a given block height on Mainnet or Testnet (not taking into account the slow start)
#!/usr/bin/env python3
# ***INCORRECT VERSION, FOR ILLUSTRATION ONLY***
def exact_div(x, y):
assert x % y == 0
return x // y
# floor(u/x + v/y)
def div2(u, x, v, y):
return (u*y + v*x) // (x*y)
TESTNET = 0
MAINNET = 1
class Network:
# <https://zips.z.cash/protocol/protocol.pdf#constants>
def __init__(self, network):
self.BlossomActivationHeight = 653600 if network == MAINNET else 584000
SlowStartInterval = 20000
MaxBlockSubsidy = 1250000000 # 12.5 ZEC
PreBlossomHalvingInterval = 840000
PreBlossomPoWTargetSpacing = 150
PostBlossomPoWTargetSpacing = 75
# <https://zips.z.cash/protocol/protocol.pdf#diffadjustment>
def IsBlossomActivated(self, height):
return height >= self.BlossomActivationHeight
BlossomPoWTargetSpacingRatio = exact_div(PreBlossomPoWTargetSpacing, PostBlossomPoWTargetSpacing)
# no need for floor since this is necessarily an integer
PostBlossomHalvingInterval = PreBlossomHalvingInterval * BlossomPoWTargetSpacingRatio
# <https://zips.z.cash/protocol/protocol.pdf#subsidies>
SlowStartShift = exact_div(SlowStartInterval, 2)
SlowStartRate = exact_div(MaxBlockSubsidy, SlowStartInterval)
def Halving(self, height):
if height < self.SlowStartShift:
return 0
elif not self.IsBlossomActivated(height):
return (height - self.SlowStartShift) // self.PreBlossomHalvingInterval
else:
return div2(self.BlossomActivationHeight - self.SlowStartShift, self.PreBlossomHalvingInterval,
height - self.BlossomActivationHeight, self.PostBlossomHalvingInterval)
def BlockSubsidy(self, height):
#if height < self.SlowStartShift:
# return self.SlowStartRate * height
#elif self.SlowStartShift <= height and height < self.SlowStartInterval:
# return self.SlowStartRate * (height + 1)
#if self.SlowStartInterval <= height and not self.IsBlossomActivated(height):
# THIS IS WRONG: it does not take into account the slow start
if not self.IsBlossomActivated(height):
return self.MaxBlockSubsidy // (1 << self.Halving(height))
else:
return self.MaxBlockSubsidy // (self.BlossomPoWTargetSpacingRatio << self.Halving(height))
def SupplyAfterHeight(self, height):
return sum((self.BlockSubsidy(h) for h in range(height+1)))
# WRONG VALUES (NO SLOW START)
print(Network(MAINNET).SupplyAfterHeight(1799152)) # September 6th 2022 12:15 UTC
print(Network(MAINNET).SupplyAfterHeight(1875375)) # November 11th 2022 11:35 UTC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment