Cache for `GetLeaderPubKeyFromCoinbase`, removed `NthNextHmyExt`.

pull/4377/head
frozen 2 years ago committed by Casey Gardiner
parent b7d4bb6c92
commit 998bb642c5
  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" "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/internal/chain"
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"
@ -697,7 +696,7 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) {
return return
} }
// Check if the same leader. // Check if the same leader.
pub, err := chain.GetLeaderPubKeyFromCoinbase(consensus.Blockchain, header) pub, err := consensus.Blockchain.GetLeaderPubKeyFromCoinbase(header)
if err != nil { if err != nil {
utils.Logger().Error().Err(err).Msg("Failed to get leader public key from coinbase") utils.Logger().Error().Err(err).Msg("Failed to get leader public key from coinbase")
return return
@ -708,16 +707,7 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) {
} }
} }
// Passed all checks, we can change leader. // Passed all checks, we can change leader.
var ( wasFound, next := consensus.Decider.NthNextHmy(shard.Schedule.InstanceForEpoch(epoch), leader, 1)
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)
}
if !wasFound { if !wasFound {
utils.Logger().Error().Msg("Failed to get next leader") utils.Logger().Error().Msg("Failed to get next leader")
return return

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

@ -39,6 +39,7 @@ import (
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
bls2 "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
consensus_engine "github.com/harmony-one/harmony/consensus/engine" consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/consensus/reward" "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/state"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/crypto/bls"
harmonyconfig "github.com/harmony-one/harmony/internal/configs/harmony" harmonyconfig "github.com/harmony-one/harmony/internal/configs/harmony"
"github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/tikv" "github.com/harmony-one/harmony/internal/tikv"
@ -181,6 +183,7 @@ type BlockChainImpl struct {
validatorListByDelegatorCache *lru.Cache // Cache of validator list by delegator validatorListByDelegatorCache *lru.Cache // Cache of validator list by delegator
pendingCrossLinksCache *lru.Cache // Cache of last pending crosslinks pendingCrossLinksCache *lru.Cache // Cache of last pending crosslinks
blockAccumulatorCache *lru.Cache // Cache of block accumulators blockAccumulatorCache *lru.Cache // Cache of block accumulators
leaderPubKeyFromCoinbase *lru.Cache // Cache of leader public key from coinbase
quit chan struct{} // blockchain quit channel quit chan struct{} // blockchain quit channel
running int32 // running must be called atomically running int32 // running must be called atomically
blockchainPruner *blockchainPruner // use to prune beacon chain blockchainPruner *blockchainPruner // use to prune beacon chain
@ -242,6 +245,7 @@ func newBlockChainWithOptions(
validatorListByDelegatorCache, _ := lru.New(validatorListByDelegatorCacheLimit) validatorListByDelegatorCache, _ := lru.New(validatorListByDelegatorCacheLimit)
pendingCrossLinksCache, _ := lru.New(pendingCrossLinksCacheLimit) pendingCrossLinksCache, _ := lru.New(pendingCrossLinksCacheLimit)
blockAccumulatorCache, _ := lru.New(blockAccumulatorCacheLimit) blockAccumulatorCache, _ := lru.New(blockAccumulatorCacheLimit)
leaderPubKeyFromCoinbase, _ := lru.New(chainConfig.LeaderRotationBlocksCount + 2)
bc := &BlockChainImpl{ bc := &BlockChainImpl{
chainConfig: chainConfig, chainConfig: chainConfig,
@ -265,6 +269,7 @@ func newBlockChainWithOptions(
validatorListByDelegatorCache: validatorListByDelegatorCache, validatorListByDelegatorCache: validatorListByDelegatorCache,
pendingCrossLinksCache: pendingCrossLinksCache, pendingCrossLinksCache: pendingCrossLinksCache,
blockAccumulatorCache: blockAccumulatorCache, blockAccumulatorCache: blockAccumulatorCache,
leaderPubKeyFromCoinbase: leaderPubKeyFromCoinbase,
blockchainPruner: newBlockchainPruner(db), blockchainPruner: newBlockchainPruner(db),
engine: engine, engine: engine,
vmConfig: vmConfig, vmConfig: vmConfig,
@ -3256,6 +3261,60 @@ func (bc *BlockChainImpl) SuperCommitteeForNextEpoch(
return nextCommittee, err 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() { func (bc *BlockChainImpl) EnablePruneBeaconChainFeature() {
bc.pruneBeaconChainEnable = true bc.pruneBeaconChainEnable = true
} }

@ -13,6 +13,7 @@ import (
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/crypto/bls"
harmonyconfig "github.com/harmony-one/harmony/internal/configs/harmony" harmonyconfig "github.com/harmony-one/harmony/internal/configs/harmony"
"github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/tikv/redis_helper" "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) 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 { func (a Stub) IsTikvWriterMaster() bool {
return false return false
} }

Loading…
Cancel
Save