Merge pull request #1866 from rlan35/staking_tx

Fix potential lastmileblocks crash; Remove validator.Stake; refactor Compute;
pull/1871/head
Rongjian Lan 5 years ago committed by GitHub
commit c0e99c633c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      api/proto/node/node.go
  2. 8
      api/service/syncing/syncing.go
  3. 16
      consensus/quorum/one-node-staked-vote.go
  4. 23
      core/blockchain.go
  5. 13
      hmy/api_backend.go
  6. 6
      internal/chain/engine.go
  7. 2
      internal/hmyapi/backend.go
  8. 25
      internal/hmyapi/blockchain.go
  9. 2
      internal/hmyapi/types.go
  10. 2
      internal/params/config.go
  11. 2
      node/node_genesis.go
  12. 11
      node/node_handler.go
  13. 179
      node/node_resharding.go
  14. 8
      node/node_syncing.go
  15. 48
      node/worker/worker.go
  16. 20
      shard/committee/assignment.go
  17. 11
      staking/types/validator.go
  18. 2
      staking/types/validator_test.go

@ -14,7 +14,6 @@ import (
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard"
) )
// MessageType is to indicate the specific type of message under Node category // MessageType is to indicate the specific type of message under Node category
@ -25,9 +24,9 @@ const (
Transaction MessageType = iota Transaction MessageType = iota
Block Block
Client Client
_ // used to be Control _ // used to be Control
PING // node send ip/pki to register with leader PING // node send ip/pki to register with leader
ShardState ShardState // Deprecated
Staking Staking
) )
@ -160,36 +159,6 @@ func ConstructCrossLinkHeadersMessage(headers []*block.Header) []byte {
return byteBuffer.Bytes() return byteBuffer.Bytes()
} }
// ConstructEpochShardStateMessage contructs epoch shard state message
func ConstructEpochShardStateMessage(epochShardState shard.EpochShardState) []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(proto.Node)})
byteBuffer.WriteByte(byte(ShardState))
encoder := gob.NewEncoder(byteBuffer)
err := encoder.Encode(epochShardState)
if err != nil {
utils.Logger().Error().Err(err).Msg("[ConstructEpochShardStateMessage] Encode")
return nil
}
return byteBuffer.Bytes()
}
// DeserializeEpochShardStateFromMessage deserializes the shard state Message from bytes payload
func DeserializeEpochShardStateFromMessage(payload []byte) (*shard.EpochShardState, error) {
epochShardState := new(shard.EpochShardState)
r := bytes.NewBuffer(payload)
decoder := gob.NewDecoder(r)
err := decoder.Decode(epochShardState)
if err != nil {
utils.Logger().Error().Err(err).Msg("[GetEpochShardStateFromMessage] Decode")
return nil, fmt.Errorf("Decode epoch shard state Error")
}
return epochShardState, nil
}
// ConstructCXReceiptsProof constructs cross shard receipts and related proof including // ConstructCXReceiptsProof constructs cross shard receipts and related proof including
// merkle proof, blockHeader and commitSignatures // merkle proof, blockHeader and commitSignatures
func ConstructCXReceiptsProof(cxs types.CXReceipts, mkp *types.CXMerkleProof, header *block.Header, commitSig []byte, commitBitmap []byte) []byte { func ConstructCXReceiptsProof(cxs types.CXReceipts, mkp *types.CXMerkleProof, header *block.Header, commitSig []byte, commitBitmap []byte) []byte {

@ -138,10 +138,12 @@ func (ss *StateSync) purgeOldBlocksFromCache() {
func (ss *StateSync) AddLastMileBlock(block *types.Block) { func (ss *StateSync) AddLastMileBlock(block *types.Block) {
ss.lastMileMux.Lock() ss.lastMileMux.Lock()
defer ss.lastMileMux.Unlock() defer ss.lastMileMux.Unlock()
if len(ss.lastMileBlocks) >= LastMileBlocksSize { if ss.lastMileBlocks != nil {
ss.lastMileBlocks = ss.lastMileBlocks[1:] if len(ss.lastMileBlocks) >= LastMileBlocksSize {
ss.lastMileBlocks = ss.lastMileBlocks[1:]
}
ss.lastMileBlocks = append(ss.lastMileBlocks, block)
} }
ss.lastMileBlocks = append(ss.lastMileBlocks, block)
} }
// CloseConnections close grpc connections for state sync clients // CloseConnections close grpc connections for state sync clients

@ -132,9 +132,9 @@ func (v *stakedVoteWeight) Award(
} }
var ( var (
errSumOfVotingPowerNotOne = errors.New("sum of total votes do not sum to 100%") errSumOfVotingPowerNotOne = errors.New("sum of total votes do not sum to 100 percent")
errSumOfOursAndTheirsNotOne = errors.New( errSumOfOursAndTheirsNotOne = errors.New(
"sum of hmy nodes and stakers do not sum to 100%", "sum of hmy nodes and stakers do not sum to 100 percent",
) )
) )
@ -191,12 +191,12 @@ func (v *stakedVoteWeight) SetVoters(
Str("Raw-Staked", v.stakedTotal.String()). Str("Raw-Staked", v.stakedTotal.String()).
Msg("Total staked") Msg("Total staked")
switch { //switch {
case totalStakedPercent.Equal(totalShare) == false: //case totalStakedPercent.Equal(totalShare) == false:
return nil, errSumOfVotingPowerNotOne // return nil, errSumOfVotingPowerNotOne
case ourPercentage.Add(theirPercentage).Equal(totalShare) == false: //case ourPercentage.Add(theirPercentage).Equal(totalShare) == false:
return nil, errSumOfOursAndTheirsNotOne // return nil, errSumOfOursAndTheirsNotOne
} //}
// Hold onto this calculation // Hold onto this calculation
v.ourVotingPowerTotal = ourPercentage v.ourVotingPowerTotal = ourPercentage

@ -1177,15 +1177,13 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
} }
// Do bookkeeping for new staking txns // Do bookkeeping for new staking txns
if bc.chainConfig.IsStaking(block.Epoch()) { for _, tx := range block.StakingTransactions() {
for _, tx := range block.StakingTransactions() { err = bc.UpdateStakingMetaData(tx, root)
err = bc.UpdateStakingMetaData(tx, root) // keep offchain database consistency with onchain we need revert
// keep offchain database consistency with onchain we need revert // but it should not happend unless local database corrupted
// but it should not happend unless local database corrupted if err != nil {
if err != nil { utils.Logger().Debug().Msgf("oops, UpdateStakingMetaData failed, err: %+v", err)
utils.Logger().Debug().Msgf("oops, UpdateStakingMetaData failed, err: %+v", err) return NonStatTy, err
return NonStatTy, err
}
} }
} }
@ -1973,7 +1971,7 @@ func (bc *BlockChain) GetShardState(epoch *big.Int) (shard.State, error) {
if epoch.Cmp(big.NewInt(GenesisEpoch)) == 0 { if epoch.Cmp(big.NewInt(GenesisEpoch)) == 0 {
shardState, err = committee.WithStakingEnabled.Compute( shardState, err = committee.WithStakingEnabled.Compute(
big.NewInt(GenesisEpoch), *bc.Config(), nil, big.NewInt(GenesisEpoch), bc.Config(), nil,
) )
} else { } else {
prevEpoch := new(big.Int).Sub(epoch, common.Big1) prevEpoch := new(big.Int).Sub(epoch, common.Big1)
@ -2643,8 +2641,3 @@ func (bc *BlockChain) ValidatorCandidates() []common.Address {
func (bc *BlockChain) DelegatorsInformation(addr common.Address) []*staking.Delegation { func (bc *BlockChain) DelegatorsInformation(addr common.Address) []*staking.Delegation {
return make([]*staking.Delegation, 0) return make([]*staking.Delegation, 0)
} }
// ValidatorStakingWithDelegation returns the amount of staking after applying all delegated stakes
func (bc *BlockChain) ValidatorStakingWithDelegation(addr common.Address) *big.Int {
return big.NewInt(0)
}

@ -351,7 +351,14 @@ func (b *APIBackend) GetDelegationsByDelegator(delegator common.Address) ([]comm
return addresses, delegations return addresses, delegations
} }
// GetValidatorStakingWithDelegation returns the amount of staking after applying all delegated stakes // GetValidatorSelfDelegation returns the amount of staking after applying all delegated stakes
func (b *APIBackend) GetValidatorStakingWithDelegation(addr common.Address) *big.Int { func (b *APIBackend) GetValidatorSelfDelegation(addr common.Address) *big.Int {
return b.hmy.BlockChain().ValidatorStakingWithDelegation(addr) wrapper, err := b.hmy.BlockChain().ReadValidatorData(addr)
if err != nil || wrapper == nil {
return nil
}
if len(wrapper.Delegations) == 0 {
return nil
}
return wrapper.Delegations[0].Amount
} }

@ -225,7 +225,7 @@ func QuorumForBlock(
) (quorum int, err error) { ) (quorum int, err error) {
var ss shard.State var ss shard.State
if reCalculate { if reCalculate {
ss, _ = committee.WithStakingEnabled.Compute(h.Epoch(), *chain.Config(), chain) ss, _ = committee.WithStakingEnabled.Compute(h.Epoch(), chain.Config(), chain)
} else { } else {
ss, err = chain.ReadShardState(h.Epoch()) ss, err = chain.ReadShardState(h.Epoch())
if err != nil { if err != nil {
@ -284,7 +284,7 @@ func GetPublicKeys(chain engine.ChainReader, header *block.Header, reCalculate b
var shardState shard.State var shardState shard.State
var err error var err error
if reCalculate { if reCalculate {
shardState, _ = committee.WithStakingEnabled.Compute(header.Epoch(), *chain.Config(), chain) shardState, _ = committee.WithStakingEnabled.Compute(header.Epoch(), chain.Config(), chain)
} else { } else {
shardState, err = chain.ReadShardState(header.Epoch()) shardState, err = chain.ReadShardState(header.Epoch())
if err != nil { if err != nil {
@ -301,6 +301,8 @@ func GetPublicKeys(chain engine.ChainReader, header *block.Header, reCalculate b
) )
} }
var committerKeys []*bls.PublicKey var committerKeys []*bls.PublicKey
utils.Logger().Print(committee.Slots)
for _, member := range committee.Slots { for _, member := range committee.Slots {
committerKey := new(bls.PublicKey) committerKey := new(bls.PublicKey)
err := member.BlsPublicKey.ToLibBLSPublicKey(committerKey) err := member.BlsPublicKey.ToLibBLSPublicKey(committerKey)

@ -79,7 +79,7 @@ type Backend interface {
GetValidatorStats(addr common.Address) *staking.ValidatorStats GetValidatorStats(addr common.Address) *staking.ValidatorStats
GetDelegationsByValidator(validator common.Address) []*staking.Delegation GetDelegationsByValidator(validator common.Address) []*staking.Delegation
GetDelegationsByDelegator(delegator common.Address) ([]common.Address, []*staking.Delegation) GetDelegationsByDelegator(delegator common.Address) ([]common.Address, []*staking.Delegation)
GetValidatorStakingWithDelegation(addr common.Address) *big.Int GetValidatorSelfDelegation(addr common.Address) *big.Int
} }
// GetAPIs returns all the APIs. // GetAPIs returns all the APIs.

@ -300,21 +300,20 @@ func (s *PublicBlockChainAPI) GetLeader(ctx context.Context) string {
return s.LatestHeader(ctx).Leader return s.LatestHeader(ctx).Leader
} }
// GetStake returns validator stake. // GetValidatorSelfDelegation returns validator stake.
func (s *PublicBlockChainAPI) GetStake(ctx context.Context, address string) hexutil.Uint64 { func (s *PublicBlockChainAPI) GetValidatorSelfDelegation(ctx context.Context, address string) hexutil.Uint64 {
validator := s.b.GetValidatorInformation(internal_common.ParseAddr(address)) return hexutil.Uint64(s.b.GetValidatorSelfDelegation(internal_common.ParseAddr(address)).Uint64())
return hexutil.Uint64(validator.Stake.Uint64())
} }
// GetValidatorStakingAddress stacking address returns validator stacking address. // GetValidatorTotalDelegation returns total balace stacking for validator with delegation.
func (s *PublicBlockChainAPI) GetValidatorStakingAddress(ctx context.Context, address string) string { func (s *PublicBlockChainAPI) GetValidatorTotalDelegation(ctx context.Context, address string) hexutil.Uint64 {
validator := s.b.GetValidatorInformation(internal_common.ParseAddr(address)) delegations := s.b.GetDelegationsByValidator(internal_common.ParseAddr(address))
return validator.Address.String() totalStake := big.NewInt(0)
} for _, delegation := range delegations {
totalStake.Add(totalStake, delegation.Amount)
// GetValidatorStakingWithDelegation returns total balace stacking for validator with delegation. }
func (s *PublicBlockChainAPI) GetValidatorStakingWithDelegation(ctx context.Context, address string) hexutil.Uint64 { // TODO: return more than uint64
return hexutil.Uint64(s.b.GetValidatorStakingWithDelegation(internal_common.ParseAddr(address)).Uint64()) return hexutil.Uint64(totalStake.Uint64())
} }
// GetShardingStructure returns an array of sharding structures. // GetShardingStructure returns an array of sharding structures.

@ -156,7 +156,7 @@ func newRPCValidator(validator *types2.Validator) *RPCValidator {
return &RPCValidator{ return &RPCValidator{
validator.Address, validator.Address,
validator.SlotPubKeys, validator.SlotPubKeys,
validator.Stake, big.NewInt(0), // TODO: add using the delegations
validator.UnbondingHeight, validator.UnbondingHeight,
validator.MinSelfDelegation, validator.MinSelfDelegation,
validator.MaxTotalDelegation, validator.MaxTotalDelegation,

@ -36,7 +36,7 @@ var (
ChainID: TestnetChainID, ChainID: TestnetChainID,
CrossTxEpoch: big.NewInt(0), CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(0), CrossLinkEpoch: big.NewInt(0),
StakingEpoch: EpochTBD, StakingEpoch: big.NewInt(3),
EIP155Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0), S3Epoch: big.NewInt(0),
} }

@ -41,7 +41,7 @@ type genesisInitializer struct {
// InitChainDB sets up a new genesis block in the database for the given shard. // InitChainDB sets up a new genesis block in the database for the given shard.
func (gi *genesisInitializer) InitChainDB(db ethdb.Database, shardID uint32) error { func (gi *genesisInitializer) InitChainDB(db ethdb.Database, shardID uint32) error {
shardState, _ := committee.WithStakingEnabled.Compute( shardState, _ := committee.WithStakingEnabled.Compute(
big.NewInt(core.GenesisEpoch), gi.node.chainConfig, nil, big.NewInt(core.GenesisEpoch), &gi.node.chainConfig, nil,
) )
if shardID != shard.BeaconChainShardID { if shardID != shard.BeaconChainShardID {
// store only the local shard for shard chains // store only the local shard for shard chains

@ -133,7 +133,7 @@ func (node *Node) HandleMessage(content []byte, sender libp2p_peer.ID) {
if block.ShardID() == 0 { if block.ShardID() == 0 {
utils.Logger().Info(). utils.Logger().Info().
Uint64("block", blocks[0].NumberU64()). Uint64("block", blocks[0].NumberU64()).
Msgf("Block being handled by block channel %d %d", block.NumberU64(), block.ShardID()) Msgf("Beacon block being handled by block channel: %d", block.NumberU64())
node.BeaconBlockChannel <- block node.BeaconBlockChannel <- block
} }
} }
@ -159,10 +159,6 @@ func (node *Node) HandleMessage(content []byte, sender libp2p_peer.ID) {
} }
case proto_node.PING: case proto_node.PING:
node.pingMessageHandler(msgPayload, sender) node.pingMessageHandler(msgPayload, sender)
case proto_node.ShardState:
if err := node.epochShardStateMessageHandler(msgPayload); err != nil {
utils.Logger().Warn().Err(err)
}
} }
default: default:
utils.Logger().Error(). utils.Logger().Error().
@ -378,8 +374,9 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block, commitSigAndBit
} }
} }
} }
// Update consensus keys at last so the change of leader status doesn't mess up normal flow // Update consensus keys at last so the change of leader status doesn't mess up normal flow
if shard.Schedule.IsLastBlock(newBlock.Number().Uint64()) { if len(newBlock.Header().ShardState()) > 0 {
next := new(big.Int).Add(newBlock.Epoch(), common.Big1) next := new(big.Int).Add(newBlock.Epoch(), common.Big1)
if node.chainConfig.StakingEpoch.Cmp(next) == 0 && if node.chainConfig.StakingEpoch.Cmp(next) == 0 &&
node.Consensus.Decider.Policy() != quorum.SuperMajorityStake { node.Consensus.Decider.Policy() != quorum.SuperMajorityStake {
@ -388,7 +385,7 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block, commitSigAndBit
return node.Consensus.ShardID, nil return node.Consensus.ShardID, nil
}) })
s, _ := committee.WithStakingEnabled.Compute( s, _ := committee.WithStakingEnabled.Compute(
next, node.chainConfig, node.Consensus.ChainReader, next, &node.chainConfig, node.Consensus.ChainReader,
) )
prevSubCommitteeDump := node.Consensus.Decider.JSON() prevSubCommitteeDump := node.Consensus.Decider.JSON()

@ -2,196 +2,17 @@ package node
import ( import (
"bytes" "bytes"
"errors"
"math" "math"
"math/big"
"os" "os"
"os/exec" "os/exec"
"strconv" "strconv"
"syscall" "syscall"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
proto_node "github.com/harmony-one/harmony/api/proto/node"
"github.com/harmony-one/harmony/core/types"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/p2p/host"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/shard/committee"
) )
// validateNewShardState validate whether the new shard state root matches
func (node *Node) validateNewShardState(block *types.Block) error {
// Common case first – blocks without resharding proposal
header := block.Header()
if header.ShardStateHash() == (common.Hash{}) {
// No new shard state was proposed
if block.ShardID() == shard.BeaconChainShardID {
if shard.Schedule.IsLastBlock(block.Number().Uint64()) {
// TODO ek - invoke view change
return errors.New("beacon leader did not propose resharding")
}
} else {
if node.nextShardState.master != nil &&
!time.Now().Before(node.nextShardState.proposeTime) {
// TODO ek – invoke view change
return errors.New("regular leader did not propose resharding")
}
}
// We aren't expecting to reshard, so proceed to sign
return nil
}
shardState := &shard.State{}
err := rlp.DecodeBytes(header.ShardState(), shardState)
if err != nil {
return err
}
proposed := *shardState
if block.ShardID() == shard.BeaconChainShardID {
// Beacon validators independently recalculate the master state and
// compare it against the proposed copy.
// TODO ek – this may be called from regular shards,
// for vetting beacon chain blocks received during block syncing.
// DRand may or or may not get in the way. Test this out.
expected, err := committee.WithStakingEnabled.ReadFromDB(
new(big.Int).Sub(block.Header().Epoch(), common.Big1),
node.Beaconchain(),
)
if err != nil {
utils.Logger().Error().Err(err).Msg("cannot calculate expected shard state")
return ctxerror.New("cannot calculate expected shard state").
WithCause(err)
}
if shard.CompareShardState(expected, proposed) != 0 {
// TODO ek – log state proposal differences
// TODO ek – this error should trigger view change
err := errors.New("shard state proposal is different from expected")
// TODO ek/chao – calculated shard state is different even with the
// same input, i.e. it is nondeterministic.
// Don't treat this as a blocker until we fix the nondeterminism.
utils.Logger().Warn().Err(err).Msg("shard state proposal is different from expected")
}
} else {
// Regular validators fetch the local-shard copy on the beacon chain
// and compare it against the proposed copy.
//
// We trust the master proposal in our copy of beacon chain.
// The sanity check for the master proposal is done earlier,
// when the beacon block containing the master proposal is received
// and before it is admitted into the local beacon chain.
//
// TODO ek – fetch masterProposal from beaconchain instead
masterProposal := node.nextShardState.master.ShardState
expected := masterProposal.FindCommitteeByID(block.ShardID())
switch len(proposed) {
case 0:
// Proposal to discontinue shard
if expected != nil {
// TODO ek – invoke view change
utils.Logger().Error().Msg("leader proposed to disband against beacon decision")
return errors.New(
"leader proposed to disband against beacon decision")
}
case 1:
// Proposal to continue shard
proposed := proposed[0]
// Sanity check: Shard ID should match
if proposed.ShardID != block.ShardID() {
// TODO ek – invoke view change
utils.Logger().Error().
Uint32("proposedShard", proposed.ShardID).
Uint32("blockShard", block.ShardID()).
Msg("proposal has incorrect shard ID")
return ctxerror.New("proposal has incorrect shard ID",
"proposedShard", proposed.ShardID,
"blockShard", block.ShardID())
}
// Did beaconchain say we are no more?
if expected == nil {
// TODO ek – invoke view change
utils.Logger().Error().Msg("leader proposed to continue against beacon decision")
return errors.New(
"leader proposed to continue against beacon decision")
}
// Did beaconchain say the same proposal?
if shard.CompareCommittee(expected, &proposed) != 0 {
// TODO ek – log differences
// TODO ek – invoke view change
utils.Logger().Error().Msg("proposal differs from one in beacon chain")
return errors.New("proposal differs from one in beacon chain")
}
default:
// TODO ek – invoke view change
utils.Logger().Error().
Int("numShards", len(proposed)).
Msg("regular resharding proposal has incorrect number of shards")
return ctxerror.New(
"regular resharding proposal has incorrect number of shards",
"numShards", len(proposed))
}
}
return nil
}
func (node *Node) broadcastEpochShardState(newBlock *types.Block) error {
shardState, err := newBlock.Header().GetShardState()
if err != nil {
return err
}
epochShardStateMessage := proto_node.ConstructEpochShardStateMessage(
shard.EpochShardState{
Epoch: newBlock.Header().Epoch().Uint64() + 1,
ShardState: shardState,
},
)
return node.host.SendMessageToGroups(
[]nodeconfig.GroupID{node.NodeConfig.GetClientGroupID()},
host.ConstructP2pMessage(byte(0), epochShardStateMessage))
}
func (node *Node) epochShardStateMessageHandler(msgPayload []byte) error {
epochShardState, err := proto_node.DeserializeEpochShardStateFromMessage(msgPayload)
if err != nil {
utils.Logger().Error().Err(err).Msg("Can't get shard state message")
return ctxerror.New("Can't get shard state message").WithCause(err)
}
if node.Consensus == nil {
return nil
}
receivedEpoch := big.NewInt(int64(epochShardState.Epoch))
utils.Logger().Info().
Int64("epoch", receivedEpoch.Int64()).
Msg("received new shard state")
node.nextShardState.master = epochShardState
if node.Consensus.IsLeader() {
// Wait a bit to allow the master table to reach other validators.
node.nextShardState.proposeTime = time.Now().Add(5 * time.Second)
} else {
// Wait a bit to allow the master table to reach the leader,
// and to allow the leader to propose next shard state based upon it.
node.nextShardState.proposeTime = time.Now().Add(15 * time.Second)
}
// TODO ek – this should be done from replaying beaconchain once
// beaconchain sync is fixed
err = node.Beaconchain().WriteShardState(
receivedEpoch, epochShardState.ShardState)
if err != nil {
utils.Logger().Error().
Uint64("epoch", receivedEpoch.Uint64()).
Err(err).Msg("cannot store shard state")
return ctxerror.New("cannot store shard state", "epoch", receivedEpoch).
WithCause(err)
}
return nil
}
/* /*
func (node *Node) transitionIntoNextEpoch(shardState types.State) { func (node *Node) transitionIntoNextEpoch(shardState types.State) {
logger = logger.New( logger = logger.New(

@ -165,9 +165,11 @@ func (node *Node) DoBeaconSyncing() {
for { for {
select { select {
case beaconBlock := <-node.BeaconBlockChannel: case beaconBlock := <-node.BeaconBlockChannel:
err := node.beaconSync.UpdateBlockAndStatus(beaconBlock, node.Beaconchain(), node.BeaconWorker) if node.beaconSync != nil {
if err != nil { err := node.beaconSync.UpdateBlockAndStatus(beaconBlock, node.Beaconchain(), node.BeaconWorker)
node.beaconSync.AddLastMileBlock(beaconBlock) if err != nil {
node.beaconSync.AddLastMileBlock(beaconBlock)
}
} }
} }
} }

@ -290,26 +290,36 @@ func (w *Worker) SuperCommitteeForNextEpoch(
nextCommittee shard.State nextCommittee shard.State
oops error oops error
) )
// WARN This currently not working and breaks around 15 block switch shardID {
// switch shardID { case shard.BeaconChainShardID:
// case shard.BeaconChainShardID: if shard.Schedule.IsLastBlock(w.current.header.Number().Uint64()) {
if shard.Schedule.IsLastBlock(w.current.header.Number().Uint64()) { nextCommittee, oops = committee.WithStakingEnabled.Compute(
nextCommittee, oops = committee.WithStakingEnabled.Compute( new(big.Int).Add(w.current.header.Epoch(), common.Big1),
new(big.Int).Add(w.current.header.Epoch(), common.Big1), w.config,
*w.config, beacon,
beacon, )
) }
default:
// WARN When we first enable staking, this condition may not be robust by itself.
if w.config.IsStaking(w.current.header.Epoch()) {
switch beacon.CurrentHeader().Epoch().Cmp(w.current.header.Epoch()) {
case 1:
nextCommittee, oops = committee.WithStakingEnabled.ReadFromDB(
beacon.CurrentHeader().Epoch(), beacon,
)
}
} else {
if shard.Schedule.IsLastBlock(w.current.header.Number().Uint64()) {
nextCommittee, oops = committee.WithStakingEnabled.Compute(
new(big.Int).Add(w.current.header.Epoch(), common.Big1),
w.config,
beacon,
)
}
}
} }
// default:
// WARN When we first enable staking, this condition may not be robust by itself.
// switch beacon.CurrentHeader().Epoch().Cmp(w.current.header.Epoch()) {
// case 1:
// nextCommittee, oops = committee.WithStakingEnabled.ReadFromDB(
// beacon.CurrentHeader().Epoch(), beacon,
// )
// }
// }
return nextCommittee, oops return nextCommittee, oops
} }

@ -19,7 +19,7 @@ import (
// ValidatorListProvider .. // ValidatorListProvider ..
type ValidatorListProvider interface { type ValidatorListProvider interface {
Compute( Compute(
epoch *big.Int, config params.ChainConfig, reader DataProvider, epoch *big.Int, config *params.ChainConfig, reader DataProvider,
) (shard.State, error) ) (shard.State, error)
ReadFromDB(epoch *big.Int, reader DataProvider) (shard.State, error) ReadFromDB(epoch *big.Int, reader DataProvider) (shard.State, error)
} }
@ -41,7 +41,6 @@ type Reader interface {
// StakingCandidatesReader .. // StakingCandidatesReader ..
type StakingCandidatesReader interface { type StakingCandidatesReader interface {
ReadValidatorData(addr common.Address) (*staking.ValidatorWrapper, error) ReadValidatorData(addr common.Address) (*staking.ValidatorWrapper, error)
ValidatorStakingWithDelegation(addr common.Address) *big.Int
ValidatorCandidates() []common.Address ValidatorCandidates() []common.Address
} }
@ -126,11 +125,15 @@ func eposStakedCommittee(
for i := range candidates { for i := range candidates {
// TODO Should be using .ValidatorStakingWithDelegation, not implemented yet // TODO Should be using .ValidatorStakingWithDelegation, not implemented yet
validator, err := stakerReader.ReadValidatorData(candidates[i]) validator, err := stakerReader.ReadValidatorData(candidates[i])
validatorStake := big.NewInt(0)
for _, delegation := range validator.Delegations {
validatorStake.Add(validatorStake, delegation.Amount)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
essentials[validator.Address] = effective.SlotOrder{ essentials[validator.Address] = effective.SlotOrder{
validator.Stake, validatorStake,
validator.SlotPubKeys, validator.SlotPubKeys,
} }
} }
@ -185,15 +188,8 @@ func eposStakedCommittee(
func (def partialStakingEnabled) ComputePublicKeys( func (def partialStakingEnabled) ComputePublicKeys(
epoch *big.Int, d DataProvider, epoch *big.Int, d DataProvider,
) [][]*bls.PublicKey { ) [][]*bls.PublicKey {
config := d.Config() config := d.Config()
instance := shard.Schedule.InstanceForEpoch(epoch) superComm, _ := def.Compute(epoch, config, d)
superComm := shard.State{}
if config.IsStaking(epoch) {
superComm, _ = eposStakedCommittee(instance, d, 320)
} else {
superComm = preStakingEnabledCommittee(instance)
}
allIdentities := make([][]*bls.PublicKey, len(superComm)) allIdentities := make([][]*bls.PublicKey, len(superComm))
@ -249,7 +245,7 @@ func (def partialStakingEnabled) ReadFromDB(
// ReadFromComputation is single entry point for reading the State of the network // ReadFromComputation is single entry point for reading the State of the network
func (def partialStakingEnabled) Compute( func (def partialStakingEnabled) Compute(
epoch *big.Int, config params.ChainConfig, stakerReader DataProvider, epoch *big.Int, config *params.ChainConfig, stakerReader DataProvider,
) (newSuperComm shard.State, err error) { ) (newSuperComm shard.State, err error) {
instance := shard.Schedule.InstanceForEpoch(epoch) instance := shard.Schedule.InstanceForEpoch(epoch)
if !config.IsStaking(epoch) { if !config.IsStaking(epoch) {

@ -57,9 +57,6 @@ type Validator struct {
Address common.Address `json:"address" yaml:"address"` Address common.Address `json:"address" yaml:"address"`
// The BLS public key of the validator for consensus // The BLS public key of the validator for consensus
SlotPubKeys []shard.BlsPublicKey `json:"slot_pub_keys" yaml:"slot_pub_keys"` SlotPubKeys []shard.BlsPublicKey `json:"slot_pub_keys" yaml:"slot_pub_keys"`
// TODO Need to remove this .Stake Field
// The stake put by the validator itself
Stake *big.Int `json:"stake" yaml:"stake"`
// if unbonding, height at which this validator has begun unbonding // if unbonding, height at which this validator has begun unbonding
UnbondingHeight *big.Int `json:"unbonding_height" yaml:"unbonding_height"` UnbondingHeight *big.Int `json:"unbonding_height" yaml:"unbonding_height"`
// validator's self declared minimum self delegation // validator's self declared minimum self delegation
@ -218,9 +215,6 @@ func (v *Validator) GetAddress() common.Address { return v.Address }
// GetName returns the name of validator in the description // GetName returns the name of validator in the description
func (v *Validator) GetName() string { return v.Description.Name } func (v *Validator) GetName() string { return v.Description.Name }
// GetStake returns the total staking amount
func (v *Validator) GetStake() *big.Int { return v.Stake }
// GetCommissionRate returns the commission rate of the validator // GetCommissionRate returns the commission rate of the validator
func (v *Validator) GetCommissionRate() numeric.Dec { return v.Commission.Rate } func (v *Validator) GetCommissionRate() numeric.Dec { return v.Commission.Rate }
@ -239,7 +233,7 @@ func CreateValidatorFromNewMsg(val *CreateValidator, blockNum *big.Int) (*Valida
// TODO: a new validator should have a minimum of 1 token as self delegation, and that should be added as a delegation entry here. // TODO: a new validator should have a minimum of 1 token as self delegation, and that should be added as a delegation entry here.
v := Validator{ v := Validator{
val.ValidatorAddress, pubKeys, val.ValidatorAddress, pubKeys,
val.Amount, new(big.Int), val.MinSelfDelegation, val.MaxTotalDelegation, false, new(big.Int), val.MinSelfDelegation, val.MaxTotalDelegation, false,
commission, desc, blockNum, commission, desc, blockNum,
} }
return &v, nil return &v, nil
@ -304,14 +298,13 @@ func (v *Validator) String() string {
return fmt.Sprintf(`Validator return fmt.Sprintf(`Validator
Address: %s Address: %s
SlotPubKeys: %s SlotPubKeys: %s
Stake: %s
Unbonding Height: %v Unbonding Height: %v
Minimum Self Delegation: %v Minimum Self Delegation: %v
Maximum Total Delegation: %v Maximum Total Delegation: %v
Description: %v Description: %v
Commission: %v`, Commission: %v`,
common2.MustAddressToBech32(v.Address), printSlotPubKeys(v.SlotPubKeys), common2.MustAddressToBech32(v.Address), printSlotPubKeys(v.SlotPubKeys),
v.Stake, v.UnbondingHeight, v.UnbondingHeight,
v.MinSelfDelegation, v.MaxTotalDelegation, v.Description, v.Commission, v.MinSelfDelegation, v.MaxTotalDelegation, v.Description, v.Commission,
) )
} }

@ -12,7 +12,7 @@ func CreateNewValidator() Validator {
c := Commission{cr, big.NewInt(300)} c := Commission{cr, big.NewInt(300)}
d := Description{Name: "SuperHero", Identity: "YouWillNotKnow", Website: "under_construction", Details: "N/A"} d := Description{Name: "SuperHero", Identity: "YouWillNotKnow", Website: "under_construction", Details: "N/A"}
v := Validator{Address: common.Address{}, SlotPubKeys: nil, v := Validator{Address: common.Address{}, SlotPubKeys: nil,
Stake: big.NewInt(500), UnbondingHeight: big.NewInt(20), MinSelfDelegation: big.NewInt(7), UnbondingHeight: big.NewInt(20), MinSelfDelegation: big.NewInt(7),
Active: false, Commission: c, Description: d} Active: false, Commission: c, Description: d}
return v return v
} }

Loading…
Cancel
Save