update leader rotation configs

feature/dev-engine_test
static 1 year ago
commit 3d7a9318d1
  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. 44
      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: travis_rpc_checker:
bash ./scripts/travis_rpc_checker.sh 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 { func VerifyNewBlock(hooks *webhooks.Hooks, blockChain core.BlockChain, beaconChain core.BlockChain) func(*types.Block) error {
return func(newBlock *types.Block) error { return func(newBlock *types.Block) error {
if err := blockChain.ValidateNewBlock(newBlock, beaconChain); err != nil { if err := blockChain.ValidateNewBlock(newBlock, beaconChain); err != nil {
switch {
case errors.Is(err, core.ErrKnownBlock):
return nil
default:
}
if hooks := hooks; hooks != nil { if hooks := hooks; hooks != nil {
if p := hooks.ProtocolIssues; p != nil { if p := hooks.ProtocolIssues; p != nil {
url := p.OnCannotCommit url := p.OnCannotCommit
@ -680,7 +686,7 @@ func VerifyNewBlock(hooks *webhooks.Hooks, blockChain core.BlockChain, beaconCha
Int("numStakingTx", len(newBlock.StakingTransactions())). Int("numStakingTx", len(newBlock.StakingTransactions())).
Err(err). Err(err).
Msgf("[VerifyNewBlock] Cannot Verify New Block!!!, blockHeight %d, myHeight %d", newBlock.NumberU64(), blockChain.CurrentHeader().NumberU64()) 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", "[VerifyNewBlock] Cannot Verify New Block!!! block-hash %s txn-count %d",
newBlock.Hash().Hex(), newBlock.Hash().Hex(),
len(newBlock.Transactions()), len(newBlock.Transactions()),

@ -5,6 +5,8 @@ import (
"github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/registry" "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" msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/consensus/quorum" "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) 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" "github.com/ethereum/go-ethereum/common"
bls2 "github.com/harmony-one/bls/ffi/go/bls" bls2 "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/consensus/signature" "github.com/harmony-one/harmony/consensus/signature"
"github.com/harmony-one/harmony/core"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -31,7 +32,6 @@ import (
var ( var (
errSenderPubKeyNotLeader = errors.New("sender pubkey doesn't match leader") errSenderPubKeyNotLeader = errors.New("sender pubkey doesn't match leader")
errVerifyMessageSignature = errors.New("verify message signature failed") errVerifyMessageSignature = errors.New("verify message signature failed")
errParsingFBFTMessage = errors.New("failed parsing FBFT message")
) )
// timeout constant // 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 { 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") switch {
return 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") consensus.getLogger().Info().Msg("[preCommitAndPropose] Start consensus timer")
@ -693,7 +698,7 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) {
prev = consensus.getLeaderPubKey() prev = consensus.getLeaderPubKey()
leader = 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) ss, err := bc.ReadShardState(epoch)
if err != nil { if err != nil {
utils.Logger().Error().Err(err).Msg("Failed to read shard state") 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 // mine no less than 3 blocks in a row
numBlocksProducedByLeader = minimumBlocksForLeaderInRow numBlocksProducedByLeader = minimumBlocksForLeaderInRow
} }
type stored struct { s := bc.LeaderRotationMeta()
pub []byte if !bytes.Equal(leader.Bytes[:], s.Pub) {
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) {
// Another leader. // Another leader.
return return
} }
// if it is the first validator which produce blocks, then it should produce `rest` blocks too. // If it is the first validator producing blocks, it should also produce the remaining 'rest' of the blocks.
if s.shifts == 0 { if s.Shifts == 0 {
numBlocksProducedByLeader += rest numBlocksProducedByLeader += rest
} }
if s.count < numBlocksProducedByLeader { if s.Count < numBlocksProducedByLeader {
// Not enough blocks produced by the leader. // Not enough blocks produced by the leader, continue producing by the same leader.
return return
} }
// Passed all checks, we can change leader. // Passed all checks, we can change leader.
@ -748,7 +746,7 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) {
wasFound bool wasFound bool
next *bls.PublicKeyWrapper next *bls.PublicKeyWrapper
) )
if bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch, consensus.ShardID) { if bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch) {
wasFound, next = consensus.Decider.NthNextValidator(committee.Slots, leader, 1) wasFound, next = consensus.Decider.NthNextValidator(committee.Slots, leader, 1)
} else { } else {
wasFound, next = consensus.Decider.NthNextHmy(shard.Schedule.InstanceForEpoch(epoch), leader, 1) wasFound, next = consensus.Decider.NthNextHmy(shard.Schedule.InstanceForEpoch(epoch), leader, 1)
@ -778,7 +776,7 @@ func (consensus *Consensus) setupForNewConsensus(blk *types.Block, committedMsg
} else { } else {
epoch = blk.Epoch() epoch = blk.Epoch()
} }
if consensus.Blockchain().Config().IsLeaderRotation(epoch) { if consensus.Blockchain().Config().IsLeaderRotationInternalValidators(epoch) {
consensus.rotateLeader(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 // FIXME: rotate leader on harmony nodes only before fully externalization
var wasFound bool var wasFound bool
var next *bls.PublicKeyWrapper var next *bls.PublicKeyWrapper
if blockchain != nil && blockchain.Config().IsLeaderRotation(epoch) { if blockchain != nil && blockchain.Config().IsLeaderRotationInternalValidators(epoch) {
if blockchain.Config().IsLeaderRotationExternalValidatorsAllowed(epoch, consensus.ShardID) { if blockchain.Config().IsLeaderRotationExternalValidatorsAllowed(epoch) {
wasFound, next = consensus.Decider.NthNextValidator( wasFound, next = consensus.Decider.NthNextValidator(
committee.Slots, committee.Slots,
lastLeaderPubKey, lastLeaderPubKey,

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

@ -90,7 +90,8 @@ var (
blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil) blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil)
// ErrNoGenesis is the error when there is no genesis. // 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 ..
errExceedMaxPendingSlashes = errors.New("exceeed max pending slashes") errExceedMaxPendingSlashes = errors.New("exceeed max pending slashes")
errNilEpoch = errors.New("nil epoch for voting power computation") errNilEpoch = errors.New("nil epoch for voting power computation")
@ -222,7 +223,7 @@ type BlockChainImpl struct {
badBlocks *lru.Cache // Bad block cache badBlocks *lru.Cache // Bad block cache
pendingSlashes slash.Records pendingSlashes slash.Records
maxGarbCollectedBlkNum int64 maxGarbCollectedBlkNum int64
leaderRotationMeta leaderRotationMeta leaderRotationMeta LeaderRotationMeta
options Options options Options
} }
@ -1633,9 +1634,20 @@ func (bc *BlockChainImpl) InsertChain(chain types.Blocks, verifyHeaders bool) (i
return len(chain), nil 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) n, events, logs, err := bc.insertChain(chain, verifyHeaders)
bc.PostChainEvents(events, logs) bc.PostChainEvents(events, logs)
if err == nil { if err == nil {
if prevHash == bc.CurrentBlock().Hash() {
panic("insertChain failed to update current block")
}
// there should be only 1 block. // there should be only 1 block.
for _, b := range chain { for _, b := range chain {
if b.Epoch().Uint64() > 0 { if b.Epoch().Uint64() > 0 {
@ -1654,75 +1666,8 @@ func (bc *BlockChainImpl) InsertChain(chain types.Blocks, verifyHeaders bool) (i
return n, err return n, err
} }
// buildLeaderRotationMeta builds leader rotation meta if feature is activated. func (bc *BlockChainImpl) LeaderRotationMeta() LeaderRotationMeta {
func (bc *BlockChainImpl) buildLeaderRotationMeta(curHeader *block.Header) error { return bc.leaderRotationMeta.Clone()
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)
} }
// insertChain will execute the actual chain insertion and event aggregation. The // insertChain will execute the actual chain insertion and event aggregation. The
@ -1731,7 +1676,7 @@ func (bc *BlockChainImpl) LeaderRotationMeta() (publicKeyBytes []byte, epoch, co
func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (int, []interface{}, []*types.Log, error) { func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (int, []interface{}, []*types.Log, error) {
// Sanity check that we have something meaningful to import // Sanity check that we have something meaningful to import
if len(chain) == 0 { 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 // Do a sanity check that the provided chain is actually ordered and linked
for i := 1; i < len(chain); i++ { for i := 1; i < len(chain); i++ {

@ -1,8 +1,127 @@
package core package core
type leaderRotationMeta struct { import (
pub []byte "bytes"
epoch uint64 "hash/crc32"
count uint64 "strconv"
shifts uint64 "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 return
} }
func (a Stub) LeaderRotationMeta() (publicKeyBytes []byte, epoch, count, shifts uint64, err error) { func (a Stub) LeaderRotationMeta() LeaderRotationMeta {
return nil, 0, 0, 0, errors.Errorf("method LeaderRotationMeta not implemented for %s", a.Name) return LeaderRotationMeta{}
} }
func (a Stub) CommitPreimages() error { func (a Stub) CommitPreimages() error {

@ -1,7 +1,6 @@
package core_test package core_test
import ( import (
"fmt"
"testing" "testing"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -76,8 +75,8 @@ func TestAddNewBlock(t *testing.T) {
_, err = blockchain.InsertChain([]*types.Block{block}, false) _, err = blockchain.InsertChain([]*types.Block{block}, false)
require.NoError(t, err, "error when adding new block") require.NoError(t, err, "error when adding new block")
pk, epoch, count, shifts, err := blockchain.LeaderRotationMeta() meta := blockchain.LeaderRotationMeta()
fmt.Println("pk", pk, "epoch", epoch, "count", count, "shifts", shifts, "err", err) require.NotEmptyf(t, meta, "error when getting leader rotation meta")
t.Log("#", block.Header().NumberU64(), node.Blockchain().CurrentBlock().NumberU64(), block.Hash().Hex(), block.ParentHash()) 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 // SerializedSignature defines the bls signature
type SerializedSignature [BLSSignatureSizeInBytes]byte type SerializedSignature [BLSSignatureSizeInBytes]byte
// Bytes returns the byte array of bls signature
func (pk SerializedPublicKey) Bytes() []byte {
return pk[:]
}
// Big .. // Big ..
func (pk SerializedPublicKey) Big() *big.Int { func (pk SerializedPublicKey) Big() *big.Int {
return new(big.Int).SetBytes(pk[:]) return new(big.Int).SetBytes(pk[:])

@ -69,8 +69,8 @@ var (
SlotsLimitedEpoch: big.NewInt(999), // Around Fri, 27 May 2022 09:41:02 UTC with 2s block time 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 CrossShardXferPrecompileEpoch: big.NewInt(1323), // Around Wed 8 Feb 11:30PM UTC
AllowlistEpoch: EpochTBD, AllowlistEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: EpochTBD, LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD, LeaderRotationExternalValidatorsEpoch: EpochTBD,
FeeCollectEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00 FeeCollectEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00
ValidatorCodeFixEpoch: 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 HIP30Epoch: big.NewInt(1673), // 2023-11-02 17:30:00+00:00
@ -113,8 +113,8 @@ var (
ChainIdFixEpoch: big.NewInt(0), ChainIdFixEpoch: big.NewInt(0),
CrossShardXferPrecompileEpoch: big.NewInt(2), CrossShardXferPrecompileEpoch: big.NewInt(2),
AllowlistEpoch: big.NewInt(2), AllowlistEpoch: big.NewInt(2),
LeaderRotationExternalNonBeaconLeaders: EpochTBD, LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD, LeaderRotationExternalValidatorsEpoch: EpochTBD,
FeeCollectEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00 FeeCollectEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00
ValidatorCodeFixEpoch: 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 HIP30Epoch: big.NewInt(2176), // 2023-10-12 10:00:00+00:00
@ -158,12 +158,12 @@ var (
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(1), CrossShardXferPrecompileEpoch: big.NewInt(1),
AllowlistEpoch: EpochTBD, AllowlistEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: EpochTBD, LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD, LeaderRotationExternalValidatorsEpoch: EpochTBD,
FeeCollectEpoch: EpochTBD, FeeCollectEpoch: EpochTBD,
ValidatorCodeFixEpoch: EpochTBD, ValidatorCodeFixEpoch: EpochTBD,
HIP30Epoch: EpochTBD, HIP30Epoch: EpochTBD,
NoNilDelegationsEpoch: EpochTBD, NoNilDelegationsEpoch: EpochTBD,
BlockGas30MEpoch: big.NewInt(0), BlockGas30MEpoch: big.NewInt(0),
} }
@ -203,8 +203,8 @@ var (
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(5), CrossShardXferPrecompileEpoch: big.NewInt(5),
AllowlistEpoch: EpochTBD, AllowlistEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: EpochTBD, LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD, LeaderRotationExternalValidatorsEpoch: EpochTBD,
FeeCollectEpoch: big.NewInt(5), FeeCollectEpoch: big.NewInt(5),
ValidatorCodeFixEpoch: big.NewInt(5), ValidatorCodeFixEpoch: big.NewInt(5),
HIP30Epoch: big.NewInt(7), HIP30Epoch: big.NewInt(7),
@ -249,8 +249,8 @@ var (
CrossShardXferPrecompileEpoch: big.NewInt(1), CrossShardXferPrecompileEpoch: big.NewInt(1),
AllowlistEpoch: EpochTBD, AllowlistEpoch: EpochTBD,
FeeCollectEpoch: EpochTBD, FeeCollectEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: EpochTBD, LeaderRotationInternalValidatorsEpoch: EpochTBD,
LeaderRotationExternalBeaconLeaders: EpochTBD, LeaderRotationExternalValidatorsEpoch: EpochTBD,
ValidatorCodeFixEpoch: EpochTBD, ValidatorCodeFixEpoch: EpochTBD,
HIP30Epoch: EpochTBD, HIP30Epoch: EpochTBD,
NoNilDelegationsEpoch: big.NewInt(2), NoNilDelegationsEpoch: big.NewInt(2),
@ -292,8 +292,8 @@ var (
SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16
CrossShardXferPrecompileEpoch: big.NewInt(1), CrossShardXferPrecompileEpoch: big.NewInt(1),
AllowlistEpoch: EpochTBD, AllowlistEpoch: EpochTBD,
LeaderRotationExternalNonBeaconLeaders: big.NewInt(5), LeaderRotationInternalValidatorsEpoch: big.NewInt(5),
LeaderRotationExternalBeaconLeaders: big.NewInt(6), LeaderRotationExternalValidatorsEpoch: big.NewInt(6),
FeeCollectEpoch: big.NewInt(2), FeeCollectEpoch: big.NewInt(2),
ValidatorCodeFixEpoch: big.NewInt(2), ValidatorCodeFixEpoch: big.NewInt(2),
HIP30Epoch: EpochTBD, HIP30Epoch: EpochTBD,
@ -533,9 +533,9 @@ type ChainConfig struct {
// The first epoch at the end of which stale delegations are removed // The first epoch at the end of which stale delegations are removed
NoNilDelegationsEpoch *big.Int `json:"no-nil-delegations-epoch,omitempty"` NoNilDelegationsEpoch *big.Int `json:"no-nil-delegations-epoch,omitempty"`
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. // FeeCollectEpoch is the first epoch that enables txn fees to be collected into the community-managed account.
// It should >= StakingEpoch. // It should >= StakingEpoch.
@ -810,22 +810,16 @@ func (c *ChainConfig) IsAllowlistEpoch(epoch *big.Int) bool {
return isForked(c.AllowlistEpoch, epoch) return isForked(c.AllowlistEpoch, epoch)
} }
func (c *ChainConfig) IsLeaderRotation(epoch *big.Int) bool { func (c *ChainConfig) IsLeaderRotationInternalValidators(epoch *big.Int) bool {
return isForked(c.LeaderRotationExternalNonBeaconLeaders, epoch) return isForked(c.LeaderRotationInternalValidatorsEpoch, epoch)
} }
func (c *ChainConfig) IsBlockGas30M(epoch *big.Int) bool { func (c *ChainConfig) IsBlockGas30M(epoch *big.Int) bool {
return isForked(c.BlockGas30MEpoch, epoch) return isForked(c.BlockGas30MEpoch, epoch)
} }
func (c *ChainConfig) IsLeaderRotationExternalValidatorsAllowed(epoch *big.Int, shardID uint32) bool { func (c *ChainConfig) IsLeaderRotationExternalValidatorsAllowed(epoch *big.Int) bool {
if !c.IsLeaderRotation(epoch) { return isForked(c.LeaderRotationExternalValidatorsEpoch, epoch)
return false
}
if shardID == 0 {
return isForked(c.LeaderRotationExternalBeaconLeaders, epoch)
}
return true
} }
// IsFeeCollectEpoch determines whether Txn Fees will be collected into the community-managed account. // 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("numTxs", newBlock.Transactions().Len()).
Int("numStakingTxs", newBlock.StakingTransactions().Len()). Int("numStakingTxs", newBlock.StakingTransactions().Len()).
Int("crossShardReceipts", newBlock.IncomingReceipts().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. // Send the new block to Consensus so it can be confirmed.
cs.BlockChannel(newBlock) cs.BlockChannel(newBlock)

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

Loading…
Cancel
Save