Add shard state hash into genesis

pull/560/head
Rongjian Lan 6 years ago
parent a6a7609b57
commit f4748d7bcc
  1. 58
      core/gen_genesis.go
  2. 46
      core/genesis.go
  3. 21
      core/resharding.go
  4. 7
      node/node_genesis.go
  5. 4
      node/node_newblock.go

@ -18,19 +18,20 @@ var _ = (*genesisSpecMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (g Genesis) MarshalJSON() ([]byte, error) {
type Genesis struct {
Config *params.ChainConfig `json:"config"`
Nonce math.HexOrDecimal64 `json:"nonce"`
ShardID uint32 `json:"shardID"`
Timestamp math.HexOrDecimal64 `json:"timestamp"`
ExtraData hexutil.Bytes `json:"extraData"`
GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
Mixhash common.Hash `json:"mixHash"`
Coinbase common.Address `json:"coinbase"`
Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
Number math.HexOrDecimal64 `json:"number"`
GasUsed math.HexOrDecimal64 `json:"gasUsed"`
ParentHash common.Hash `json:"parentHash"`
Config *params.ChainConfig `json:"config"`
Nonce math.HexOrDecimal64 `json:"nonce"`
ShardID uint32 `json:"shardID"`
Timestamp math.HexOrDecimal64 `json:"timestamp"`
ExtraData hexutil.Bytes `json:"extraData"`
GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
Mixhash common.Hash `json:"mixHash"`
Coinbase common.Address `json:"coinbase"`
Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
ShardStateHash common.Hash `json:"shardStateHash"`
Number math.HexOrDecimal64 `json:"number"`
GasUsed math.HexOrDecimal64 `json:"gasUsed"`
ParentHash common.Hash `json:"parentHash"`
}
var enc Genesis
enc.Config = g.Config
@ -48,6 +49,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
enc.Alloc[common.UnprefixedAddress(k)] = v
}
}
enc.ShardStateHash = g.ShardStateHash
enc.Number = math.HexOrDecimal64(g.Number)
enc.GasUsed = math.HexOrDecimal64(g.GasUsed)
enc.ParentHash = g.ParentHash
@ -57,19 +59,20 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
// UnmarshalJSON unmarshals from JSON.
func (g *Genesis) UnmarshalJSON(input []byte) error {
type Genesis struct {
Config *params.ChainConfig `json:"config"`
Nonce *math.HexOrDecimal64 `json:"nonce"`
ShardID *uint32 `json:"shardID"`
Timestamp *math.HexOrDecimal64 `json:"timestamp"`
ExtraData *hexutil.Bytes `json:"extraData"`
GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
Mixhash *common.Hash `json:"mixHash"`
Coinbase *common.Address `json:"coinbase"`
Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
Number *math.HexOrDecimal64 `json:"number"`
GasUsed *math.HexOrDecimal64 `json:"gasUsed"`
ParentHash *common.Hash `json:"parentHash"`
Config *params.ChainConfig `json:"config"`
Nonce *math.HexOrDecimal64 `json:"nonce"`
ShardID *uint32 `json:"shardID"`
Timestamp *math.HexOrDecimal64 `json:"timestamp"`
ExtraData *hexutil.Bytes `json:"extraData"`
GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
Mixhash *common.Hash `json:"mixHash"`
Coinbase *common.Address `json:"coinbase"`
Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
ShardStateHash *common.Hash `json:"shardStateHash"`
Number *math.HexOrDecimal64 `json:"number"`
GasUsed *math.HexOrDecimal64 `json:"gasUsed"`
ParentHash *common.Hash `json:"parentHash"`
}
var dec Genesis
if err := json.Unmarshal(input, &dec); err != nil {
@ -111,6 +114,9 @@ func (g *Genesis) UnmarshalJSON(input []byte) error {
for k, v := range dec.Alloc {
g.Alloc[common.Address(k)] = v
}
if dec.ShardStateHash != nil {
g.ShardStateHash = *dec.ShardStateHash
}
if dec.Number != nil {
g.Number = uint64(*dec.Number)
}

@ -45,16 +45,17 @@ var errGenesisNoConfig = errors.New("genesis has no chain configuration")
// Genesis specifies the header fields, state of a genesis block. It also defines hard
// fork switch-over blocks through the chain configuration.
type Genesis struct {
Config *params.ChainConfig `json:"config"`
Nonce uint64 `json:"nonce"`
ShardID uint32 `json:"shardID"`
Timestamp uint64 `json:"timestamp"`
ExtraData []byte `json:"extraData"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
Difficulty *big.Int `json:"difficulty" gencodec:"required"`
Mixhash common.Hash `json:"mixHash"`
Coinbase common.Address `json:"coinbase"`
Alloc GenesisAlloc `json:"alloc" gencodec:"required"`
Config *params.ChainConfig `json:"config"`
Nonce uint64 `json:"nonce"`
ShardID uint32 `json:"shardID"`
Timestamp uint64 `json:"timestamp"`
ExtraData []byte `json:"extraData"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
Difficulty *big.Int `json:"difficulty" gencodec:"required"`
Mixhash common.Hash `json:"mixHash"`
Coinbase common.Address `json:"coinbase"`
Alloc GenesisAlloc `json:"alloc" gencodec:"required"`
ShardStateHash common.Hash `json:"shardStateHash"`
// These fields are used for consensus tests. Please don't use them
// in actual genesis blocks.
@ -237,18 +238,19 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
}
root := statedb.IntermediateRoot(false)
head := &types.Header{
Number: new(big.Int).SetUint64(g.Number),
Nonce: types.EncodeNonce(g.Nonce),
ShardID: types.EncodeShardID(g.ShardID),
Time: new(big.Int).SetUint64(g.Timestamp),
ParentHash: g.ParentHash,
Extra: g.ExtraData,
GasLimit: g.GasLimit,
GasUsed: g.GasUsed,
Difficulty: g.Difficulty,
MixDigest: g.Mixhash,
Coinbase: g.Coinbase,
Root: root,
Number: new(big.Int).SetUint64(g.Number),
Nonce: types.EncodeNonce(g.Nonce),
ShardID: types.EncodeShardID(g.ShardID),
Time: new(big.Int).SetUint64(g.Timestamp),
ParentHash: g.ParentHash,
Extra: g.ExtraData,
GasLimit: g.GasLimit,
GasUsed: g.GasUsed,
Difficulty: g.Difficulty,
MixDigest: g.Mixhash,
Coinbase: g.Coinbase,
Root: root,
ShardStateHash: g.ShardStateHash,
}
if g.GasLimit == 0 {
head.GasLimit = 10000000000 // TODO(RJ): figure out better solution. // params.GenesisGasLimit

@ -19,9 +19,12 @@ import (
const (
// InitialSeed is the initial random seed, a magic number to answer everything, remove later
InitialSeed uint32 = 42
// FirstEpoch is the number of the first epoch.
// TODO(minhdoan): we should design the first epoch as 0. Please figure out how to change other logic to make it 0
FirstEpoch = 1
// GenesisEpoch is the number of the first genesis epoch.
GenesisEpoch = 0
// GenesisShardNum is the number of shard at genesis
GenesisShardNum = 3
// GenesisShardSize is the size of each shard at genesis
GenesisShardSize = 10
)
// ShardingState is data structure hold the sharding state
@ -134,8 +137,8 @@ func GetShardingStateFromBlockChain(bc *BlockChain, epoch uint64) *ShardingState
// CalculateNewShardState get sharding state from previous epoch and calculate sharding state for new epoch
// TODO: currently, we just mock everything
func CalculateNewShardState(bc *BlockChain, epoch uint64, stakeInfo *map[common.Address]*structs.StakeInfo) types.ShardState {
if epoch == FirstEpoch {
return getInitShardState(3, 10)
if epoch == GenesisEpoch {
return GetInitShardState()
}
ss := GetShardingStateFromBlockChain(bc, epoch-1)
newNodeList := ss.UpdateShardingState(stakeInfo)
@ -190,13 +193,13 @@ func (ss *ShardingState) calculateKickoutRate(newNodeList []types.NodeID) float6
return math.Max(0.1, math.Min(rate, 1.0))
}
// getInitShardState returns the initial shard state at genesis.
func getInitShardState(numberOfShards, numNodesPerShard int) types.ShardState {
// GetInitShardState returns the initial shard state at genesis.
func GetInitShardState() types.ShardState {
shardState := types.ShardState{}
for i := 0; i < numberOfShards; i++ {
for i := 0; i < GenesisShardNum; i++ {
com := types.Committee{ShardID: uint32(i)}
if i == 0 {
for j := 0; j < numNodesPerShard; j++ {
for j := 0; j < GenesisShardSize; j++ {
priKey := bls.SecretKey{}
priKey.SetHexString(contract.InitialBeaconChainAccounts[i].Private)
addrBytes := priKey.GetPublicKey().GetAddress()

@ -43,9 +43,10 @@ func (node *Node) GenesisBlockSetup(db ethdb.Database) (*core.BlockChain, error)
chainConfig := params.TestChainConfig
chainConfig.ChainID = big.NewInt(int64(node.Consensus.ShardID)) // Use ChainID as piggybacked ShardID
gspec := core.Genesis{
Config: chainConfig,
Alloc: genesisAlloc,
ShardID: uint32(node.Consensus.ShardID),
Config: chainConfig,
Alloc: genesisAlloc,
ShardID: uint32(node.Consensus.ShardID),
ShardStateHash: core.GetInitShardState().Hash(),
}
// Store genesis block into db.

@ -60,7 +60,7 @@ func (node *Node) WaitForConsensusReady(readySignal chan struct{}, stopChan chan
} else {
// add new shard state if it's epoch block
// TODO(minhdoan): only happens for beaconchain
node.addNewShardState(block)
node.addNewShardStateHash(block)
newBlock = block
break
}
@ -78,7 +78,7 @@ func (node *Node) WaitForConsensusReady(readySignal chan struct{}, stopChan chan
}()
}
func (node *Node) addNewShardState(block *types.Block) {
func (node *Node) addNewShardStateHash(block *types.Block) {
shardState := node.blockchain.GetNewShardState(block, &node.CurrentStakes)
if shardState != nil {
shardHash := shardState.Hash()

Loading…
Cancel
Save