diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 80e2c58a1..4d45836d2 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.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, diff --git a/consensus/consensus_service.go b/consensus/consensus_service.go index 20cbb3cc9..624492934 100644 --- a/consensus/consensus_service.go +++ b/consensus/consensus_service.go @@ -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 } diff --git a/consensus/engine/consensus_engine.go b/consensus/engine/consensus_engine.go index 6b0d7f07f..f2932c411 100644 --- a/consensus/engine/consensus_engine.go +++ b/consensus/engine/consensus_engine.go @@ -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. diff --git a/core/chain_makers.go b/core/chain_makers.go index cdd30e907..8d7da2610 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -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 } diff --git a/core/state/statedb.go b/core/state/statedb.go index 10681ff8c..10a38749f 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -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" diff --git a/internal/chain/engine.go b/internal/chain/engine.go index 31ecf1501..6dbd7e45c 100644 --- a/internal/chain/engine.go +++ b/internal/chain/engine.go @@ -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 { diff --git a/internal/configs/sharding/localnet.go b/internal/configs/sharding/localnet.go index c656d6035..0bbf18182 100644 --- a/internal/configs/sharding/localnet.go +++ b/internal/configs/sharding/localnet.go @@ -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 diff --git a/internal/params/config.go b/internal/params/config.go index 7848a9a0c..21af1fda3 100644 --- a/internal/params/config.go +++ b/internal/params/config.go @@ -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. diff --git a/node/node_genesis.go b/node/node_genesis.go index 7c03d4062..0beb04876 100644 --- a/node/node_genesis.go +++ b/node/node_genesis.go @@ -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 { diff --git a/node/node_handler.go b/node/node_handler.go index 12aaa37c3..1f128fba6 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -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 diff --git a/shard/committee/assignment.go b/shard/committee/assignment.go index b6c7498ed..ce0458cdc 100644 --- a/shard/committee/assignment.go +++ b/shard/committee/assignment.go @@ -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) } diff --git a/staking/types/validator.go b/staking/types/validator.go index 1d4920201..b97927efb 100644 --- a/staking/types/validator.go +++ b/staking/types/validator.go @@ -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 }