Skip to content

Commit

Permalink
Merge pull request #118 from 0chain/initialState
Browse files Browse the repository at this point in the history
Initial state
  • Loading branch information
peterlimg committed Mar 18, 2021
2 parents 5b337c2 + 87bbd88 commit cbb43d0
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 17 deletions.
19 changes: 8 additions & 11 deletions code/go/0chain.net/chaincore/chain/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,33 +505,30 @@ func (c *Chain) GetConfigInfoStore() datastore.Store {
return c.configInfoStore
}

func (c *Chain) getInitialState() util.Serializable {
tokens := viper.GetInt64("server_chain.tokens")
func (c *Chain) getInitialState(tokens state.Balance) util.Serializable {
balance := &state.State{}
balance.SetTxnHash("0000000000000000000000000000000000000000000000000000000000000000")
var cents int64 = 1
for i := int8(0); i < c.Decimals; i++ {
cents *= 10
}
balance.Balance = state.Balance(tokens * cents)
balance.Balance = state.Balance(tokens)
return balance
}

/*setupInitialState - setup the initial state based on configuration */
func (c *Chain) setupInitialState() util.MerklePatriciaTrieI {
func (c *Chain) setupInitialState(initStates *state.InitStates) util.MerklePatriciaTrieI {
pmt := util.NewMerklePatriciaTrie(c.stateDB, util.Sequence(0))
pmt.Insert(util.Path(c.OwnerID), c.getInitialState())
for _, v := range initStates.States {
pmt.Insert(util.Path(v.ID), c.getInitialState(v.Tokens))
}
pmt.SaveChanges(c.stateDB, false)
Logger.Info("initial state root", zap.Any("hash", util.ToHex(pmt.GetRoot())))
return pmt
}

/*GenerateGenesisBlock - Create the genesis block for the chain */
func (c *Chain) GenerateGenesisBlock(hash string, genesisMagicBlock *block.MagicBlock) (round.RoundI, *block.Block) {
func (c *Chain) GenerateGenesisBlock(hash string, genesisMagicBlock *block.MagicBlock, initStates *state.InitStates) (round.RoundI, *block.Block) {
c.GenesisBlockHash = hash
gb := block.NewBlock(c.GetKey(), 0)
gb.Hash = hash
gb.ClientState = c.setupInitialState()
gb.ClientState = c.setupInitialState(initStates)
gb.SetStateStatus(block.StateSuccessful)
gb.SetBlockState(block.StateNotarized)
gb.ClientStateHash = gb.ClientState.GetRoot()
Expand Down
34 changes: 34 additions & 0 deletions code/go/0chain.net/chaincore/state/initial_state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package state

import (
"0chain.net/core/datastore"

"gopkg.in/yaml.v2"
"io/ioutil"
)

// InitStates is a slice of InitState used for all the initial states in the genesis block.
type InitStates struct {
States []InitState `yaml:"initialStates"`
}

// InitState is a clients initial state in the genesis block.
type InitState struct {
ID datastore.Key `yaml:"id"`
Tokens Balance `yaml:"tokens"`
}

// NewInitStates is used to return a new InitStates.
func NewInitStates() *InitStates {
return &InitStates{}
}

// Read is use on the InitStates to read the initial states for the genesis block from a yaml file.
func (initStates *InitStates) Read(file string) (err error) {
bytes, err := ioutil.ReadFile(file)
if err != nil {
return
}
err = yaml.Unmarshal(bytes, initStates)
return
}
5 changes: 3 additions & 2 deletions code/go/0chain.net/miner/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"0chain.net/chaincore/client"
"0chain.net/chaincore/node"
"0chain.net/chaincore/round"
"0chain.net/chaincore/state"
"0chain.net/chaincore/threshold/bls"
"0chain.net/core/common"
"0chain.net/core/datastore"
Expand Down Expand Up @@ -171,8 +172,8 @@ func (mc *Chain) GetBlockMessageChannel() chan *BlockMessage {
}

// SetupGenesisBlock - setup the genesis block for this chain.
func (mc *Chain) SetupGenesisBlock(hash string, magicBlock *block.MagicBlock) *block.Block {
gr, gb := mc.GenerateGenesisBlock(hash, magicBlock)
func (mc *Chain) SetupGenesisBlock(hash string, magicBlock *block.MagicBlock, initStates *state.InitStates) *block.Block {
gr, gb := mc.GenerateGenesisBlock(hash, magicBlock, initStates)
if gr == nil || gb == nil {
panic("Genesis round/block can't be null")
}
Expand Down
13 changes: 12 additions & 1 deletion code/go/0chain.net/miner/miner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func main() {
keysFile := flag.String("keys_file", "", "keys_file")
delayFile := flag.String("delay_file", "", "delay_file")
magicBlockFile := flag.String("magic_block_file", "", "magic_block_file")
initialStatesFile := flag.String("initial_states", "", "initial_states")
flag.Parse()
config.Configuration.DeploymentMode = byte(*deploymentMode)
config.SetupDefaultConfig()
Expand Down Expand Up @@ -95,6 +96,16 @@ func main() {
miner.SetNetworkRelayTime(viper.GetDuration("network.relay_time") * time.Millisecond)
node.ReadConfig()

if *initialStatesFile == "" {
*initialStatesFile = viper.GetString("network.initial_states")
}

initStates := state.NewInitStates()
err = initStates.Read(*initialStatesFile)
if err != nil {
Logger.Panic("Failed to read initialStates", zap.Any("Error", err))
}

// if there's no magic_block_file commandline flag, use configured then
if *magicBlockFile == "" {
*magicBlockFile = viper.GetString("network.magic_block_file")
Expand All @@ -120,7 +131,7 @@ func main() {
chain.SetupStateLogger("/tmp/state.txt")
}
gb := mc.SetupGenesisBlock(viper.GetString("server_chain.genesis_block.id"),
magicBlock)
magicBlock, initStates)
mb := mc.GetLatestMagicBlock()
Logger.Info("Miners in main", zap.Int("size", mb.Miners.Size()))

Expand Down
5 changes: 3 additions & 2 deletions code/go/0chain.net/sharder/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"0chain.net/chaincore/block"
"0chain.net/chaincore/chain"
"0chain.net/chaincore/round"
"0chain.net/chaincore/state"
"0chain.net/core/common"
"0chain.net/core/datastore"
"0chain.net/sharder/blockstore"
Expand Down Expand Up @@ -74,8 +75,8 @@ func (sc *Chain) GetRoundChannel() chan *round.Round {
}

/*SetupGenesisBlock - setup the genesis block for this chain */
func (sc *Chain) SetupGenesisBlock(hash string, magicBlock *block.MagicBlock) *block.Block {
gr, gb := sc.GenerateGenesisBlock(hash, magicBlock)
func (sc *Chain) SetupGenesisBlock(hash string, magicBlock *block.MagicBlock, initStates *state.InitStates) *block.Block {
gr, gb := sc.GenerateGenesisBlock(hash, magicBlock, initStates)
if gr == nil || gb == nil {
panic("Genesis round/block can not be null")
}
Expand Down
13 changes: 12 additions & 1 deletion code/go/0chain.net/sharder/sharder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func main() {
keysFile := flag.String("keys_file", "", "keys_file")
magicBlockFile := flag.String("magic_block_file", "", "magic_block_file")
minioFile := flag.String("minio_file", "", "minio_file")
initialStatesFile := flag.String("initial_states", "", "initial_states")
flag.String("nodes_file", "", "nodes_file (deprecated)")
flag.Parse()
config.Configuration.DeploymentMode = byte(*deploymentMode)
Expand Down Expand Up @@ -142,6 +143,16 @@ func main() {
chain.SetNetworkRelayTime(viper.GetDuration("network.relay_time") * time.Millisecond)
node.ReadConfig()

if *initialStatesFile == "" {
*initialStatesFile = viper.GetString("network.initial_states")
}

initStates := state.NewInitStates()
err = initStates.Read(*initialStatesFile)
if err != nil {
Logger.Panic("Failed to read initialStates", zap.Any("Error", err))
}

// if there's no magic_block_file commandline flag, use configured then
if *magicBlockFile == "" {
*magicBlockFile = viper.GetString("network.magic_block_file")
Expand Down Expand Up @@ -169,7 +180,7 @@ func main() {

setupBlockStorageProvider(mConf)
sc.SetupGenesisBlock(viper.GetString("server_chain.genesis_block.id"),
magicBlock)
magicBlock, initStates)
Logger.Info("sharder node", zap.Any("node", node.Self))

var selfNode = node.Self.Underlying()
Expand Down
1 change: 1 addition & 0 deletions docker.local/config/0chain.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ server_chain:

network:
magic_block_file: config/b0magicBlock_4_miners_1_sharder.json
initial_states: config/initial_state.yaml
dns_url: '' # http://198.18.0.98:9091
relay_time: 200 # milliseconds
max_concurrent_requests: 40
Expand Down
15 changes: 15 additions & 0 deletions docker.local/config/initial_state.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
initialStates:
- id: 31810bd1258ae95955fb40c7ef72498a556d3587121376d9059119d280f34929
tokens: 10000000000

- id: 585732eb076d07455fbebcf3388856b6fd00449a25c47c0f72d961c7c4e7e7c2
tokens: 10000000000

- id: 8877e3da19b4cb51e59b4646ec7c0cf4849bc7b860257d69ddbf753b9a981e1b
tokens: 10000000000

- id: bfa64c67f49bceec8be618b1b6f558bdbaf9c100fd95d55601fa2190a4e548d8
tokens: 10000000000

- id: 57b416fcda1cf82b8a7e1fc3a47c68a94e617be873b5383ea2606bda757d3ce4
tokens: 10000000000

0 comments on commit cbb43d0

Please sign in to comment.