Cache for `GetLeaderPubKeyFromCoinbase`, removed `NthNextHmyExt`.

pull/4351/head
frozen 2 years ago committed by Casey Gardiner
parent 7de4b30e44
commit 50ed1c666b
  1. 14
      consensus/consensus_v2.go
  2. 3
      core/blockchain.go
  3. 59
      core/blockchain_impl.go
  4. 5
      core/blockchain_stub.go

@ -11,7 +11,6 @@ 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/internal/chain"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/utils"
@ -697,7 +696,7 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) {
return
}
// Check if the same leader.
pub, err := chain.GetLeaderPubKeyFromCoinbase(consensus.Blockchain, header)
pub, err := consensus.Blockchain.GetLeaderPubKeyFromCoinbase(header)
if err != nil {
utils.Logger().Error().Err(err).Msg("Failed to get leader public key from coinbase")
return
@ -708,16 +707,7 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) {
}
}
// Passed all checks, we can change leader.
var (
wasFound bool
next *bls.PublicKeyWrapper
)
// The same leader for N blocks.
if consensus.Blockchain.Config().IsAllowlistEpoch(epoch) {
wasFound, next = consensus.Decider.NthNextHmyExt(shard.Schedule.InstanceForEpoch(epoch), leader, 1)
} else {
wasFound, next = consensus.Decider.NthNextHmy(shard.Schedule.InstanceForEpoch(epoch), leader, 1)
}
wasFound, next := consensus.Decider.NthNextHmy(shard.Schedule.InstanceForEpoch(epoch), leader, 1)
if !wasFound {
utils.Logger().Error().Msg("Failed to get next leader")
return

@ -13,6 +13,7 @@ import (
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/crypto/bls"
harmonyconfig "github.com/harmony-one/harmony/internal/configs/harmony"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/tikv/redis_helper"
@ -334,6 +335,8 @@ type BlockChain interface {
state *state.DB,
) (status WriteStatus, err error)
GetLeaderPubKeyFromCoinbase(h *block.Header) (*bls.PublicKeyWrapper, error)
// ========== Only For Tikv Start ==========
// return true if is tikv writer master

@ -39,6 +39,7 @@ import (
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rlp"
bls2 "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/block"
consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/consensus/reward"
@ -47,6 +48,7 @@ import (
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/crypto/bls"
harmonyconfig "github.com/harmony-one/harmony/internal/configs/harmony"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/tikv"
@ -181,6 +183,7 @@ type BlockChainImpl struct {
validatorListByDelegatorCache *lru.Cache // Cache of validator list by delegator
pendingCrossLinksCache *lru.Cache // Cache of last pending crosslinks
blockAccumulatorCache *lru.Cache // Cache of block accumulators
leaderPubKeyFromCoinbase *lru.Cache // Cache of leader public key from coinbase
quit chan struct{} // blockchain quit channel
running int32 // running must be called atomically
blockchainPruner *blockchainPruner // use to prune beacon chain
@ -242,6 +245,7 @@ func newBlockChainWithOptions(
validatorListByDelegatorCache, _ := lru.New(validatorListByDelegatorCacheLimit)
pendingCrossLinksCache, _ := lru.New(pendingCrossLinksCacheLimit)
blockAccumulatorCache, _ := lru.New(blockAccumulatorCacheLimit)
leaderPubKeyFromCoinbase, _ := lru.New(chainConfig.LeaderRotationBlocksCount + 2)
bc := &BlockChainImpl{
chainConfig: chainConfig,
@ -265,6 +269,7 @@ func newBlockChainWithOptions(
validatorListByDelegatorCache: validatorListByDelegatorCache,
pendingCrossLinksCache: pendingCrossLinksCache,
blockAccumulatorCache: blockAccumulatorCache,
leaderPubKeyFromCoinbase: leaderPubKeyFromCoinbase,
blockchainPruner: newBlockchainPruner(db),
engine: engine,
vmConfig: vmConfig,
@ -3256,6 +3261,60 @@ func (bc *BlockChainImpl) SuperCommitteeForNextEpoch(
return nextCommittee, err
}
// GetLeaderPubKeyFromCoinbase retrieve corresponding blsPublicKey from Coinbase Address
func (bc *BlockChainImpl) GetLeaderPubKeyFromCoinbase(h *block.Header) (*bls.PublicKeyWrapper, error) {
if cached, ok := bc.leaderPubKeyFromCoinbase.Get(h.Number().Uint64()); ok {
return cached.(*bls.PublicKeyWrapper), nil
}
rs, err := bc.getLeaderPubKeyFromCoinbase(h)
if err != nil {
return nil, err
}
bc.leaderPubKeyFromCoinbase.Add(h.Number().Uint64(), rs)
return rs, nil
}
// getLeaderPubKeyFromCoinbase retrieve corresponding blsPublicKey from Coinbase Address
func (bc *BlockChainImpl) getLeaderPubKeyFromCoinbase(h *block.Header) (*bls.PublicKeyWrapper, error) {
shardState, err := bc.ReadShardState(h.Epoch())
if err != nil {
return nil, errors.Wrapf(err, "cannot read shard state %v %s",
h.Epoch(),
h.Coinbase().Hash().Hex(),
)
}
committee, err := shardState.FindCommitteeByID(h.ShardID())
if err != nil {
return nil, err
}
committerKey := new(bls2.PublicKey)
isStaking := bc.Config().IsStaking(h.Epoch())
for _, member := range committee.Slots {
if isStaking {
// After staking the coinbase address will be the address of bls public key
if utils.GetAddressFromBLSPubKeyBytes(member.BLSPublicKey[:]) == h.Coinbase() {
if committerKey, err = bls.BytesToBLSPublicKey(member.BLSPublicKey[:]); err != nil {
return nil, err
}
return &bls.PublicKeyWrapper{Object: committerKey, Bytes: member.BLSPublicKey}, nil
}
} else {
if member.EcdsaAddress == h.Coinbase() {
if committerKey, err = bls.BytesToBLSPublicKey(member.BLSPublicKey[:]); err != nil {
return nil, err
}
return &bls.PublicKeyWrapper{Object: committerKey, Bytes: member.BLSPublicKey}, nil
}
}
}
return nil, errors.Errorf(
"cannot find corresponding BLS Public Key coinbase %s",
h.Coinbase().Hex(),
)
}
func (bc *BlockChainImpl) EnablePruneBeaconChainFeature() {
bc.pruneBeaconChainEnable = true
}

@ -13,6 +13,7 @@ import (
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/crypto/bls"
harmonyconfig "github.com/harmony-one/harmony/internal/configs/harmony"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/tikv/redis_helper"
@ -403,6 +404,10 @@ func (a Stub) CommitOffChainData(batch rawdb.DatabaseWriter, block *types.Block,
return 0, errors.Errorf("method CommitOffChainData not implemented for %s", a.Name)
}
func (a Stub) GetLeaderPubKeyFromCoinbase(h *block.Header) (*bls.PublicKeyWrapper, error) {
return nil, errors.Errorf("method GetLeaderPubKeyFromCoinbase not implemented for %s", a.Name)
}
func (a Stub) IsTikvWriterMaster() bool {
return false
}

Loading…
Cancel
Save