Rotation fix and update. (#4516)

* fixed memory

* error on existed block

* Fixed config to pass tests.

* Cleanup

* Cleanup

* Condition to pass tests.
pull/4500/head
Konstantin 1 year ago committed by GitHub
parent 9f5768a799
commit 163365625c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      Makefile
  2. 8
      consensus/consensus_service.go
  3. 17
      consensus/consensus_service_test.go
  4. 36
      consensus/consensus_v2.go
  5. 4
      consensus/view_change.go
  6. 4
      core/blockchain.go
  7. 89
      core/blockchain_impl.go
  8. 129
      core/blockchain_leader_rotation.go
  9. 57
      core/blockchain_leader_rotation_test.go
  10. 4
      core/blockchain_stub.go
  11. 5
      core_test/shardchain_test.go
  12. 5
      crypto/bls/bls.go
  13. 486
      internal/params/config.go
  14. 2
      node/node_newblock.go
  15. 6
      test/build-localnet-validator.sh

@ -171,3 +171,12 @@ travis_go_checker:
travis_rpc_checker:
bash ./scripts/travis_rpc_checker.sh
travis_rosetta_checker:
bash ./scripts/travis_rosetta_checker.sh
debug_external: clean
bash test/debug-external.sh
build_localnet_validator:
bash test/build-localnet-validator.sh

@ -663,6 +663,12 @@ func (consensus *Consensus) getLogger() *zerolog.Logger {
func VerifyNewBlock(hooks *webhooks.Hooks, blockChain core.BlockChain, beaconChain core.BlockChain) func(*types.Block) error {
return func(newBlock *types.Block) error {
if err := blockChain.ValidateNewBlock(newBlock, beaconChain); err != nil {
switch {
case errors.Is(err, core.ErrKnownBlock):
return nil
default:
}
if hooks := hooks; hooks != nil {
if p := hooks.ProtocolIssues; p != nil {
url := p.OnCannotCommit
@ -680,7 +686,7 @@ func VerifyNewBlock(hooks *webhooks.Hooks, blockChain core.BlockChain, beaconCha
Int("numStakingTx", len(newBlock.StakingTransactions())).
Err(err).
Msgf("[VerifyNewBlock] Cannot Verify New Block!!!, blockHeight %d, myHeight %d", newBlock.NumberU64(), blockChain.CurrentHeader().NumberU64())
return errors.Errorf(
return errors.WithMessagef(err,
"[VerifyNewBlock] Cannot Verify New Block!!! block-hash %s txn-count %d",
newBlock.Hash().Hex(),
len(newBlock.Transactions()),

@ -5,6 +5,8 @@ import (
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/registry"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/consensus/quorum"
@ -73,3 +75,18 @@ func TestSetViewID(t *testing.T) {
t.Errorf("Cannot set consensus ID. Got: %v, Expected: %v", consensus.GetCurBlockViewID(), height)
}
}
func TestErrors(t *testing.T) {
e1 := errors.New("e1")
require.True(t, errors.Is(e1, e1))
t.Run("wrap", func(t *testing.T) {
e2 := errors.Wrap(e1, "e2")
require.True(t, errors.Is(e2, e1))
})
t.Run("withMessage", func(t *testing.T) {
e2 := errors.WithMessage(e1, "e2")
require.True(t, errors.Is(e2, e1))
})
}

@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/common"
bls2 "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/consensus/signature"
"github.com/harmony-one/harmony/core"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils"
"github.com/rs/zerolog"
@ -31,7 +32,6 @@ import (
var (
errSenderPubKeyNotLeader = errors.New("sender pubkey doesn't match leader")
errVerifyMessageSignature = errors.New("verify message signature failed")
errParsingFBFTMessage = errors.New("failed parsing FBFT message")
)
// timeout constant
@ -578,8 +578,13 @@ func (consensus *Consensus) preCommitAndPropose(blk *types.Block) error {
}
if _, err := consensus.Blockchain().InsertChain([]*types.Block{blk}, !consensus.FBFTLog().IsBlockVerified(blk.Hash())); err != nil {
consensus.getLogger().Error().Err(err).Msg("[preCommitAndPropose] Failed to add block to chain")
return
switch {
case errors.Is(err, core.ErrKnownBlock):
consensus.getLogger().Info().Msg("[preCommitAndPropose] Block already known")
default:
consensus.getLogger().Error().Err(err).Msg("[preCommitAndPropose] Failed to add block to chain")
return
}
}
consensus.getLogger().Info().Msg("[preCommitAndPropose] Start consensus timer")
@ -693,7 +698,7 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) {
prev = consensus.getLeaderPubKey()
leader = consensus.getLeaderPubKey()
)
utils.Logger().Info().Msgf("[Rotating leader] epoch: %v rotation:%v external rotation %v", epoch.Uint64(), bc.Config().IsLeaderRotation(epoch), bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch, consensus.ShardID))
utils.Logger().Info().Msgf("[Rotating leader] epoch: %v rotation:%v external rotation %v", epoch.Uint64(), bc.Config().IsLeaderRotationInternalValidators(epoch), bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch))
ss, err := bc.ReadShardState(epoch)
if err != nil {
utils.Logger().Error().Err(err).Msg("Failed to read shard state")
@ -721,24 +726,17 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) {
// mine no less than 3 blocks in a row
numBlocksProducedByLeader = minimumBlocksForLeaderInRow
}
type stored struct {
pub []byte
epoch uint64
count uint64
shifts uint64 // count how much changes validator per epoch
}
var s stored
s.pub, s.epoch, s.count, s.shifts, _ = bc.LeaderRotationMeta()
if !bytes.Equal(leader.Bytes[:], s.pub) {
s := bc.LeaderRotationMeta()
if !bytes.Equal(leader.Bytes[:], s.Pub) {
// Another leader.
return
}
// if it is the first validator which produce blocks, then it should produce `rest` blocks too.
if s.shifts == 0 {
// If it is the first validator producing blocks, it should also produce the remaining 'rest' of the blocks.
if s.Shifts == 0 {
numBlocksProducedByLeader += rest
}
if s.count < numBlocksProducedByLeader {
// Not enough blocks produced by the leader.
if s.Count < numBlocksProducedByLeader {
// Not enough blocks produced by the leader, continue producing by the same leader.
return
}
// Passed all checks, we can change leader.
@ -748,7 +746,7 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) {
wasFound bool
next *bls.PublicKeyWrapper
)
if bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch, consensus.ShardID) {
if bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch) {
wasFound, next = consensus.Decider.NthNextValidator(committee.Slots, leader, 1)
} else {
wasFound, next = consensus.Decider.NthNextHmy(shard.Schedule.InstanceForEpoch(epoch), leader, 1)
@ -778,7 +776,7 @@ func (consensus *Consensus) setupForNewConsensus(blk *types.Block, committedMsg
} else {
epoch = blk.Epoch()
}
if consensus.Blockchain().Config().IsLeaderRotation(epoch) {
if consensus.Blockchain().Config().IsLeaderRotationInternalValidators(epoch) {
consensus.rotateLeader(epoch)
}

@ -202,8 +202,8 @@ func (consensus *Consensus) getNextLeaderKey(viewID uint64, committee *shard.Com
// FIXME: rotate leader on harmony nodes only before fully externalization
var wasFound bool
var next *bls.PublicKeyWrapper
if blockchain != nil && blockchain.Config().IsLeaderRotation(epoch) {
if blockchain.Config().IsLeaderRotationExternalValidatorsAllowed(epoch, consensus.ShardID) {
if blockchain != nil && blockchain.Config().IsLeaderRotationInternalValidators(epoch) {
if blockchain.Config().IsLeaderRotationExternalValidatorsAllowed(epoch) {
wasFound, next = consensus.Decider.NthNextValidator(
committee.Slots,
lastLeaderPubKey,

@ -121,8 +121,8 @@ type BlockChain interface {
//
// After insertion is done, all accumulated events will be fired.
InsertChain(chain types.Blocks, verifyHeaders bool) (int, error)
// LeaderRotationMeta returns the number of continuous blocks by the leader.
LeaderRotationMeta() (publicKeyBytes []byte, epoch, count, shifts uint64, err error)
// LeaderRotationMeta returns info about leader rotation.
LeaderRotationMeta() LeaderRotationMeta
// BadBlocks returns a list of the last 'bad blocks' that
// the client has seen on the network.
BadBlocks() []BadBlock

@ -90,7 +90,8 @@ var (
blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil)
// ErrNoGenesis is the error when there is no genesis.
ErrNoGenesis = errors.New("Genesis not found in chain")
ErrNoGenesis = errors.New("Genesis not found in chain")
ErrEmptyChain = errors.New("empty chain")
// errExceedMaxPendingSlashes ..
errExceedMaxPendingSlashes = errors.New("exceeed max pending slashes")
errNilEpoch = errors.New("nil epoch for voting power computation")
@ -222,7 +223,7 @@ type BlockChainImpl struct {
badBlocks *lru.Cache // Bad block cache
pendingSlashes slash.Records
maxGarbCollectedBlkNum int64
leaderRotationMeta leaderRotationMeta
leaderRotationMeta LeaderRotationMeta
options Options
}
@ -1632,9 +1633,20 @@ func (bc *BlockChainImpl) InsertChain(chain types.Blocks, verifyHeaders bool) (i
return len(chain), nil
}
for _, b := range chain {
// check if blocks already exist
if bc.HasBlock(b.Hash(), b.NumberU64()) {
return 0, errors.Wrapf(ErrKnownBlock, "block %s %d already exists", b.Hash().Hex(), b.NumberU64())
}
}
prevHash := bc.CurrentBlock().Hash()
n, events, logs, err := bc.insertChain(chain, verifyHeaders)
bc.PostChainEvents(events, logs)
if err == nil {
if prevHash == bc.CurrentBlock().Hash() {
panic("insertChain failed to update current block")
}
// there should be only 1 block.
for _, b := range chain {
if b.Epoch().Uint64() > 0 {
@ -1653,75 +1665,8 @@ func (bc *BlockChainImpl) InsertChain(chain types.Blocks, verifyHeaders bool) (i
return n, err
}
// buildLeaderRotationMeta builds leader rotation meta if feature is activated.
func (bc *BlockChainImpl) buildLeaderRotationMeta(curHeader *block.Header) error {
if !bc.chainConfig.IsLeaderRotation(curHeader.Epoch()) {
return nil
}
if curHeader.NumberU64() == 0 {
return errors.New("current header is genesis")
}
curPubKey, err := bc.getLeaderPubKeyFromCoinbase(curHeader)
if err != nil {
return err
}
for i := curHeader.NumberU64() - 1; i >= 0; i-- {
header := bc.GetHeaderByNumber(i)
if header == nil {
return errors.New("header is nil")
}
blockPubKey, err := bc.getLeaderPubKeyFromCoinbase(header)
if err != nil {
return err
}
if curPubKey.Bytes != blockPubKey.Bytes || curHeader.Epoch().Uint64() != header.Epoch().Uint64() {
for j := i; j <= curHeader.NumberU64(); j++ {
header := bc.GetHeaderByNumber(j)
if header == nil {
return errors.New("header is nil")
}
err := bc.saveLeaderRotationMeta(header)
if err != nil {
utils.Logger().Error().Err(err).Msg("save leader continuous blocks count error")
return err
}
}
return nil
}
}
return errors.New("no leader rotation meta to save")
}
func (bc *BlockChainImpl) saveLeaderRotationMeta(h *block.Header) error {
blockPubKey, err := bc.getLeaderPubKeyFromCoinbase(h)
if err != nil {
return err
}
var s = bc.leaderRotationMeta
// increase counter only if the same leader and epoch
if bytes.Equal(s.pub, blockPubKey.Bytes[:]) && s.epoch == h.Epoch().Uint64() {
s.count++
} else {
s.count = 1
}
// we should increase shifts if the leader is changed.
if !bytes.Equal(s.pub, blockPubKey.Bytes[:]) {
s.shifts++
}
// but set to zero if new
if s.epoch != h.Epoch().Uint64() {
s.shifts = 0
}
s.epoch = h.Epoch().Uint64()
bc.leaderRotationMeta = s
return nil
}
func (bc *BlockChainImpl) LeaderRotationMeta() (publicKeyBytes []byte, epoch, count, shifts uint64, err error) {
return rawdb.ReadLeaderRotationMeta(bc.db)
func (bc *BlockChainImpl) LeaderRotationMeta() LeaderRotationMeta {
return bc.leaderRotationMeta.Clone()
}
// insertChain will execute the actual chain insertion and event aggregation. The
@ -1730,7 +1675,7 @@ func (bc *BlockChainImpl) LeaderRotationMeta() (publicKeyBytes []byte, epoch, co
func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (int, []interface{}, []*types.Log, error) {
// Sanity check that we have something meaningful to import
if len(chain) == 0 {
return 0, nil, nil, nil
return 0, nil, nil, ErrEmptyChain
}
// Do a sanity check that the provided chain is actually ordered and linked
for i := 1; i < len(chain); i++ {

@ -1,8 +1,127 @@
package core
type leaderRotationMeta struct {
pub []byte
epoch uint64
count uint64
shifts uint64
import (
"bytes"
"hash/crc32"
"strconv"
"strings"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/utils"
"github.com/pkg/errors"
)
// LeaderRotationMeta contains information about leader rotation
type LeaderRotationMeta struct {
Pub []byte // bls public key of previous block miner
Epoch uint64 // epoch number of previously inserted block
Count uint64 // quantity of continuous blocks inserted by the same leader
Shifts uint64 // number of leader shifts, shift happens when leader changes
}
// ShortString returns string representation of the struct
func (a LeaderRotationMeta) ShortString() string {
s := strings.Builder{}
s.Write(a.Pub[3:])
s.WriteString(" ")
s.WriteString(strconv.FormatUint(a.Epoch, 10))
s.WriteString(" ")
s.WriteString(strconv.FormatUint(a.Count, 10))
s.WriteString(" ")
s.WriteString(strconv.FormatUint(a.Shifts, 10))
return s.String()
}
// Hash returns hash of the struct
func (a LeaderRotationMeta) Hash() []byte {
c := crc32.NewIEEE()
c.Write(a.Pub)
c.Write([]byte(strconv.FormatUint(a.Epoch, 10)))
c.Write([]byte(strconv.FormatUint(a.Count, 10)))
c.Write([]byte(strconv.FormatUint(a.Shifts, 10)))
return c.Sum(nil)
}
// Clone returns a copy of the struct
func (a LeaderRotationMeta) Clone() LeaderRotationMeta {
return LeaderRotationMeta{
Pub: append([]byte{}, a.Pub...),
Epoch: a.Epoch,
Count: a.Count,
Shifts: a.Shifts,
}
}
// buildLeaderRotationMeta builds leader rotation meta if feature is activated.
func (bc *BlockChainImpl) buildLeaderRotationMeta(curHeader *block.Header) error {
if !bc.chainConfig.IsLeaderRotationInternalValidators(curHeader.Epoch()) {
return nil
}
if curHeader.NumberU64() == 0 {
return errors.New("current header is genesis")
}
curPubKey, err := bc.getLeaderPubKeyFromCoinbase(curHeader)
if err != nil {
return err
}
for i := curHeader.NumberU64() - 1; i >= 0; i-- {
header := bc.GetHeaderByNumber(i)
if header == nil {
return errors.New("header is nil")
}
blockPubKey, err := bc.getLeaderPubKeyFromCoinbase(header)
if err != nil {
return err
}
if curPubKey.Bytes != blockPubKey.Bytes || curHeader.Epoch().Uint64() != header.Epoch().Uint64() {
for j := i; j <= curHeader.NumberU64(); j++ {
header := bc.GetHeaderByNumber(j)
if header == nil {
return errors.New("header is nil")
}
err := bc.saveLeaderRotationMeta(header)
if err != nil {
utils.Logger().Error().Err(err).Msg("save leader continuous blocks count error")
return err
}
}
return nil
}
}
return errors.New("no leader rotation meta to save")
}
// saveLeaderRotationMeta saves leader rotation meta if feature is activated.
func (bc *BlockChainImpl) saveLeaderRotationMeta(h *block.Header) error {
blockPubKey, err := bc.getLeaderPubKeyFromCoinbase(h)
if err != nil {
return err
}
bc.leaderRotationMeta = processRotationMeta(h.Epoch().Uint64(), blockPubKey.Bytes, bc.leaderRotationMeta)
return nil
}
func processRotationMeta(epoch uint64, blockPubKey bls.SerializedPublicKey, s LeaderRotationMeta) LeaderRotationMeta {
// increase counter only if the same leader and epoch
if bytes.Equal(s.Pub, blockPubKey[:]) && s.Epoch == epoch {
s.Count++
} else {
s.Count = 1
}
// we should increase shifts if the leader has changed.
if !bytes.Equal(s.Pub, blockPubKey[:]) {
s.Shifts++
}
// but set to zero if new
if s.Epoch != epoch {
s.Shifts = 0
}
s.Epoch = epoch
return LeaderRotationMeta{
Pub: blockPubKey[:],
Epoch: s.Epoch,
Count: s.Count,
Shifts: s.Shifts,
}
}

@ -0,0 +1,57 @@
package core
import (
"testing"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/stretchr/testify/require"
)
var k1 = bls.SerializedPublicKey{1, 2, 3}
func TestRotationMetaProcess(t *testing.T) {
t.Run("same_leader_increase_count", func(t *testing.T) {
rs := processRotationMeta(1, bls.SerializedPublicKey{}, LeaderRotationMeta{
Pub: bls.SerializedPublicKey{}.Bytes(),
Epoch: 1,
Count: 1,
Shifts: 1,
})
require.Equal(t, LeaderRotationMeta{
Pub: bls.SerializedPublicKey{}.Bytes(),
Epoch: 1,
Count: 2,
Shifts: 1,
}, rs)
})
t.Run("new_leader_increase_shifts", func(t *testing.T) {
rs := processRotationMeta(1, k1, LeaderRotationMeta{
Pub: bls.SerializedPublicKey{}.Bytes(),
Epoch: 1,
Count: 1,
Shifts: 1,
})
require.Equal(t, LeaderRotationMeta{
Pub: k1.Bytes(),
Epoch: 1,
Count: 1,
Shifts: 2,
}, rs)
})
t.Run("new_epoch_reset_count", func(t *testing.T) {
rs := processRotationMeta(2, k1, LeaderRotationMeta{
Pub: bls.SerializedPublicKey{}.Bytes(),
Epoch: 1,
Count: 1,
Shifts: 1,
})
require.Equal(t, LeaderRotationMeta{
Pub: k1.Bytes(),
Epoch: 2,
Count: 1,
Shifts: 0,
}, rs)
})
}

@ -438,8 +438,8 @@ func (a Stub) InitTiKV(conf *harmonyconfig.TiKVConfig) {
return
}
func (a Stub) LeaderRotationMeta() (publicKeyBytes []byte, epoch, count, shifts uint64, err error) {
return nil, 0, 0, 0, errors.Errorf("method LeaderRotationMeta not implemented for %s", a.Name)
func (a Stub) LeaderRotationMeta() LeaderRotationMeta {
return LeaderRotationMeta{}
}
func (a Stub) CommitPreimages() error {

@ -1,7 +1,6 @@
package core_test
import (
"fmt"
"testing"
"github.com/ethereum/go-ethereum/common"
@ -76,8 +75,8 @@ func TestAddNewBlock(t *testing.T) {
_, err = blockchain.InsertChain([]*types.Block{block}, false)
require.NoError(t, err, "error when adding new block")
pk, epoch, count, shifts, err := blockchain.LeaderRotationMeta()
fmt.Println("pk", pk, "epoch", epoch, "count", count, "shifts", shifts, "err", err)
meta := blockchain.LeaderRotationMeta()
require.NotEmptyf(t, meta, "error when getting leader rotation meta")
t.Log("#", block.Header().NumberU64(), node.Blockchain().CurrentBlock().NumberU64(), block.Hash().Hex(), block.ParentHash())

@ -64,6 +64,11 @@ type SerializedPublicKey [PublicKeySizeInBytes]byte
// SerializedSignature defines the bls signature
type SerializedSignature [BLSSignatureSizeInBytes]byte
// Bytes returns the byte array of bls signature
func (pk SerializedPublicKey) Bytes() []byte {
return pk[:]
}
// Big ..
func (pk SerializedPublicKey) Big() *big.Int {
return new(big.Int).SetBytes(pk[:])

@ -36,262 +36,262 @@ var once sync.Once
var (
// MainnetChainConfig is the chain parameters to run a node on the main network.
MainnetChainConfig = &ChainConfig{
ChainID: MainnetChainID,
EthCompatibleChainID: EthMainnetShard0ChainID,
EthCompatibleShard0ChainID: EthMainnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(442), // Around Thursday Feb 4th 2020, 10AM PST
CrossTxEpoch: big.NewInt(28),
CrossLinkEpoch: big.NewInt(186),
AggregatedRewardEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time
StakingEpoch: big.NewInt(186),
PreStakingEpoch: big.NewInt(185),
QuickUnlockEpoch: big.NewInt(191),
FiveSecondsEpoch: big.NewInt(230),
TwoSecondsEpoch: big.NewInt(366), // Around Tuesday Dec 8th 2020, 8AM PST
SixtyPercentEpoch: big.NewInt(530), // Around Monday Apr 12th 2021, 22:30 UTC
RedelegationEpoch: big.NewInt(290),
NoEarlyUnlockEpoch: big.NewInt(530), // Around Monday Apr 12th 2021, 22:30 UTC
VRFEpoch: big.NewInt(631), // Around Wed July 7th 2021
PrevVRFEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time
MinDelegation100Epoch: big.NewInt(631), // Around Wed July 7th 2021
MinCommissionRateEpoch: big.NewInt(631), // Around Wed July 7th 2021
MinCommissionPromoPeriod: big.NewInt(100),
EPoSBound35Epoch: big.NewInt(631), // Around Wed July 7th 2021
EIP155Epoch: big.NewInt(28),
S3Epoch: big.NewInt(28),
DataCopyFixEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time
IstanbulEpoch: big.NewInt(314),
ReceiptLogEpoch: big.NewInt(101),
SHA3Epoch: big.NewInt(725), // Around Mon Oct 11 2021, 19:00 UTC
HIP6And8Epoch: big.NewInt(725), // Around Mon Oct 11 2021, 19:00 UTC
StakingPrecompileEpoch: big.NewInt(871), // Around Tue Feb 11 2022
ChainIdFixEpoch: big.NewInt(1323), // Around Wed 8 Feb 11:30PM UTC
SlotsLimitedEpoch: big.NewInt(999), // Around Fri, 27 May 2022 09:41:02 UTC with 2s block time
CrossShardXferPrecompileEpoch: big.NewInt(1323), // Around Wed 8 Feb 11:30PM UTC
AllowlistEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD,
FeeCollectEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00
ValidatorCodeFixEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00
HIP30Epoch: big.NewInt(1673), // 2023-11-02 17:30:00+00:00
BlockGas30MEpoch: big.NewInt(1673), // 2023-11-02 17:30:00+00:00
ChainID: MainnetChainID,
EthCompatibleChainID: EthMainnetShard0ChainID,
EthCompatibleShard0ChainID: EthMainnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(442), // Around Thursday Feb 4th 2020, 10AM PST
CrossTxEpoch: big.NewInt(28),
CrossLinkEpoch: big.NewInt(186),
AggregatedRewardEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time
StakingEpoch: big.NewInt(186),
PreStakingEpoch: big.NewInt(185),
QuickUnlockEpoch: big.NewInt(191),
FiveSecondsEpoch: big.NewInt(230),
TwoSecondsEpoch: big.NewInt(366), // Around Tuesday Dec 8th 2020, 8AM PST
SixtyPercentEpoch: big.NewInt(530), // Around Monday Apr 12th 2021, 22:30 UTC
RedelegationEpoch: big.NewInt(290),
NoEarlyUnlockEpoch: big.NewInt(530), // Around Monday Apr 12th 2021, 22:30 UTC
VRFEpoch: big.NewInt(631), // Around Wed July 7th 2021
PrevVRFEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time
MinDelegation100Epoch: big.NewInt(631), // Around Wed July 7th 2021
MinCommissionRateEpoch: big.NewInt(631), // Around Wed July 7th 2021
MinCommissionPromoPeriod: big.NewInt(100),
EPoSBound35Epoch: big.NewInt(631), // Around Wed July 7th 2021
EIP155Epoch: big.NewInt(28),
S3Epoch: big.NewInt(28),
DataCopyFixEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time
IstanbulEpoch: big.NewInt(314),
ReceiptLogEpoch: big.NewInt(101),
SHA3Epoch: big.NewInt(725), // Around Mon Oct 11 2021, 19:00 UTC
HIP6And8Epoch: big.NewInt(725), // Around Mon Oct 11 2021, 19:00 UTC
StakingPrecompileEpoch: big.NewInt(871), // Around Tue Feb 11 2022
ChainIdFixEpoch: big.NewInt(1323), // Around Wed 8 Feb 11:30PM UTC
SlotsLimitedEpoch: big.NewInt(999), // Around Fri, 27 May 2022 09:41:02 UTC with 2s block time
CrossShardXferPrecompileEpoch: big.NewInt(1323), // Around Wed 8 Feb 11:30PM UTC
AllowlistEpoch: EpochTBD,
LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalValidatorsEpoch: EpochTBD,
FeeCollectEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00
ValidatorCodeFixEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00
HIP30Epoch: big.NewInt(1673), // 2023-11-02 17:30:00+00:00
BlockGas30MEpoch: big.NewInt(1673), // 2023-11-02 17:30:00+00:00
}
// TestnetChainConfig contains the chain parameters to run a node on the harmony test network.
TestnetChainConfig = &ChainConfig{
ChainID: TestnetChainID,
EthCompatibleChainID: EthTestnetShard0ChainID,
EthCompatibleShard0ChainID: EthTestnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(2),
SixtyPercentEpoch: big.NewInt(2),
RedelegationEpoch: big.NewInt(2),
NoEarlyUnlockEpoch: big.NewInt(2),
VRFEpoch: big.NewInt(2),
PrevVRFEpoch: big.NewInt(2),
MinDelegation100Epoch: big.NewInt(2),
MinCommissionRateEpoch: big.NewInt(2),
MinCommissionPromoPeriod: big.NewInt(2),
EPoSBound35Epoch: big.NewInt(2),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: big.NewInt(2),
StakingPrecompileEpoch: big.NewInt(2),
SlotsLimitedEpoch: big.NewInt(2),
ChainIdFixEpoch: big.NewInt(0),
CrossShardXferPrecompileEpoch: big.NewInt(2),
AllowlistEpoch: big.NewInt(2),
LeaderRotationExternalNonBeaconLeaders: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD,
FeeCollectEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00
ValidatorCodeFixEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00
HIP30Epoch: big.NewInt(2176), // 2023-10-12 10:00:00+00:00
BlockGas30MEpoch: big.NewInt(2176), // 2023-10-12 10:00:00+00:00
ChainID: TestnetChainID,
EthCompatibleChainID: EthTestnetShard0ChainID,
EthCompatibleShard0ChainID: EthTestnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(2),
SixtyPercentEpoch: big.NewInt(2),
RedelegationEpoch: big.NewInt(2),
NoEarlyUnlockEpoch: big.NewInt(2),
VRFEpoch: big.NewInt(2),
PrevVRFEpoch: big.NewInt(2),
MinDelegation100Epoch: big.NewInt(2),
MinCommissionRateEpoch: big.NewInt(2),
MinCommissionPromoPeriod: big.NewInt(2),
EPoSBound35Epoch: big.NewInt(2),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: big.NewInt(2),
StakingPrecompileEpoch: big.NewInt(2),
SlotsLimitedEpoch: big.NewInt(2),
ChainIdFixEpoch: big.NewInt(0),
CrossShardXferPrecompileEpoch: big.NewInt(2),
AllowlistEpoch: big.NewInt(2),
LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalValidatorsEpoch: EpochTBD,
FeeCollectEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00
ValidatorCodeFixEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00
HIP30Epoch: big.NewInt(2176), // 2023-10-12 10:00:00+00:00
BlockGas30MEpoch: big.NewInt(2176), // 2023-10-12 10:00:00+00:00
}
// PangaeaChainConfig contains the chain parameters for the Pangaea network.
// All features except for CrossLink are enabled at launch.
PangaeaChainConfig = &ChainConfig{
ChainID: PangaeaChainID,
EthCompatibleChainID: EthPangaeaShard0ChainID,
EthCompatibleShard0ChainID: EthPangaeaShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(3),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: big.NewInt(0),
RedelegationEpoch: big.NewInt(0),
NoEarlyUnlockEpoch: big.NewInt(0),
VRFEpoch: big.NewInt(0),
PrevVRFEpoch: big.NewInt(0),
MinDelegation100Epoch: big.NewInt(0),
MinCommissionRateEpoch: big.NewInt(0),
MinCommissionPromoPeriod: big.NewInt(10),
EPoSBound35Epoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: big.NewInt(0),
StakingPrecompileEpoch: big.NewInt(2), // same as staking
ChainIdFixEpoch: big.NewInt(0),
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(1),
AllowlistEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD,
FeeCollectEpoch: EpochTBD,
ValidatorCodeFixEpoch: EpochTBD,
HIP30Epoch: EpochTBD,
BlockGas30MEpoch: big.NewInt(0),
ChainID: PangaeaChainID,
EthCompatibleChainID: EthPangaeaShard0ChainID,
EthCompatibleShard0ChainID: EthPangaeaShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(3),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: big.NewInt(0),
RedelegationEpoch: big.NewInt(0),
NoEarlyUnlockEpoch: big.NewInt(0),
VRFEpoch: big.NewInt(0),
PrevVRFEpoch: big.NewInt(0),
MinDelegation100Epoch: big.NewInt(0),
MinCommissionRateEpoch: big.NewInt(0),
MinCommissionPromoPeriod: big.NewInt(10),
EPoSBound35Epoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: big.NewInt(0),
StakingPrecompileEpoch: big.NewInt(2), // same as staking
ChainIdFixEpoch: big.NewInt(0),
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(1),
AllowlistEpoch: EpochTBD,
LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalValidatorsEpoch: EpochTBD,
FeeCollectEpoch: EpochTBD,
ValidatorCodeFixEpoch: EpochTBD,
HIP30Epoch: EpochTBD,
BlockGas30MEpoch: big.NewInt(0),
}
// PartnerChainConfig contains the chain parameters for the Partner network.
// This is the Devnet config
PartnerChainConfig = &ChainConfig{
ChainID: PartnerChainID,
EthCompatibleChainID: EthPartnerShard0ChainID,
EthCompatibleShard0ChainID: EthPartnerShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(3),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: EpochTBD,
RedelegationEpoch: big.NewInt(0),
NoEarlyUnlockEpoch: big.NewInt(0),
VRFEpoch: big.NewInt(0),
PrevVRFEpoch: big.NewInt(0),
MinDelegation100Epoch: big.NewInt(0),
MinCommissionRateEpoch: big.NewInt(0),
MinCommissionPromoPeriod: big.NewInt(10),
EPoSBound35Epoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: big.NewInt(0),
StakingPrecompileEpoch: big.NewInt(5),
ChainIdFixEpoch: big.NewInt(5),
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(5),
AllowlistEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD,
FeeCollectEpoch: big.NewInt(5),
ValidatorCodeFixEpoch: big.NewInt(5),
HIP30Epoch: big.NewInt(7),
BlockGas30MEpoch: big.NewInt(7),
ChainID: PartnerChainID,
EthCompatibleChainID: EthPartnerShard0ChainID,
EthCompatibleShard0ChainID: EthPartnerShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(3),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: EpochTBD,
RedelegationEpoch: big.NewInt(0),
NoEarlyUnlockEpoch: big.NewInt(0),
VRFEpoch: big.NewInt(0),
PrevVRFEpoch: big.NewInt(0),
MinDelegation100Epoch: big.NewInt(0),
MinCommissionRateEpoch: big.NewInt(0),
MinCommissionPromoPeriod: big.NewInt(10),
EPoSBound35Epoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: big.NewInt(0),
StakingPrecompileEpoch: big.NewInt(5),
ChainIdFixEpoch: big.NewInt(5),
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(5),
AllowlistEpoch: EpochTBD,
LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalValidatorsEpoch: EpochTBD,
FeeCollectEpoch: big.NewInt(5),
ValidatorCodeFixEpoch: big.NewInt(5),
HIP30Epoch: big.NewInt(7),
BlockGas30MEpoch: big.NewInt(7),
}
// StressnetChainConfig contains the chain parameters for the Stress test network.
// All features except for CrossLink are enabled at launch.
StressnetChainConfig = &ChainConfig{
ChainID: StressnetChainID,
EthCompatibleChainID: EthStressnetShard0ChainID,
EthCompatibleShard0ChainID: EthStressnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(3),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: big.NewInt(10),
RedelegationEpoch: big.NewInt(0),
NoEarlyUnlockEpoch: big.NewInt(0),
VRFEpoch: big.NewInt(0),
PrevVRFEpoch: big.NewInt(0),
MinDelegation100Epoch: big.NewInt(0),
MinCommissionRateEpoch: big.NewInt(0),
MinCommissionPromoPeriod: big.NewInt(10),
EPoSBound35Epoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: big.NewInt(0),
StakingPrecompileEpoch: big.NewInt(2),
ChainIdFixEpoch: big.NewInt(0),
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(1),
AllowlistEpoch: EpochTBD,
FeeCollectEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD,
ValidatorCodeFixEpoch: EpochTBD,
HIP30Epoch: EpochTBD,
BlockGas30MEpoch: big.NewInt(0),
ChainID: StressnetChainID,
EthCompatibleChainID: EthStressnetShard0ChainID,
EthCompatibleShard0ChainID: EthStressnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(3),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: big.NewInt(10),
RedelegationEpoch: big.NewInt(0),
NoEarlyUnlockEpoch: big.NewInt(0),
VRFEpoch: big.NewInt(0),
PrevVRFEpoch: big.NewInt(0),
MinDelegation100Epoch: big.NewInt(0),
MinCommissionRateEpoch: big.NewInt(0),
MinCommissionPromoPeriod: big.NewInt(10),
EPoSBound35Epoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: big.NewInt(0),
StakingPrecompileEpoch: big.NewInt(2),
ChainIdFixEpoch: big.NewInt(0),
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(1),
AllowlistEpoch: EpochTBD,
FeeCollectEpoch: EpochTBD,
LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalValidatorsEpoch: EpochTBD,
ValidatorCodeFixEpoch: EpochTBD,
HIP30Epoch: EpochTBD,
BlockGas30MEpoch: big.NewInt(0),
}
// LocalnetChainConfig contains the chain parameters to run for local development.
LocalnetChainConfig = &ChainConfig{
ChainID: TestnetChainID,
EthCompatibleChainID: EthTestnetShard0ChainID,
EthCompatibleShard0ChainID: EthTestnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(3),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(0),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup
RedelegationEpoch: big.NewInt(0),
NoEarlyUnlockEpoch: big.NewInt(0),
VRFEpoch: big.NewInt(0),
PrevVRFEpoch: big.NewInt(0),
MinDelegation100Epoch: big.NewInt(0),
MinCommissionRateEpoch: big.NewInt(0),
MinCommissionPromoPeriod: big.NewInt(10),
EPoSBound35Epoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup
StakingPrecompileEpoch: big.NewInt(2),
ChainIdFixEpoch: big.NewInt(0),
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(1),
AllowlistEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: big.NewInt(5),
LeaderRotationExternalBeaconLeaders: big.NewInt(6),
FeeCollectEpoch: big.NewInt(2),
ValidatorCodeFixEpoch: big.NewInt(2),
HIP30Epoch: EpochTBD,
BlockGas30MEpoch: big.NewInt(0),
ChainID: TestnetChainID,
EthCompatibleChainID: EthTestnetShard0ChainID,
EthCompatibleShard0ChainID: EthTestnetShard0ChainID,
EthCompatibleEpoch: big.NewInt(0),
CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2),
AggregatedRewardEpoch: big.NewInt(3),
StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(0),
QuickUnlockEpoch: big.NewInt(0),
FiveSecondsEpoch: big.NewInt(0),
TwoSecondsEpoch: big.NewInt(0),
SixtyPercentEpoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup
RedelegationEpoch: big.NewInt(0),
NoEarlyUnlockEpoch: big.NewInt(0),
VRFEpoch: big.NewInt(0),
PrevVRFEpoch: big.NewInt(0),
MinDelegation100Epoch: big.NewInt(0),
MinCommissionRateEpoch: big.NewInt(0),
MinCommissionPromoPeriod: big.NewInt(10),
EPoSBound35Epoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0),
S3Epoch: big.NewInt(0),
DataCopyFixEpoch: big.NewInt(0),
IstanbulEpoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
SHA3Epoch: big.NewInt(0),
HIP6And8Epoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup
StakingPrecompileEpoch: big.NewInt(2),
ChainIdFixEpoch: big.NewInt(0),
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(1),
AllowlistEpoch: EpochTBD,
LeaderRotationInternalValidatorsEpoch: big.NewInt(5),
LeaderRotationExternalValidatorsEpoch: big.NewInt(6),
FeeCollectEpoch: big.NewInt(2),
ValidatorCodeFixEpoch: big.NewInt(2),
HIP30Epoch: EpochTBD,
BlockGas30MEpoch: big.NewInt(0),
}
// AllProtocolChanges ...
@ -521,9 +521,9 @@ type ChainConfig struct {
// AllowlistEpoch is the first epoch to support allowlist of HIP18
AllowlistEpoch *big.Int
LeaderRotationExternalNonBeaconLeaders *big.Int `json:"leader-rotation-external-non-beacon-leaders,omitempty"`
LeaderRotationInternalValidatorsEpoch *big.Int `json:"leader-rotation-internal-validators,omitempty"`
LeaderRotationExternalBeaconLeaders *big.Int `json:"leader-rotation-external-beacon-leaders,omitempty"`
LeaderRotationExternalValidatorsEpoch *big.Int `json:"leader-rotation-external-validators,omitempty"`
// FeeCollectEpoch is the first epoch that enables txn fees to be collected into the community-managed account.
// It should >= StakingEpoch.
@ -778,22 +778,16 @@ func (c *ChainConfig) IsAllowlistEpoch(epoch *big.Int) bool {
return isForked(c.AllowlistEpoch, epoch)
}
func (c *ChainConfig) IsLeaderRotation(epoch *big.Int) bool {
return isForked(c.LeaderRotationExternalNonBeaconLeaders, epoch)
func (c *ChainConfig) IsLeaderRotationInternalValidators(epoch *big.Int) bool {
return isForked(c.LeaderRotationInternalValidatorsEpoch, epoch)
}
func (c *ChainConfig) IsBlockGas30M(epoch *big.Int) bool {
return isForked(c.BlockGas30MEpoch, epoch)
}
func (c *ChainConfig) IsLeaderRotationExternalValidatorsAllowed(epoch *big.Int, shardID uint32) bool {
if !c.IsLeaderRotation(epoch) {
return false
}
if shardID == 0 {
return isForked(c.LeaderRotationExternalBeaconLeaders, epoch)
}
return true
func (c *ChainConfig) IsLeaderRotationExternalValidatorsAllowed(epoch *big.Int) bool {
return isForked(c.LeaderRotationExternalValidatorsEpoch, epoch)
}
// IsFeeCollectEpoch determines whether Txn Fees will be collected into the community-managed account.

@ -93,7 +93,7 @@ func (node *Node) WaitForConsensusReadyV2(cs *consensus.Consensus, stopChan chan
Int("numTxs", newBlock.Transactions().Len()).
Int("numStakingTxs", newBlock.StakingTransactions().Len()).
Int("crossShardReceipts", newBlock.IncomingReceipts().Len()).
Msg("=========Successfully Proposed New Block==========")
Msgf("=========Successfully Proposed New Block, shard: %d epoch: %d number: %d ==========", newBlock.ShardID(), newBlock.Epoch().Uint64(), newBlock.NumberU64())
// Send the new block to Consensus so it can be confirmed.
cs.BlockChannel(newBlock)

@ -19,13 +19,13 @@ hmy --node=http://127.0.0.1:9500 transfer --from one1zksj3evekayy90xt4psrz8h
#wait for epoch 2
epoch=$(hmy blockchain latest-headers --node="http://localhost:9500" | jq -r '.["result"]["beacon-chain-header"]["epoch"]')
while (( epoch < 2 )); do
echo "Not yet on epoch 2 .. waiting 30s"
while (( epoch < 1 )); do
echo "Not yet on epoch 1 .. waiting 30s"
epoch=$(hmy blockchain latest-headers --node="http://localhost:9500" | jq -r '.["result"]["beacon-chain-header"]["epoch"]')
sleep 30
done
echo "Now in epoch 2, we'll create the external validators"
echo "Now in epoch 1, we'll create the external validators"
hmy --node="http://localhost:9500" staking create-validator \
--validator-addr one17ughrllgnzx9sfa46p568k8rdmtz7qj85slc6t --amount 10000 \

Loading…
Cancel
Save