Commit 32ffcd76 authored by geo-gs's avatar geo-gs Committed by David Vorick

Add Genesis Siacoin Allocation

The Sia blockchain does not set a genesis siacoin allocation.
However, having the constants in place to support a genesis siacoin
allocation would make it easier for genesis forks of Sia to set up
an airdrop. It would also simplify documentation on how to execute
an airdrop when starting a genesis fork of Sia.

Additionally, the Genesis block should not be limited to having all
Siacoin and Siafund outputs in the same transaction. Doing so causes
confusion as there is no limitation in the types.constants.go file
but there is elsewhere in the code. The end result is that without
this change there is an undocumented constraint on how the Genesis
block should be structured.
parent edf75b7e
......@@ -111,6 +111,13 @@ func (cs *ConsensusSet) createConsensusDB(tx *bolt.Tx) error {
return err
}
// Update the siacoin output diffs map for the genesis block on disk. This
// needs to happen between the database being opened/initilized and the
// consensus set hash being calculated
for _, scod := range cs.blockRoot.SiacoinOutputDiffs {
commitSiacoinOutputDiff(tx, scod, modules.DiffApply)
}
// Set the siafund pool to 0.
setSiafundPool(tx, types.NewCurrency64(0))
......
......@@ -133,15 +133,28 @@ func NewCustomConsensusSet(gateway modules.Gateway, bootstrap bool, persistDir s
persistDir: persistDir,
}
// Create the diffs for the genesis siafund outputs.
for i, siafundOutput := range types.GenesisBlock.Transactions[0].SiafundOutputs {
sfid := types.GenesisBlock.Transactions[0].SiafundOutputID(uint64(i))
sfod := modules.SiafundOutputDiff{
Direction: modules.DiffApply,
ID: sfid,
SiafundOutput: siafundOutput,
// Create the diffs for the genesis transaction outputs
for _, transaction := range types.GenesisBlock.Transactions {
// Create the diffs for the genesis siacoin outputs.
for i, siacoinOutput := range transaction.SiacoinOutputs {
scid := transaction.SiacoinOutputID(uint64(i))
scod := modules.SiacoinOutputDiff{
Direction: modules.DiffApply,
ID: scid,
SiacoinOutput: siacoinOutput,
}
cs.blockRoot.SiacoinOutputDiffs = append(cs.blockRoot.SiacoinOutputDiffs, scod)
}
// Create the diffs for the genesis siafund outputs.
for i, siafundOutput := range transaction.SiafundOutputs {
sfid := transaction.SiafundOutputID(uint64(i))
sfod := modules.SiafundOutputDiff{
Direction: modules.DiffApply,
ID: sfid,
SiafundOutput: siafundOutput,
}
cs.blockRoot.SiafundOutputDiffs = append(cs.blockRoot.SiafundOutputDiffs, sfod)
}
cs.blockRoot.SiafundOutputDiffs = append(cs.blockRoot.SiafundOutputDiffs, sfod)
}
// Initialize the consensus persistence structures.
......
......@@ -528,14 +528,29 @@ func dbCalculateBlockFacts(tx *bolt.Tx, cs modules.ConsensusSet, block types.Blo
func dbAddGenesisBlock(tx *bolt.Tx) {
id := types.GenesisID
dbAddBlockID(tx, id, 0)
txid := types.GenesisBlock.Transactions[0].ID()
dbAddTransactionID(tx, txid, 0)
for i, sfo := range types.GenesisSiafundAllocation {
sfoid := types.GenesisBlock.Transactions[0].SiafundOutputID(uint64(i))
dbAddSiafundOutputID(tx, sfoid, txid)
dbAddUnlockHash(tx, sfo.UnlockHash, txid)
dbAddSiafundOutput(tx, sfoid, sfo)
// Add Genesis transactions to database
for _, transaction := range types.GenesisBlock.Transactions {
// Add Genesis Transaction to database
txid := transaction.ID()
dbAddTransactionID(tx, txid, 0)
// Add Genesis Siacoin outputs to database
for i, sco := range transaction.SiacoinOutputs {
scoid := transaction.SiacoinOutputID(uint64(i))
dbAddSiacoinOutputID(tx, scoid, txid)
dbAddUnlockHash(tx, sco.UnlockHash, txid)
dbAddSiacoinOutput(tx, scoid, sco)
}
// Add Geesis Siafund outputs to database
for i, sfo := range transaction.SiafundOutputs {
sfoid := transaction.SiafundOutputID(uint64(i))
dbAddSiafundOutputID(tx, sfoid, txid)
dbAddUnlockHash(tx, sfo.UnlockHash, txid)
dbAddSiafundOutput(tx, sfoid, sfo)
}
}
dbAddBlockFacts(tx, blockFacts{
BlockFacts: modules.BlockFacts{
BlockID: id,
......@@ -543,7 +558,8 @@ func dbAddGenesisBlock(tx *bolt.Tx) {
Difficulty: types.RootTarget.Difficulty(),
Target: types.RootTarget,
TotalCoins: types.CalculateCoinbase(0),
TransactionCount: 1,
TransactionCount: uint64(len(types.GenesisBlock.Transactions)),
SiacoinOutputCount: uint64(len(types.GenesisSiacoinAllocation)),
SiafundOutputCount: uint64(len(types.GenesisSiafundAllocation)),
},
Timestamp: types.GenesisBlock.Timestamp,
......
......@@ -71,13 +71,24 @@ func CalculateNumSiacoins(height BlockHeight) Currency {
avgDeflationSiacoins := CalculateCoinbase(0).Add(CalculateCoinbase(height)).Div(NewCurrency64(2))
if height <= deflationBlocks {
deflationSiacoins := avgDeflationSiacoins.Mul(NewCurrency64(uint64(height + 1)))
return deflationSiacoins
return numGenesisSiacoins.Add(deflationSiacoins)
}
deflationSiacoins := avgDeflationSiacoins.Mul(NewCurrency64(uint64(deflationBlocks + 1)))
trailingSiacoins := NewCurrency64(uint64(height - deflationBlocks)).Mul(CalculateCoinbase(height))
return deflationSiacoins.Add(trailingSiacoins)
return numGenesisSiacoins.Add(deflationSiacoins).Add(trailingSiacoins)
}
var numGenesisSiacoins = func() Currency {
// Sum all the values for the genesis siacoin outputs.
numGenesisSiacoins := NewCurrency64(0)
for _, transaction := range GenesisBlock.Transactions {
for _, siacoinOutput := range transaction.SiacoinOutputs {
numGenesisSiacoins = numGenesisSiacoins.Add(siacoinOutput.Value)
}
}
return numGenesisSiacoins
}()
// ID returns the ID of a Block, which is calculated by hashing the header.
func (h BlockHeader) ID() BlockID {
return BlockID(crypto.HashObject(h))
......
......@@ -40,7 +40,7 @@ func TestCalculateCoinbase(t *testing.T) {
// 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 {
if !c.Equals(CalculateCoinbase(0).Add(numGenesisSiacoins)) {
t.Error("unexpected circulation result for value 0, got", c)
}
......
......@@ -79,6 +79,9 @@ var (
// redundant computation.
GenesisID BlockID
// GenesisSiacoinAllocation is the set of SiacoinOutputs created in the Genesis
// block
GenesisSiacoinAllocation []SiacoinOutput
// GenesisSiafundAllocation is the set of SiafundOutputs created in the Genesis
// block.
GenesisSiafundAllocation []SiafundOutput
......@@ -207,6 +210,14 @@ func init() {
OakMaxRise = big.NewRat(102, 100)
OakMaxDrop = big.NewRat(100, 102)
// Populate the void address with 1 billion siacoins in the genesis block.
GenesisSiacoinAllocation = []SiacoinOutput{
{
Value: NewCurrency64(1000000000).Mul(SiacoinPrecision),
UnlockHash: UnlockHash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
GenesisSiafundAllocation = []SiafundOutput{
{
Value: NewCurrency64(2000),
......@@ -255,6 +266,14 @@ func init() {
OakMaxRise = big.NewRat(10001, 10e3)
OakMaxDrop = big.NewRat(10e3, 10001)
// Populate the void address with 1 billion siacoins in the genesis block.
GenesisSiacoinAllocation = []SiacoinOutput{
{
Value: NewCurrency64(1000000000).Mul(SiacoinPrecision),
UnlockHash: UnlockHash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
GenesisSiafundAllocation = []SiafundOutput{
{
Value: NewCurrency64(2000),
......@@ -379,6 +398,8 @@ func init() {
OakMaxRise = big.NewRat(1004, 1e3)
OakMaxDrop = big.NewRat(1e3, 1004)
GenesisSiacoinAllocation = []SiacoinOutput{}
GenesisSiafundAllocation = []SiafundOutput{
{
Value: NewCurrency64(2),
......
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