[committee] Switch over committee for stake epoch

pull/1850/head
Edgar Aroutiounian 5 years ago
parent e0c24d8f13
commit c673bd97d9
  1. 3
      cmd/harmony/main.go
  2. 3
      consensus/consensus_service.go
  3. 4
      consensus/engine/consensus_engine.go
  4. 6
      core/chain_makers.go
  5. 1
      core/state/statedb.go
  6. 7
      internal/chain/engine.go
  7. 2
      internal/configs/sharding/localnet.go
  8. 7
      internal/params/config.go
  9. 1
      node/node_genesis.go
  10. 30
      node/node_handler.go
  11. 9
      shard/committee/assignment.go
  12. 9
      staking/types/validator.go

@ -224,7 +224,6 @@ func setupConsensusKey(nodeConfig *nodeconfig.ConfigType) *bls.PublicKey {
os.Exit(100)
}
pubKey := consensusPriKey.GetPublicKey()
// Consensus keys are the BLS12-381 keys used to sign consensus messages
nodeConfig.ConsensusPriKey, nodeConfig.ConsensusPubKey = consensusPriKey, consensusPriKey.GetPublicKey()
if nodeConfig.ConsensusPriKey == nil || nodeConfig.ConsensusPubKey == nil {
@ -236,7 +235,6 @@ func setupConsensusKey(nodeConfig *nodeconfig.ConfigType) *bls.PublicKey {
func createGlobalConfig() *nodeconfig.ConfigType {
var err error
nodeConfig := nodeconfig.GetShardConfig(initialAccount.ShardID)
if *nodeType == "validator" {
// Set up consensus keys.
@ -310,7 +308,6 @@ func setupConsensusAndNode(nodeConfig *nodeconfig.ConfigType) *node.Node {
// Current node.
chainDBFactory := &shardchain.LDBFactory{RootDir: nodeConfig.DBDir}
// fmt.Println("What is my port at this moment", *port)
currentNode := node.New(
myHost, currentConsensus, chainDBFactory, *isArchival, *port,

@ -119,7 +119,6 @@ func (consensus *Consensus) UpdatePublicKeys(pubKeys []*bls.PublicKey) int64 {
for i := range pubKeys {
utils.Logger().Info().Int("index", i).Str("BLSPubKey", pubKeys[i].SerializeToHexStr()).Msg("Member")
}
consensus.LeaderPubKey = pubKeys[0]
utils.Logger().Info().
Str("info", consensus.LeaderPubKey.SerializeToHexStr()).Msg("My Leader")
@ -263,7 +262,7 @@ func (consensus *Consensus) verifySenderKey(msg *msg_pb.Message) (*bls.PublicKey
}
if !consensus.IsValidatorInCommittee(senderKey) {
return nil, fmt.Errorf("Validator %s is not in committee on shard: %d", senderKey.SerializeToHexStr(), consensus.ShardID)
return nil, fmt.Errorf("Validator %s is not in committee", senderKey.SerializeToHexStr())
}
return senderKey, nil
}

@ -43,6 +43,10 @@ type ChainReader interface {
// ReadActiveValidatorList retrieves the list of active validators
ReadActiveValidatorList() ([]common.Address, error)
ValidatorCandidates() []common.Address
ReadValidatorData(addr common.Address) (*staking.ValidatorWrapper, error)
ValidatorStakingWithDelegation(addr common.Address) *big.Int
}
// Engine is an algorithm agnostic consensus engine.

@ -271,3 +271,9 @@ func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *block.Hea
func (cr *fakeChainReader) GetBlock(hash common.Hash, number uint64) *types.Block { return nil }
func (cr *fakeChainReader) ReadShardState(epoch *big.Int) (shard.State, error) { return nil, nil }
func (cr *fakeChainReader) ReadActiveValidatorList() ([]common.Address, error) { return nil, nil }
func (cr *fakeChainReader) ValidatorCandidates() []common.Address { return nil }
func (cr *fakeChainReader) ReadValidatorData(addr common.Address) (*staking.ValidatorWrapper, error) {
return nil, nil
}
func (cr *fakeChainReader) ValidatorStakingWithDelegation(addr common.Address) *big.Int { return nil }

@ -30,7 +30,6 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/staking"
stk "github.com/harmony-one/harmony/staking/types"

@ -11,6 +11,7 @@ import (
"github.com/harmony-one/harmony/consensus/reward"
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard"
@ -199,6 +200,7 @@ func (e *engineImpl) Finalize(
}
for _, validator := range validators {
wrapper := state.GetStakingInfo(validator)
// fmt.Println("In finalize", validator.String(), "wrapper:", wrapper, "on-epoch", header.Epoch(), "on-shard", header.ShardID())
if wrapper != nil {
for i := range wrapper.Delegations {
delegation := wrapper.Delegations[i]
@ -209,6 +211,7 @@ func (e *engineImpl) Finalize(
return nil, ctxerror.New("failed update validator info").WithCause(err)
}
} else {
err = errors.New("validator came back empty" + common2.MustAddressToBech32(validator))
return nil, ctxerror.New("failed getting validator info").WithCause(err)
}
}
@ -223,7 +226,7 @@ func QuorumForBlock(
) (quorum int, err error) {
var ss shard.State
if reCalculate {
ss, _ = committee.WithStakingEnabled.Compute(h.Epoch(), *chain.Config(), nil)
ss, _ = committee.WithStakingEnabled.Compute(h.Epoch(), *chain.Config(), chain)
} else {
ss, err = chain.ReadShardState(h.Epoch())
if err != nil {
@ -282,7 +285,7 @@ func GetPublicKeys(chain engine.ChainReader, header *block.Header, reCalculate b
var shardState shard.State
var err error
if reCalculate {
shardState, _ = committee.WithStakingEnabled.Compute(header.Epoch(), *chain.Config(), nil)
shardState, _ = committee.WithStakingEnabled.Compute(header.Epoch(), *chain.Config(), chain)
} else {
shardState, err = chain.ReadShardState(header.Epoch())
if err != nil {

@ -17,7 +17,7 @@ const (
localnetV1Epoch = 1
localnetV2Epoch = 2
localnetEpochBlock1 = 3
localnetEpochBlock1 = 10
twoOne = 5
localnetVdfDifficulty = 5000 // This takes about 10s to finish the vdf

@ -36,10 +36,9 @@ var (
ChainID: TestnetChainID,
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(0),
// MinEpoch needed is at least 1, crashes on 0
StakingEpoch: big.NewInt(1),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
StakingEpoch: EpochTBD,
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
}
// PangaeaChainConfig contains the chain parameters for the Pangaea network.

@ -43,6 +43,7 @@ func (gi *genesisInitializer) InitChainDB(db ethdb.Database, shardID uint32) err
shardState, _ := committee.WithStakingEnabled.Compute(
big.NewInt(core.GenesisEpoch), gi.node.chainConfig, nil,
)
// fmt.Println("initial-shard-state", shardState.JSON())
if shardID != shard.BeaconChainShardID {

@ -8,7 +8,6 @@ import (
"sync/atomic"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/bls/ffi/go/bls"
@ -18,7 +17,6 @@ import (
proto_discovery "github.com/harmony-one/harmony/api/proto/discovery"
proto_node "github.com/harmony-one/harmony/api/proto/node"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/core/types"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/ctxerror"
@ -27,7 +25,6 @@ import (
"github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/p2p/host"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/shard/committee"
staking "github.com/harmony-one/harmony/staking/types"
)
@ -335,8 +332,6 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block, commitSigAndBit
return
}
// fmt.Println("Finished consensus->", node.NodeConfig.Port)
// Update last consensus time for metrics
// TODO: randomly selected a few validators to broadcast messages instead of only leader broadcast
// TODO: refactor the asynchronous calls to separate go routine.
@ -363,35 +358,10 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block, commitSigAndBit
// Broadcast client requested missing cross shard receipts if there is any
node.BroadcastMissingCXReceipts()
next := new(big.Int).Add(newBlock.Epoch(), common.Big1)
// 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 node.chainConfig.StakingEpoch.Cmp(next) == 0 &&
node.Consensus.Decider.Policy() != quorum.SuperMajorityStake {
node.Consensus.Decider = quorum.NewDecider(quorum.SuperMajorityStake)
node.Consensus.Decider.SetShardIDProvider(func() (uint32, error) {
return node.Consensus.ShardID, nil
})
s, _ := committee.WithStakingEnabled.Compute(
next, node.chainConfig, node.Consensus.ChainReader,
)
node.Consensus.Decider.UpdateVotingPower(
s.FindCommitteeByID(node.Consensus.ShardID).Slots,
)
}
node.Consensus.UpdateConsensusInformation()
if shard.Schedule.IsLastBlock(newBlock.Number().Uint64()) {
if node.chainConfig.StakingEpoch.Cmp(next) == 0 {
// Hit this case again, need after UpdateConsensus
curPubKeys := committee.WithStakingEnabled.ComputePublicKeys(
next, node.Consensus.ChainReader,
)[int(node.Consensus.ShardID)]
node.Consensus.Decider.UpdateParticipants(curPubKeys)
}
}
}
// TODO chao: uncomment this after beacon syncing is stable

@ -10,6 +10,7 @@ import (
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/staking/effective"
staking "github.com/harmony-one/harmony/staking/types"
@ -118,6 +119,7 @@ func eposStakedCommittee(
// TODO Nervous about this because overtime the list will become quite large
candidates := stakerReader.ValidatorCandidates()
essentials := map[common.Address]effective.SlotOrder{}
utils.Logger().Info().Int("candidates-count", len(candidates)).Msg("Preparing EPoS Staked Committee")
// TODO benchmark difference if went with data structure that sorts on insert
for i := range candidates {
@ -126,6 +128,7 @@ func eposStakedCommittee(
if err != nil {
return nil, err
}
essentials[validator.Address] = effective.SlotOrder{
validator.Stake,
validator.SlotPubKeys,
@ -170,7 +173,6 @@ func eposStakedCommittee(
&slot.Dec,
})
}
// fmt.Println("epos-comm", superComm.JSON())
return superComm, nil
}
@ -183,10 +185,7 @@ func (def partialStakingEnabled) ComputePublicKeys(
instance := shard.Schedule.InstanceForEpoch(epoch)
superComm := shard.State{}
if config.IsStaking(epoch) {
stakedSlots :=
(instance.NumNodesPerShard() - instance.NumHarmonyOperatedNodesPerShard()) *
int(instance.NumShards())
superComm, _ = eposStakedCommittee(instance, d, stakedSlots)
superComm, _ = eposStakedCommittee(instance, d, 320)
} else {
superComm = preStakingEnabledCommittee(instance)
}

@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/rlp"
common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard"
)
@ -46,6 +47,7 @@ type Validator struct {
Address common.Address `json:"address" yaml:"address"`
// The BLS public key of the validator for consensus
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
@ -108,6 +110,13 @@ func (w *ValidatorWrapper) SanityCheck() error {
hundredPercent := numeric.NewDec(1)
zeroPercent := numeric.NewDec(0)
utils.Logger().Info().
Str("rate", w.Validator.Rate.String()).
Str("max-rate", w.Validator.MaxRate.String()).
Str("max-change-rate", w.Validator.MaxChangeRate.String()).
Msg("Sanity check on validator commission rates, should all be in [0, 1]")
if w.Validator.Rate.LT(zeroPercent) || w.Validator.Rate.GT(hundredPercent) {
return errInvalidComissionRate
}

Loading…
Cancel
Save