diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index c30df7ed5..377e7e40d 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -489,7 +489,7 @@ func nodeconfigSetShardSchedule(config harmonyconfig.HarmonyConfig) { } devnetConfig, err := shardingconfig.NewInstance( - uint32(dnConfig.NumShards), dnConfig.ShardSize, dnConfig.HmyNodeSize, dnConfig.SlotsLimit, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccounts, nil, shardingconfig.VLBPE) + uint32(dnConfig.NumShards), dnConfig.ShardSize, dnConfig.HmyNodeSize, dnConfig.SlotsLimit, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccounts, shardingconfig.Allowlist{}, nil, shardingconfig.VLBPE) if err != nil { _, _ = fmt.Fprintf(os.Stderr, "ERROR invalid devnet sharding config: %s", err) diff --git a/consensus/consensus_service.go b/consensus/consensus_service.go index 69ec3625b..2c59a311f 100644 --- a/consensus/consensus_service.go +++ b/consensus/consensus_service.go @@ -73,10 +73,10 @@ func (consensus *Consensus) signAndMarshalConsensusMessage(message *msg_pb.Messa // UpdatePublicKeys updates the PublicKeys for // quorum on current subcommittee, protected by a mutex -func (consensus *Consensus) UpdatePublicKeys(pubKeys []bls_cosi.PublicKeyWrapper) int64 { +func (consensus *Consensus) UpdatePublicKeys(pubKeys, allowlist []bls_cosi.PublicKeyWrapper) int64 { // TODO: use mutex for updating public keys pointer. No need to lock on all these logic. consensus.pubKeyLock.Lock() - consensus.Decider.UpdateParticipants(pubKeys) + consensus.Decider.UpdateParticipants(pubKeys, allowlist) consensus.getLogger().Info().Msg("My Committee updated") for i := range pubKeys { consensus.getLogger().Info(). @@ -372,7 +372,7 @@ func (consensus *Consensus) UpdateConsensusInformation() Mode { consensus.getLogger().Info(). Int("numPubKeys", len(pubKeys)). Msg("[UpdateConsensusInformation] Successfully updated public keys") - consensus.UpdatePublicKeys(pubKeys) + consensus.UpdatePublicKeys(pubKeys, shard.Schedule.InstanceForEpoch(nextEpoch).ExternalAllowlist()) // Update voters in the committee if _, err := consensus.Decider.SetVoters( diff --git a/consensus/construct_test.go b/consensus/construct_test.go index 69c8e89b2..9e3b54712 100644 --- a/consensus/construct_test.go +++ b/consensus/construct_test.go @@ -151,7 +151,7 @@ func TestConstructPrepareMessage(test *testing.T) { if err != nil { test.Fatalf("Cannot create consensus: %v", err) } - consensus.UpdatePublicKeys([]bls.PublicKeyWrapper{pubKeyWrapper1, pubKeyWrapper2}) + consensus.UpdatePublicKeys([]bls.PublicKeyWrapper{pubKeyWrapper1, pubKeyWrapper2}, []bls.PublicKeyWrapper{}) consensus.SetCurBlockViewID(2) consensus.blockHash = [32]byte{} @@ -243,7 +243,7 @@ func TestConstructCommitMessage(test *testing.T) { if err != nil { test.Fatalf("Cannot create consensus: %v", err) } - consensus.UpdatePublicKeys([]bls.PublicKeyWrapper{pubKeyWrapper1, pubKeyWrapper2}) + consensus.UpdatePublicKeys([]bls.PublicKeyWrapper{pubKeyWrapper1, pubKeyWrapper2}, []bls.PublicKeyWrapper{}) consensus.SetCurBlockViewID(2) consensus.blockHash = [32]byte{} diff --git a/consensus/quorum/one-node-staked-vote_test.go b/consensus/quorum/one-node-staked-vote_test.go index f18a5ae06..d365d27c9 100644 --- a/consensus/quorum/one-node-staked-vote_test.go +++ b/consensus/quorum/one-node-staked-vote_test.go @@ -71,7 +71,7 @@ func setupBaseCase() (Decider, *TallyResult, shard.SlotList, map[string]secretKe } decider := NewDecider(SuperMajorityStake, shard.BeaconChainShardID) - decider.UpdateParticipants(pubKeys) + decider.UpdateParticipants(pubKeys, []bls.PublicKeyWrapper{}) tally, err := decider.SetVoters(&shard.Committee{ ShardID: shard.BeaconChainShardID, Slots: slotList, }, big.NewInt(3)) @@ -100,7 +100,7 @@ func setupEdgeCase() (Decider, *TallyResult, shard.SlotList, secretKeyMap) { } decider := NewDecider(SuperMajorityStake, shard.BeaconChainShardID) - decider.UpdateParticipants(pubKeys) + decider.UpdateParticipants(pubKeys, []bls.PublicKeyWrapper{}) tally, err := decider.SetVoters(&shard.Committee{ ShardID: shard.BeaconChainShardID, Slots: slotList, }, big.NewInt(3)) diff --git a/consensus/quorum/quorom_test.go b/consensus/quorum/quorom_test.go index 53631b575..60b910a4d 100644 --- a/consensus/quorum/quorom_test.go +++ b/consensus/quorum/quorom_test.go @@ -8,6 +8,7 @@ import ( bls_core "github.com/harmony-one/bls/ffi/go/bls" harmony_bls "github.com/harmony-one/harmony/crypto/bls" shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding" + "github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/shard" "github.com/stretchr/testify/assert" @@ -63,7 +64,7 @@ func TestAddingQuoromParticipants(t *testing.T) { blsKeys = append(blsKeys, wrapper) } - decider.UpdateParticipants(blsKeys) + decider.UpdateParticipants(blsKeys, []bls.PublicKeyWrapper{}) assert.Equal(t, keyCount, decider.ParticipantsCount()) } @@ -86,7 +87,7 @@ func TestSubmitVote(test *testing.T) { pubKeyWrapper2 := bls.PublicKeyWrapper{Object: blsPriKey2.GetPublicKey()} pubKeyWrapper2.Bytes.FromLibBLSPublicKey(pubKeyWrapper2.Object) - decider.UpdateParticipants([]bls.PublicKeyWrapper{pubKeyWrapper1, pubKeyWrapper2}) + decider.UpdateParticipants([]bls.PublicKeyWrapper{pubKeyWrapper1, pubKeyWrapper2}, []bls.PublicKeyWrapper{}) if _, err := decider.submitVote( Prepare, @@ -143,7 +144,7 @@ func TestSubmitVoteAggregateSig(test *testing.T) { pubKeyWrapper3 := bls.PublicKeyWrapper{Object: blsPriKey3.GetPublicKey()} pubKeyWrapper3.Bytes.FromLibBLSPublicKey(pubKeyWrapper3.Object) - decider.UpdateParticipants([]bls.PublicKeyWrapper{pubKeyWrapper1, pubKeyWrapper2}) + decider.UpdateParticipants([]bls.PublicKeyWrapper{pubKeyWrapper1, pubKeyWrapper2}, []bls.PublicKeyWrapper{}) decider.submitVote( Prepare, @@ -221,7 +222,7 @@ func TestAddNewVote(test *testing.T) { pubKeys = append(pubKeys, wrapper) } - decider.UpdateParticipants(pubKeys) + decider.UpdateParticipants(pubKeys, []bls.PublicKeyWrapper{}) decider.SetVoters(&shard.Committee{ ShardID: shard.BeaconChainShardID, Slots: slotList, }, big.NewInt(3)) @@ -326,7 +327,7 @@ func TestAddNewVoteAggregateSig(test *testing.T) { // make all external keys belong to same account slotList[3].EcdsaAddress = slotList[4].EcdsaAddress - decider.UpdateParticipants(pubKeys) + decider.UpdateParticipants(pubKeys, []bls.PublicKeyWrapper{}) decider.SetVoters(&shard.Committee{ ShardID: shard.BeaconChainShardID, Slots: slotList, }, big.NewInt(3)) @@ -410,7 +411,7 @@ func TestAddNewVoteInvalidAggregateSig(test *testing.T) { slotList[5].EcdsaAddress = slotList[7].EcdsaAddress slotList[6].EcdsaAddress = slotList[7].EcdsaAddress - decider.UpdateParticipants(pubKeys) + decider.UpdateParticipants(pubKeys, []bls.PublicKeyWrapper{}) decider.SetVoters(&shard.Committee{ ShardID: shard.BeaconChainShardID, Slots: slotList, }, big.NewInt(3)) @@ -547,3 +548,48 @@ func TestInvalidAggregateSig(test *testing.T) { test.Error("Expect aggregate signature verification to succeed with correctly matched keys and sigs") } } + +func TestNthNextHmyExt(test *testing.T) { + numHmyNodes := 10 + numAllExtNodes := 10 + numAllowlistExtNodes := numAllExtNodes / 2 + allowlist := shardingconfig.Allowlist{MaxLimitPerShard: numAllowlistExtNodes - 1} + blsKeys := []harmony_bls.PublicKeyWrapper{} + for i := 0; i < numHmyNodes+numAllExtNodes; i++ { + blsKey := harmony_bls.RandPrivateKey() + wrapper := harmony_bls.PublicKeyWrapper{Object: blsKey.GetPublicKey()} + wrapper.Bytes.FromLibBLSPublicKey(wrapper.Object) + blsKeys = append(blsKeys, wrapper) + } + allowlistLeaders := blsKeys[len(blsKeys)-allowlist.MaxLimitPerShard:] + allLeaders := append(blsKeys[:numHmyNodes], allowlistLeaders...) + + decider := NewDecider(SuperMajorityVote, shard.BeaconChainShardID) + fakeInstance := shardingconfig.MustNewInstance(2, 20, numHmyNodes, 0, numeric.OneDec(), nil, nil, allowlist, nil, 0) + + decider.UpdateParticipants(blsKeys, allowlistLeaders) + for i := 0; i < len(allLeaders); i++ { + leader := allLeaders[i] + for j := 0; j < len(allLeaders)*2; j++ { + expectNextLeader := allLeaders[(i+j)%len(allLeaders)] + found, nextLeader := decider.NthNextHmyExt(fakeInstance, &leader, j) + if !found { + test.Fatal("next leader not found") + } + if expectNextLeader.Bytes != nextLeader.Bytes { + test.Fatal("next leader is not expected") + } + + preJ := -j + preIndex := (i + len(allLeaders) + preJ%len(allLeaders)) % len(allLeaders) + expectPreLeader := allLeaders[preIndex] + found, preLeader := decider.NthNextHmyExt(fakeInstance, &leader, preJ) + if !found { + test.Fatal("previous leader not found") + } + if expectPreLeader.Bytes != preLeader.Bytes { + test.Fatal("previous leader is not expected") + } + } + } +} diff --git a/consensus/quorum/quorum.go b/consensus/quorum/quorum.go index a341a77ad..ebb3bb17f 100644 --- a/consensus/quorum/quorum.go +++ b/consensus/quorum/quorum.go @@ -3,6 +3,7 @@ package quorum import ( "fmt" "math/big" + "sort" "github.com/harmony-one/harmony/crypto/bls" @@ -75,8 +76,9 @@ type ParticipantTracker interface { ParticipantsCount() int64 NthNext(*bls.PublicKeyWrapper, int) (bool, *bls.PublicKeyWrapper) NthNextHmy(shardingconfig.Instance, *bls.PublicKeyWrapper, int) (bool, *bls.PublicKeyWrapper) + NthNextHmyExt(shardingconfig.Instance, *bls.PublicKeyWrapper, int) (bool, *bls.PublicKeyWrapper) FirstParticipant(shardingconfig.Instance) *bls.PublicKeyWrapper - UpdateParticipants(pubKeys []bls.PublicKeyWrapper) + UpdateParticipants(pubKeys, allowlist []bls.PublicKeyWrapper) } // SignatoryTracker .. @@ -160,8 +162,10 @@ type cIdentities struct { // Public keys of the committee including leader and validators publicKeys []bls.PublicKeyWrapper keyIndexMap map[bls.SerializedPublicKey]int - prepare *votepower.Round - commit *votepower.Round + // every element is a index of publickKeys + allowlistIndex []int + prepare *votepower.Round + commit *votepower.Round // viewIDSigs: every validator // sign on |viewID|blockHash| in view changing message viewChange *votepower.Round @@ -246,6 +250,41 @@ func (s *cIdentities) NthNextHmy(instance shardingconfig.Instance, pubKey *bls.P return found, &s.publicKeys[idx] } +// NthNextHmyExt return the Nth next pubkey of Harmony + allowlist nodes, next can be negative number +func (s *cIdentities) NthNextHmyExt(instance shardingconfig.Instance, pubKey *bls.PublicKeyWrapper, next int) (bool, *bls.PublicKeyWrapper) { + found := false + + idx := s.IndexOf(pubKey.Bytes) + if idx != -1 { + found = true + } + numHmyNodes := instance.NumHarmonyOperatedNodesPerShard() + // sanity check to avoid out of bound access + if numHmyNodes <= 0 || numHmyNodes > len(s.publicKeys) { + numHmyNodes = len(s.publicKeys) + } + nth := idx + if idx >= numHmyNodes { + nth = sort.SearchInts(s.allowlistIndex, idx) + numHmyNodes + } + + numExtNodes := instance.ExternalAllowlistLimit() + if numExtNodes > len(s.allowlistIndex) { + numExtNodes = len(s.allowlistIndex) + } + + totalNodes := numHmyNodes + numExtNodes + // (totalNodes + next%totalNodes) can convert negitive 'next' to positive + nth = (nth + totalNodes + next%totalNodes) % totalNodes + if nth < numHmyNodes { + idx = nth + } else { + // find index of external slot key + idx = s.allowlistIndex[nth-numHmyNodes] + } + return found, &s.publicKeys[idx] +} + // FirstParticipant returns the first participant of the shard func (s *cIdentities) FirstParticipant(instance shardingconfig.Instance) *bls.PublicKeyWrapper { return &s.publicKeys[0] @@ -255,11 +294,17 @@ func (s *cIdentities) Participants() multibls.PublicKeys { return s.publicKeys } -func (s *cIdentities) UpdateParticipants(pubKeys []bls.PublicKeyWrapper) { +func (s *cIdentities) UpdateParticipants(pubKeys, allowlist []bls.PublicKeyWrapper) { keyIndexMap := map[bls.SerializedPublicKey]int{} for i := range pubKeys { keyIndexMap[pubKeys[i].Bytes] = i } + for _, key := range allowlist { + if i, exist := keyIndexMap[key.Bytes]; exist { + s.allowlistIndex = append(s.allowlistIndex, i) + } + } + sort.Ints(s.allowlistIndex) s.publicKeys = pubKeys s.keyIndexMap = keyIndexMap } diff --git a/consensus/view_change.go b/consensus/view_change.go index 04a8e731a..580e330b8 100644 --- a/consensus/view_change.go +++ b/consensus/view_change.go @@ -213,10 +213,19 @@ func (consensus *Consensus) getNextLeaderKey(viewID uint64) *bls.PublicKeyWrappe Msg("[getNextLeaderKey] got leaderPubKey from coinbase") // wasFound, next := consensus.Decider.NthNext(lastLeaderPubKey, gap) // FIXME: rotate leader on harmony nodes only before fully externalization - wasFound, next := consensus.Decider.NthNextHmy( - shard.Schedule.InstanceForEpoch(epoch), - lastLeaderPubKey, - gap) + var wasFound bool + var next *bls.PublicKeyWrapper + if consensus.Blockchain != nil && consensus.Blockchain.Config().IsAllowlistEpoch(epoch) { + wasFound, next = consensus.Decider.NthNextHmyExt( + shard.Schedule.InstanceForEpoch(epoch), + lastLeaderPubKey, + gap) + } else { + wasFound, next = consensus.Decider.NthNextHmy( + shard.Schedule.InstanceForEpoch(epoch), + lastLeaderPubKey, + gap) + } if !wasFound { consensus.getLogger().Warn(). Str("key", consensus.LeaderPubKey.Bytes.Hex()). diff --git a/consensus/view_change_test.go b/consensus/view_change_test.go index 50416be07..20bf54f9e 100644 --- a/consensus/view_change_test.go +++ b/consensus/view_change_test.go @@ -111,7 +111,7 @@ func TestGetNextLeaderKeyShouldSucceed(t *testing.T) { wrappedBLSKeys = append(wrappedBLSKeys, wrapped) } - consensus.Decider.UpdateParticipants(wrappedBLSKeys) + consensus.Decider.UpdateParticipants(wrappedBLSKeys, []bls.PublicKeyWrapper{}) assert.Equal(t, keyCount, consensus.Decider.ParticipantsCount()) consensus.LeaderPubKey = &wrappedBLSKeys[0] diff --git a/crypto/bls/bls.go b/crypto/bls/bls.go index 2c84e0fc7..54916278b 100644 --- a/crypto/bls/bls.go +++ b/crypto/bls/bls.go @@ -45,6 +45,19 @@ func WrapperFromPrivateKey(pri *bls.SecretKey) PrivateKeyWrapper { } } +// WrapperPublicKeyFromString makes a PublicKeyWrapper from public key hex string +func WrapperPublicKeyFromString(pubkey string) (*PublicKeyWrapper, error) { + pub := &bls.PublicKey{} + if err := pub.DeserializeHexStr(pubkey); err != nil { + return nil, err + } + pubBytes := FromLibBLSPublicKeyUnsafe(pub) + return &PublicKeyWrapper{ + Bytes: *pubBytes, + Object: pub, + }, nil +} + // SerializedPublicKey defines the serialized bls public key type SerializedPublicKey [PublicKeySizeInBytes]byte diff --git a/internal/configs/sharding/allowlist.go b/internal/configs/sharding/allowlist.go new file mode 100644 index 000000000..a88b98272 --- /dev/null +++ b/internal/configs/sharding/allowlist.go @@ -0,0 +1,49 @@ +package shardingconfig + +import ( + "fmt" + + bls_cosi "github.com/harmony-one/harmony/crypto/bls" +) + +type Allowlist struct { + MaxLimitPerShard int + BLSPublicKeys []bls_cosi.PublicKeyWrapper +} + +func BLS(pubkeys []string) []bls_cosi.PublicKeyWrapper { + blsPubkeys := make([]bls_cosi.PublicKeyWrapper, len(pubkeys)) + for i := range pubkeys { + if key, err := bls_cosi.WrapperPublicKeyFromString(pubkeys[i]); err != nil { + panic(fmt.Sprintf("invalid bls key: %d:%s error:%s", i, pubkeys[i], err.Error())) + } else { + blsPubkeys[i] = *key + } + } + return blsPubkeys +} + +// each time to update the allowlist, it requires a hardfork. +// keep same version of mainnet Instance +var mainnetAllowlisV3_TBD = Allowlist{ + MaxLimitPerShard: 0, + BLSPublicKeys: BLS([]string{}), +} + +// keep same version of testnet Instance +var testnetAllowlistV3_3 = Allowlist{ + MaxLimitPerShard: 4, + BLSPublicKeys: BLS([]string{ + "7915b9cbae9d675af510cb252362b80ae6d68a3684bbea203bc30d2f5fda25ffcedfa3cf2a6c1d3051469379920a418d", + "cf8dad79f5da460462b190a4996f1701589139aa0d8a2202bdd10004ad3b0d9299165278f8002bcb49599444b3607802", + "a7b563a180629a121a3f78d2864b3d5c5b76d1672a3f9de9349fde9c7a3dad0922bf9a4e68cb38d033d6a9ddef754709", + "0a62ca435c5e48983b6124768b383d3f0b2d358326604aec692189c7833f4a52dff865c1515c32f315eb8e78eaceec11", + }), +} + +var localnetAllowlist = Allowlist{ + MaxLimitPerShard: 0, + BLSPublicKeys: BLS([]string{}), +} + +var emptyAllowlist = Allowlist{} diff --git a/internal/configs/sharding/instance.go b/internal/configs/sharding/instance.go index 2a065353c..3c8304762 100644 --- a/internal/configs/sharding/instance.go +++ b/internal/configs/sharding/instance.go @@ -3,6 +3,7 @@ package shardingconfig import ( "math/big" + "github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/internal/genesis" "github.com/harmony-one/harmony/numeric" "github.com/pkg/errors" @@ -33,6 +34,7 @@ type instance struct { reshardingEpoch []*big.Int blocksPerEpoch uint64 slotsLimit int // HIP-16: The absolute number of maximum effective slots per shard limit for each validator. 0 means no limit. + allowlist Allowlist } // NewInstance creates and validates a new sharding configuration based @@ -41,6 +43,7 @@ func NewInstance( numShards uint32, numNodesPerShard, numHarmonyOperatedNodesPerShard, slotsLimit int, harmonyVotePercent numeric.Dec, hmyAccounts []genesis.DeployAccount, fnAccounts []genesis.DeployAccount, + allowlist Allowlist, reshardingEpoch []*big.Int, blocksE uint64, ) (Instance, error) { if numShards < 1 { @@ -84,6 +87,7 @@ func NewInstance( externalVotePercent: numeric.OneDec().Sub(harmonyVotePercent), hmyAccounts: hmyAccounts, fnAccounts: fnAccounts, + allowlist: allowlist, reshardingEpoch: reshardingEpoch, blocksPerEpoch: blocksE, slotsLimit: slotsLimit, @@ -99,12 +103,13 @@ func MustNewInstance( harmonyVotePercent numeric.Dec, hmyAccounts []genesis.DeployAccount, fnAccounts []genesis.DeployAccount, + allowlist Allowlist, reshardingEpoch []*big.Int, blocksPerEpoch uint64, ) Instance { slotsLimit := int(float32(numNodesPerShard-numHarmonyOperatedNodesPerShard) * slotsLimitPercent) sc, err := NewInstance( numShards, numNodesPerShard, numHarmonyOperatedNodesPerShard, slotsLimit, harmonyVotePercent, - hmyAccounts, fnAccounts, reshardingEpoch, blocksPerEpoch, + hmyAccounts, fnAccounts, allowlist, reshardingEpoch, blocksPerEpoch, ) if err != nil { panic(err) @@ -185,3 +190,13 @@ func (sc instance) ReshardingEpoch() []*big.Int { func (sc instance) GetNetworkID() NetworkID { return DevNet } + +// ExternalAllowlist returns the list of external leader keys in allowlist(HIP18) +func (sc instance) ExternalAllowlist() []bls.PublicKeyWrapper { + return sc.allowlist.BLSPublicKeys +} + +// ExternalAllowlistLimit returns the maximum number of external leader keys on each shard +func (sc instance) ExternalAllowlistLimit() int { + return sc.allowlist.MaxLimitPerShard +} diff --git a/internal/configs/sharding/localnet.go b/internal/configs/sharding/localnet.go index 1437b5db6..374e69bd7 100644 --- a/internal/configs/sharding/localnet.go +++ b/internal/configs/sharding/localnet.go @@ -142,9 +142,9 @@ var ( big.NewInt(0), big.NewInt(localnetV1Epoch), params.LocalnetChainConfig.StakingEpoch, params.LocalnetChainConfig.TwoSecondsEpoch, } // Number of shards, how many slots on each , how many slots owned by Harmony - localnetV0 = MustNewInstance(2, 7, 5, 0, numeric.OneDec(), genesis.LocalHarmonyAccounts, genesis.LocalFnAccounts, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld()) - localnetV1 = MustNewInstance(2, 8, 5, 0, numeric.OneDec(), genesis.LocalHarmonyAccountsV1, genesis.LocalFnAccountsV1, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld()) - localnetV2 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld()) - localnetV3 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch()) - localnetV3_1 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch()) + localnetV0 = MustNewInstance(2, 7, 5, 0, numeric.OneDec(), genesis.LocalHarmonyAccounts, genesis.LocalFnAccounts, emptyAllowlist, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld()) + localnetV1 = MustNewInstance(2, 8, 5, 0, numeric.OneDec(), genesis.LocalHarmonyAccountsV1, genesis.LocalFnAccountsV1, emptyAllowlist, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld()) + localnetV2 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, emptyAllowlist, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld()) + localnetV3 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, emptyAllowlist, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch()) + localnetV3_1 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, emptyAllowlist, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch()) ) diff --git a/internal/configs/sharding/mainnet.go b/internal/configs/sharding/mainnet.go index 881487283..43fe90e71 100644 --- a/internal/configs/sharding/mainnet.go +++ b/internal/configs/sharding/mainnet.go @@ -204,22 +204,22 @@ func (ms mainnetSchedule) IsSkippedEpoch(shardID uint32, epoch *big.Int) bool { var mainnetReshardingEpoch = []*big.Int{big.NewInt(0), big.NewInt(mainnetV0_1Epoch), big.NewInt(mainnetV0_2Epoch), big.NewInt(mainnetV0_3Epoch), big.NewInt(mainnetV0_4Epoch), big.NewInt(mainnetV1Epoch), big.NewInt(mainnetV1_1Epoch), big.NewInt(mainnetV1_2Epoch), big.NewInt(mainnetV1_3Epoch), big.NewInt(mainnetV1_4Epoch), big.NewInt(mainnetV1_5Epoch), big.NewInt(mainnetV2_0Epoch), big.NewInt(mainnetV2_1Epoch), big.NewInt(mainnetV2_2Epoch), params.MainnetChainConfig.TwoSecondsEpoch, params.MainnetChainConfig.SixtyPercentEpoch, params.MainnetChainConfig.HIP6And8Epoch} var ( - mainnetV0 = MustNewInstance(4, 150, 112, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccounts, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV0_1 = MustNewInstance(4, 152, 112, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_1, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV0_2 = MustNewInstance(4, 200, 148, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_2, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV0_3 = MustNewInstance(4, 210, 148, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_3, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV0_4 = MustNewInstance(4, 216, 148, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_4, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_1 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_1, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_2 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_2, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_3 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_3, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_4 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_4, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_5 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV2_0 = MustNewInstance(4, 250, 170, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV2_1 = MustNewInstance(4, 250, 130, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV2_2 = MustNewInstance(4, 250, 90, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV3 = MustNewInstance(4, 250, 90, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) - mainnetV3_1 = MustNewInstance(4, 250, 50, 0, numeric.MustNewDecFromStr("0.60"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) - mainnetV3_2 = MustNewInstance(4, 250, 25, 0, numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) - mainnetV3_3 = MustNewInstance(4, 250, 25, 0.06, numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) + mainnetV0 = MustNewInstance(4, 150, 112, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccounts, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV0_1 = MustNewInstance(4, 152, 112, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_1, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV0_2 = MustNewInstance(4, 200, 148, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_2, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV0_3 = MustNewInstance(4, 210, 148, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_3, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV0_4 = MustNewInstance(4, 216, 148, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_4, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV1 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV1_1 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_1, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV1_2 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_2, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV1_3 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_3, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV1_4 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_4, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV1_5 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV2_0 = MustNewInstance(4, 250, 170, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV2_1 = MustNewInstance(4, 250, 130, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV2_2 = MustNewInstance(4, 250, 90, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) + mainnetV3 = MustNewInstance(4, 250, 90, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) + mainnetV3_1 = MustNewInstance(4, 250, 50, 0, numeric.MustNewDecFromStr("0.60"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) + mainnetV3_2 = MustNewInstance(4, 250, 25, 0, numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) + mainnetV3_3 = MustNewInstance(4, 250, 25, 0.06, numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) ) diff --git a/internal/configs/sharding/pangaea.go b/internal/configs/sharding/pangaea.go index 730d6fc64..4c0fc48b2 100644 --- a/internal/configs/sharding/pangaea.go +++ b/internal/configs/sharding/pangaea.go @@ -75,5 +75,5 @@ var pangaeaReshardingEpoch = []*big.Int{ params.PangaeaChainConfig.StakingEpoch, } -var pangaeaV0 = MustNewInstance(4, 30, 30, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, pangaeaReshardingEpoch, PangaeaSchedule.BlocksPerEpoch()) -var pangaeaV1 = MustNewInstance(4, 110, 30, 0, numeric.MustNewDecFromStr("0.68"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, pangaeaReshardingEpoch, PangaeaSchedule.BlocksPerEpoch()) +var pangaeaV0 = MustNewInstance(4, 30, 30, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, pangaeaReshardingEpoch, PangaeaSchedule.BlocksPerEpoch()) +var pangaeaV1 = MustNewInstance(4, 110, 30, 0, numeric.MustNewDecFromStr("0.68"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, pangaeaReshardingEpoch, PangaeaSchedule.BlocksPerEpoch()) diff --git a/internal/configs/sharding/partner.go b/internal/configs/sharding/partner.go index 2a2d1501b..a5e1a14e8 100644 --- a/internal/configs/sharding/partner.go +++ b/internal/configs/sharding/partner.go @@ -76,5 +76,5 @@ var partnerReshardingEpoch = []*big.Int{ params.PartnerChainConfig.StakingEpoch, } -var partnerV0 = MustNewInstance(2, 5, 5, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch()) -var partnerV1 = MustNewInstance(2, 5, 4, 0, numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch()) +var partnerV0 = MustNewInstance(2, 5, 5, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch()) +var partnerV1 = MustNewInstance(2, 5, 4, 0, numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch()) diff --git a/internal/configs/sharding/shardingconfig.go b/internal/configs/sharding/shardingconfig.go index 6087f7cdd..1825452b2 100644 --- a/internal/configs/sharding/shardingconfig.go +++ b/internal/configs/sharding/shardingconfig.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" + "github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/internal/genesis" @@ -74,6 +75,12 @@ type Instance interface { BlocksPerEpoch() uint64 // HIP-16: The absolute number of maximum effective slots per shard limit for each validator. 0 means no limit. SlotsLimit() int + + // ExternalAllowlist returns the list of external leader keys in allowlist(HIP18) + ExternalAllowlist() []bls.PublicKeyWrapper + + // ExternalAllowlistLimit returns the maximum number of external leader keys on each shard(HIP18) + ExternalAllowlistLimit() int } // genShardingStructure return sharding structure, given shard number and its patterns. diff --git a/internal/configs/sharding/stress.go b/internal/configs/sharding/stress.go index 42bce4c41..ea6ba2966 100644 --- a/internal/configs/sharding/stress.go +++ b/internal/configs/sharding/stress.go @@ -78,6 +78,6 @@ var stressnetReshardingEpoch = []*big.Int{ params.StressnetChainConfig.StakingEpoch, } -var stressnetV0 = MustNewInstance(2, 10, 10, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch()) -var stressnetV1 = MustNewInstance(2, 30, 10, 0, numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch()) -var stressnetV2 = MustNewInstance(2, 30, 10, 0, numeric.MustNewDecFromStr("0.6"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch()) +var stressnetV0 = MustNewInstance(2, 10, 10, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch()) +var stressnetV1 = MustNewInstance(2, 30, 10, 0, numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch()) +var stressnetV2 = MustNewInstance(2, 30, 10, 0, numeric.MustNewDecFromStr("0.6"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch()) diff --git a/internal/configs/sharding/testnet.go b/internal/configs/sharding/testnet.go index ad8b2433e..370c7ba06 100644 --- a/internal/configs/sharding/testnet.go +++ b/internal/configs/sharding/testnet.go @@ -33,6 +33,8 @@ const ( func (ts testnetSchedule) InstanceForEpoch(epoch *big.Int) Instance { switch { + case params.TestnetChainConfig.IsAllowlistEpoch(epoch): + return testnetV3_3 case params.TestnetChainConfig.IsSlotsLimited(epoch): return testnetV3_2 case params.TestnetChainConfig.IsSixtyPercent(epoch): @@ -116,9 +118,10 @@ var testnetReshardingEpoch = []*big.Int{ params.TestnetChainConfig.TwoSecondsEpoch, } -var testnetV0 = MustNewInstance(4, 16, 15, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpochOld()) -var testnetV1 = MustNewInstance(4, 20, 15, 0, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpochOld()) -var testnetV2 = MustNewInstance(4, 30, 8, 0, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpochOld()) -var testnetV3 = MustNewInstance(4, 30, 8, 0, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) -var testnetV3_1 = MustNewInstance(4, 30, 8, 0, numeric.MustNewDecFromStr("0.60"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) -var testnetV3_2 = MustNewInstance(4, 30, 8, 0.15, numeric.MustNewDecFromStr("0.60"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) +var testnetV0 = MustNewInstance(4, 16, 15, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpochOld()) +var testnetV1 = MustNewInstance(4, 20, 15, 0, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpochOld()) +var testnetV2 = MustNewInstance(4, 30, 8, 0, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpochOld()) +var testnetV3 = MustNewInstance(4, 30, 8, 0, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) +var testnetV3_1 = MustNewInstance(4, 30, 8, 0, numeric.MustNewDecFromStr("0.60"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) +var testnetV3_2 = MustNewInstance(4, 30, 8, 0.15, numeric.MustNewDecFromStr("0.60"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) +var testnetV3_3 = MustNewInstance(4, 30, 8, 0.15, numeric.MustNewDecFromStr("0.60"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, testnetAllowlistV3_3, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) diff --git a/internal/params/config.go b/internal/params/config.go index 3ca7697af..6740df069 100644 --- a/internal/params/config.go +++ b/internal/params/config.go @@ -67,6 +67,7 @@ var ( StakingPrecompileEpoch: big.NewInt(871), // Around Tue Feb 11 2022 ChainIdFixEpoch: EpochTBD, SlotsLimitedEpoch: big.NewInt(999), // Around Fri, 27 May 2022 09:41:02 UTC with 2s block time + AllowlistEpoch: EpochTBD, } // TestnetChainConfig contains the chain parameters to run a node on the harmony test network. @@ -102,6 +103,7 @@ var ( StakingPrecompileEpoch: big.NewInt(75175), ChainIdFixEpoch: EpochTBD, SlotsLimitedEpoch: big.NewInt(75684), // epoch to enable HIP-16, around Mon, 02 May 2022 08:18:45 UTC with 2s block time + AllowlistEpoch: big.NewInt(75877), // around Fri, 10 Jun 2022 06:10:18 GMT with average block time 2.0065s } // PangaeaChainConfig contains the chain parameters for the Pangaea network. @@ -282,6 +284,7 @@ var ( big.NewInt(0), // StakingPrecompileEpoch big.NewInt(0), // ChainIdFixEpoch big.NewInt(0), // SlotsLimitedEpoch + big.NewInt(0), // AllowlistEpoch } // TestChainConfig ... @@ -319,6 +322,7 @@ var ( big.NewInt(0), // StakingPrecompileEpoch big.NewInt(0), // ChainIdFixEpoch big.NewInt(0), // SlotsLimitedEpoch + big.NewInt(0), // AllowlistEpoch } // TestRules ... @@ -442,6 +446,8 @@ type ChainConfig struct { // SlotsLimitedEpoch is the first epoch to enable HIP-16. SlotsLimitedEpoch *big.Int `json:"slots-limit-epoch,omitempty"` + // AllowlistEpoch is the first epoch to support allowlist of HIP18 + AllowlistEpoch *big.Int } // String implements the fmt.Stringer interface. @@ -613,6 +619,11 @@ func (c *ChainConfig) IsChainIdFixEpoch(epoch *big.Int) bool { return isForked(c.ChainIdFixEpoch, epoch) } +// IsAllowlistEpoch determines whether IsAllowlist of HIP18 is enabled +func (c *ChainConfig) IsAllowlistEpoch(epoch *big.Int) bool { + return isForked(c.AllowlistEpoch, epoch) +} + // UpdateEthChainIDByShard update the ethChainID based on shard ID. func UpdateEthChainIDByShard(shardID uint32) { once.Do(func() { diff --git a/node/node.go b/node/node.go index 0997ce5a6..99a7ce318 100644 --- a/node/node.go +++ b/node/node.go @@ -1170,7 +1170,7 @@ func (node *Node) InitConsensusWithValidators() (err error) { Int("numPubKeys", len(pubKeys)). Str("mode", node.Consensus.Mode().String()). Msg("[InitConsensusWithValidators] Successfully updated public keys") - node.Consensus.UpdatePublicKeys(pubKeys) + node.Consensus.UpdatePublicKeys(pubKeys, shard.Schedule.InstanceForEpoch(epoch).ExternalAllowlist()) node.Consensus.SetMode(consensus.Normal) return nil } diff --git a/scripts/travis_rpc_checker.sh b/scripts/travis_rpc_checker.sh index 23aedb528..6f0529bdb 100755 --- a/scripts/travis_rpc_checker.sh +++ b/scripts/travis_rpc_checker.sh @@ -5,7 +5,7 @@ CACHE_DIR="docker_images" mkdir -p $CACHE_DIR echo "pulling cached docker img" docker load -i $CACHE_DIR/images.tar || true -#docker pull harmonyone/localnet-test +docker pull harmonyone/localnet-test echo "saving cached docker img" docker save -o $CACHE_DIR/images.tar harmonyone/localnet-test docker run -v "$DIR/../:/go/src/github.com/harmony-one/harmony" harmonyone/localnet-test -n \ No newline at end of file