put StakeInfo into the calcualtion of shard state

pull/556/head
Rongjian Lan 6 years ago
parent c54e225dc4
commit 02de04dc39
  1. 24
      contracts/structs/structs.go
  2. 18
      core/blockchain.go
  3. 23
      core/resharding.go
  4. 1
      core/resharding_test.go
  5. 6
      node/contract.go
  6. 6
      node/node.go
  7. 3
      node/node_handler.go
  8. 2
      node/node_newblock.go
  9. 25
      node/staking.go
  10. 4
      node/staking_test.go

@ -0,0 +1,24 @@
package structs
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
)
// StakeInfoReturnValue is the struct for the return value of listLockedAddresses func in stake contract.
type StakeInfoReturnValue struct {
LockedAddresses []common.Address
BlsAddresses [][20]byte
BlockNums []*big.Int
LockPeriodCounts []*big.Int // The number of locking period the token will be locked.
Amounts []*big.Int
}
// StakeInfo stores the staking information for a staker.
type StakeInfo struct {
BlsAddress [20]byte
BlockNum *big.Int
LockPeriodCount *big.Int // The number of locking period the token will be locked.
Amount *big.Int
}

@ -27,6 +27,9 @@ import (
"sync/atomic"
"time"
"github.com/harmony-one/harmony/contracts/structs"
lru "github.com/hashicorp/golang-lru"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/common/prque"
@ -44,7 +47,6 @@ import (
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/internal/utils"
lru "github.com/hashicorp/golang-lru"
)
var (
@ -1254,10 +1256,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
cache, _ := bc.stateCache.TrieDB().Size()
stats.report(chain, i, cache)
// only insert new shardstate when block is epoch block
// TODO(minhdoan): this is only for beaconc chain
bc.InsertNewShardState(block)
}
// Append a single chain head event if we've progressed the chain
if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
@ -1705,7 +1703,7 @@ func (bc *BlockChain) GetRandPreimageByNumber(number uint64) [32]byte {
// GetNewShardState will calculate (if not exist) and get the new shard state for epoch block or nil if block is not epoch block
// epoch block is where the new shard state stored
func (bc *BlockChain) GetNewShardState(block *types.Block) types.ShardState {
func (bc *BlockChain) GetNewShardState(block *types.Block, stakeInfo *map[common.Address]*structs.StakeInfo) types.ShardState {
hash := block.Hash()
// just ignore non-epoch block
if !IsEpochBlock(block) {
@ -1722,8 +1720,8 @@ func (bc *BlockChain) GetNewShardState(block *types.Block) types.ShardState {
}
// ValidateNewShardState validate whether the new shard state root matches
func (bc *BlockChain) ValidateNewShardState(block *types.Block) error {
shardState := bc.GetNewShardState(block)
func (bc *BlockChain) ValidateNewShardState(block *types.Block, stakeInfo *map[common.Address]*structs.StakeInfo) error {
shardState := bc.GetNewShardState(block, stakeInfo)
if shardState == nil {
return nil
}
@ -1735,9 +1733,9 @@ func (bc *BlockChain) ValidateNewShardState(block *types.Block) error {
}
// InsertNewShardState insert new shard state into epoch block
func (bc *BlockChain) InsertNewShardState(block *types.Block) {
func (bc *BlockChain) InsertNewShardState(block *types.Block, stakeInfo *map[common.Address]*structs.StakeInfo) {
// write state into db.
shardState := bc.GetNewShardState(block)
shardState := bc.GetNewShardState(block, stakeInfo)
if shardState == nil {
return
}

@ -142,6 +142,17 @@ func CalculateNewShardState(bc *BlockChain, epoch uint64) types.ShardState {
return ss.shardState
}
func fakeNewNodeList(seed int64) []types.NodeID {
rand.Seed(seed)
numNewNodes := rand.Intn(10)
nodeList := []types.NodeID{}
for i := 0; i < numNewNodes; i++ {
nid := strconv.Itoa(int(rand.Int63()))
nodeList = append(nodeList, types.NodeID(nid))
}
return nodeList
}
// calculateKickoutRate calculates the cuckoo rule kick out rate in order to make committee balanced
func (ss *ShardingState) calculateKickoutRate(newNodeList []types.NodeID) float64 {
numActiveCommittees := ss.numShards / 2
@ -173,15 +184,3 @@ func getInitShardState(numberOfShards, numNodesPerShard int) types.ShardState {
}
return shardState
}
// remove later after new nodes list generation ready
func fakeNewNodeList(seed int64) []types.NodeID {
rand.Seed(seed)
numNewNodes := rand.Intn(10)
nodeList := []types.NodeID{}
for i := 0; i < numNewNodes; i++ {
nid := strconv.Itoa(int(rand.Int63()))
nodeList = append(nodeList, types.NodeID(nid))
}
return nodeList
}

@ -10,7 +10,6 @@ import (
"github.com/stretchr/testify/assert"
)
// remove later after bootstrap codes ready
func fakeGetInitShardState(numberOfShards, numOfNodes int) types.ShardState {
rand.Seed(int64(InitialSeed))
shardState := types.ShardState{}

@ -4,6 +4,8 @@ import (
"math/big"
"strings"
"github.com/harmony-one/harmony/contracts/structs"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common/math"
@ -59,7 +61,7 @@ func (node *Node) generateDeployedStakingContractAddress(contractAddress common.
}
// QueryStakeInfo queries the stake info from the stake contract.
func (node *Node) QueryStakeInfo() *StakeInfoReturnValue {
func (node *Node) QueryStakeInfo() *structs.StakeInfoReturnValue {
abi, err := abi.JSON(strings.NewReader(contracts.StakeLockContractABI))
if err != nil {
utils.GetLogInstance().Error("Failed to generate staking contract's ABI", "error", err)
@ -96,7 +98,7 @@ func (node *Node) QueryStakeInfo() *StakeInfoReturnValue {
return nil
}
ret := &StakeInfoReturnValue{}
ret := &structs.StakeInfoReturnValue{}
err = abi.Unpack(ret, "listLockedAddresses", output)

@ -9,6 +9,8 @@ import (
"sync"
"time"
"github.com/harmony-one/harmony/contracts/structs"
"github.com/harmony-one/harmony/contracts"
"github.com/ethereum/go-ethereum/common"
@ -137,7 +139,7 @@ type Node struct {
serviceManager *service.Manager
//Staked Accounts and Contract
CurrentStakes map[common.Address]*StakeInfo //This will save the latest information about staked nodes.
CurrentStakes map[common.Address]*structs.StakeInfo //This will save the latest information about staked nodes.
StakingContractAddress common.Address
WithdrawStakeFunc []byte
@ -251,7 +253,7 @@ func New(host p2p.Host, consensusObj *consensus.Consensus, db ethdb.Database) *N
// Setup one time smart contracts
node.AddFaucetContractToPendingTransactions()
node.CurrentStakes = make(map[common.Address]*StakeInfo)
node.CurrentStakes = make(map[common.Address]*structs.StakeInfo)
node.AddStakingContractToPendingTransactions() //This will save the latest information about staked nodes in current staked
}

@ -262,7 +262,7 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) bool {
// TODO: verify the vrf randomness
_ = newBlock.Header().RandPreimage
err = node.blockchain.ValidateNewShardState(newBlock)
err = node.blockchain.ValidateNewShardState(newBlock, &node.CurrentStakes)
if err != nil {
utils.GetLogInstance().Debug("Failed to verify new sharding state", "err", err)
}
@ -298,6 +298,7 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block) {
func (node *Node) AddNewBlock(newBlock *types.Block) {
blockNum, err := node.blockchain.InsertChain([]*types.Block{newBlock})
node.blockchain.InsertNewShardState(newBlock, &node.CurrentStakes)
if err != nil {
utils.GetLogInstance().Debug("Error adding new block to blockchain", "blockNum", blockNum, "Error", err)
} else {

@ -79,7 +79,7 @@ func (node *Node) WaitForConsensusReady(readySignal chan struct{}, stopChan chan
}
func (node *Node) addNewShardState(block *types.Block) {
shardState := node.blockchain.GetNewShardState(block)
shardState := node.blockchain.GetNewShardState(block, &node.CurrentStakes)
if shardState != nil {
shardHash := shardState.Hash()
utils.GetLogInstance().Debug("[resharding] adding new shard state", "shardHash", shardHash)

@ -5,6 +5,8 @@ import (
"math/big"
"os"
"github.com/harmony-one/harmony/contracts/structs"
"github.com/harmony-one/harmony/core"
"github.com/ethereum/go-ethereum/common"
@ -24,26 +26,9 @@ const (
lockPeriodInEpochs = 3 // This should be in sync with contracts/StakeLockContract.sol
)
// StakeInfoReturnValue is the struct for the return value of listLockedAddresses func in stake contract.
type StakeInfoReturnValue struct {
LockedAddresses []common.Address
BlsAddresses [][20]byte
BlockNums []*big.Int
LockPeriodCounts []*big.Int // The number of locking period the token will be locked.
Amounts []*big.Int
}
// StakeInfo stores the staking information for a staker.
type StakeInfo struct {
BlsAddress [20]byte
BlockNum *big.Int
LockPeriodCount *big.Int // The number of locking period the token will be locked.
Amount *big.Int
}
// UpdateStakingList updates staking information by querying the staking smart contract.
func (node *Node) UpdateStakingList(stakeInfoReturnValue *StakeInfoReturnValue) {
node.CurrentStakes = make(map[common.Address]*StakeInfo)
func (node *Node) UpdateStakingList(stakeInfoReturnValue *structs.StakeInfoReturnValue) {
node.CurrentStakes = make(map[common.Address]*structs.StakeInfo)
if stakeInfoReturnValue != nil {
for i, addr := range stakeInfoReturnValue.LockedAddresses {
blockNum := stakeInfoReturnValue.BlockNums[i]
@ -56,7 +41,7 @@ func (node *Node) UpdateStakingList(stakeInfoReturnValue *StakeInfoReturnValue)
continue // The token are counted into stakes at the beginning of next epoch.
}
if curEpoch-startEpoch <= lockPeriodCount.Uint64()*lockPeriodInEpochs {
node.CurrentStakes[addr] = &StakeInfo{
node.CurrentStakes[addr] = &structs.StakeInfo{
stakeInfoReturnValue.BlsAddresses[i],
blockNum,
lockPeriodCount,

@ -4,6 +4,8 @@ import (
"math/big"
"testing"
"github.com/harmony-one/harmony/contracts/structs"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/consensus"
"github.com/harmony-one/harmony/internal/utils"
@ -40,7 +42,7 @@ func TestUpdateStakingList(t *testing.T) {
node.AddNewBlock(block)
}
stakeInfo := &StakeInfoReturnValue{
stakeInfo := &structs.StakeInfoReturnValue{
[]common.Address{testAddress},
[][20]byte{testAddress},
[]*big.Int{blockNum},

Loading…
Cancel
Save