Commit ccdfe22a authored by David Vorick's avatar David Vorick

types gets function 'CalculateNumSiacoins'

parent 36d41d41
......@@ -28,9 +28,17 @@ dependencies:
go get -u github.com/laher/goxc
go get -u golang.org/x/tools/cmd/cover
# pkgs changes which packages the makefile calls operate on. run changes which
# tests are run during testing.
run = Test
pkgs = ./api ./build ./compatibility ./crypto ./encoding ./modules ./modules/consensus \
./modules/explorer ./modules/gateway ./modules/host ./modules/miner \
./modules/renter ./modules/transactionpool ./modules/wallet \
./persist ./siac ./siae ./sync ./types
# fmt calls go fmt on all packages.
fmt:
go fmt ./...
go fmt $(pkgs)
# REBUILD touches all of the build-dependent source files, forcing them to be
# rebuilt. This is necessary because the go tool is not smart enough to trigger
......@@ -61,17 +69,6 @@ xc: dependencies test test-long REBUILD
clean:
rm -rf release doc/whitepaper.aux doc/whitepaper.log doc/whitepaper.pdf
# 3 commands and a variable are available for testing Sia packages. 'pkgs'
# indicates which packages should be tested, and defaults to all the packages
# with test files. Using './...' as default breaks compatibility with the cover
# command. 'test' runs short tests that should last no more than a few seconds,
# 'test-long' runs more thorough tests which should not last more than a few
# minutes.
run = Test
pkgs = ./api ./build ./compatibility ./crypto ./encoding ./modules ./modules/consensus \
./modules/explorer ./modules/gateway ./modules/host ./modules/miner \
./modules/renter ./modules/transactionpool ./modules/wallet \
./persist ./siac ./siae ./sync ./types
test: REBUILD
go test -short -tags='debug testing' -timeout=3s $(pkgs) -run=$(run)
test-v: REBUILD
......
......@@ -158,17 +158,7 @@ func checkSiacoinCount(tx *bolt.Tx) {
manageErr(tx, err)
}
// Count how many coins should exist
deflationBlocks := types.BlockHeight(types.InitialCoinbase - types.MinimumCoinbase)
expectedSiacoins := types.CalculateCoinbase(0).Add(types.CalculateCoinbase(blockHeight(tx))).Div(types.NewCurrency64(2))
if blockHeight(tx) < deflationBlocks {
expectedSiacoins = expectedSiacoins.Mul(types.NewCurrency64(uint64(blockHeight(tx) + 1)))
} else {
expectedSiacoins = expectedSiacoins.Mul(types.NewCurrency64(uint64(deflationBlocks + 1)))
trailingSiacoins := types.NewCurrency64(uint64(blockHeight(tx) - deflationBlocks)).Mul(types.CalculateCoinbase(blockHeight(tx)))
expectedSiacoins = expectedSiacoins.Add(trailingSiacoins)
}
expectedSiacoins := types.CalculateNumSiacoins(blockHeight(tx))
totalSiacoins := dscoSiacoins.Add(scoSiacoins).Add(fcSiacoins).Add(claimSiacoins)
if totalSiacoins.Cmp(expectedSiacoins) != 0 {
diagnostics := fmt.Sprintf("Wrong number of siacoins\nDsco: %v\nSco: %v\nFc: %v\nClaim: %v\n", dscoSiacoins, scoSiacoins, fcSiacoins, claimSiacoins)
......
......@@ -6,21 +6,6 @@ import (
"github.com/NebulousLabs/Sia/types"
)
// Calculates the total number of coins that have ever been created
// from the bockheight
func totalCurrency(height types.BlockHeight) types.Currency {
totalCoins := uint64(0)
coinbase := types.InitialCoinbase
minCoinbase := types.MinimumCoinbase
for i := types.BlockHeight(0); i <= height; i++ {
totalCoins += coinbase
if coinbase > minCoinbase {
coinbase--
}
}
return types.NewCurrency64(totalCoins).Mul(types.SiacoinPrecision)
}
// Returns many pieces of readily available information
func (e *Explorer) Statistics() modules.ExplorerStatistics {
e.mu.RLock()
......@@ -38,7 +23,7 @@ func (e *Explorer) Statistics() modules.ExplorerStatistics {
Target: target,
Difficulty: difficulty,
MaturityTimestamp: currentBlock.Timestamp,
TotalCoins: totalCurrency(e.blockchainHeight),
TotalCoins: types.CalculateNumSiacoins(e.blockchainHeight),
TransactionCount: e.transactionCount,
SiacoinInputCount: e.siacoinInputCount,
......
package explorer
import (
"testing"
)
......@@ -56,6 +56,20 @@ func CalculateCoinbase(height BlockHeight) Currency {
return NewCurrency64(base).Mul(SiacoinPrecision)
}
// CalculateNumSiacoins calculates the number of siacoins in circulation at a
// given height.
func CalculateNumSiacoins(height BlockHeight) Currency {
deflationBlocks := BlockHeight(InitialCoinbase - MinimumCoinbase)
avgDeflationSiacoins := CalculateCoinbase(0).Add(CalculateCoinbase(height)).Div(NewCurrency64(2))
if height <= deflationBlocks {
deflationSiacoins := avgDeflationSiacoins.Mul(NewCurrency64(uint64(height + 1)))
return deflationSiacoins
}
deflationSiacoins := avgDeflationSiacoins.Mul(NewCurrency64(uint64(deflationBlocks + 1)))
trailingSiacoins := NewCurrency64(uint64(height - deflationBlocks)).Mul(CalculateCoinbase(height))
return deflationSiacoins.Add(trailingSiacoins)
}
// CalculateSubsidy takes a block and a height and determines the block
// subsidy.
func (b Block) CalculateSubsidy(height BlockHeight) Currency {
......@@ -146,7 +160,7 @@ func (bid *BlockID) UnmarshalJSON(b []byte) error {
var bidBytes []byte
_, err := fmt.Sscanf(string(b[1:len(b)-1]), "%x", &bidBytes)
if err != nil {
return errors.New("could not unmarshal types.BlockID: " + err.Error())
return errors.New("could not unmarshal BlockID: " + err.Error())
}
copy(bid[:], bidBytes)
return nil
......
......@@ -35,6 +35,27 @@ func TestCalculateCoinbase(t *testing.T) {
}
}
// TestCalculateNumSiacoins checks that the siacoin calculator is correctly
// determining the number of siacoins in circulation. The check is performed by
// doing a naive computation, instead of by doing the optimized computation.
func TestCalculateNumSiacoins(t *testing.T) {
c := CalculateNumSiacoins(0)
if c.Cmp(CalculateCoinbase(0)) != 0 {
t.Error("unexpected circulation result for value 0, got", c)
}
if testing.Short() {
t.SkipNow()
}
totalCoins := NewCurrency64(0)
for i := BlockHeight(0); i < 500e3; i++ {
totalCoins = totalCoins.Add(CalculateCoinbase(i))
if totalCoins.Cmp(CalculateNumSiacoins(i)) != 0 {
t.Fatal("coin miscalculation", i, totalCoins, CalculateNumSiacoins(i))
}
}
}
// TestBlockHeader checks that BlockHeader returns the correct value, and that
// the hash is consistent with the old method for obtaining the hash.
func TestBlockHeader(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment