Consensus: reduce consensus initialization steps. (#4387)

* Removed hardcoded blockchain.

* Fix for consensus.

* Fix tests.

* Fixed panic.

* Clean up code.

* Fix formatting.

* Fixed comment.

* Removed unused.

* Fix merge issue.
pull/4439/head
Konstantin 2 years ago committed by GitHub
parent 3d4bf3f49c
commit 78d802428c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      cmd/harmony/main.go
  2. 23
      consensus/consensus.go
  3. 36
      consensus/consensus_service.go
  4. 7
      consensus/consensus_service_test.go
  5. 2
      consensus/consensus_v2.go
  6. 13
      consensus/construct_test.go
  7. 9
      consensus/downloader.go
  8. 2
      consensus/leader.go
  9. 8
      consensus/signature/signature.go
  10. 2
      consensus/threshold.go
  11. 2
      consensus/validator.go
  12. 7
      core/blockchain.go
  13. 8
      core/blockchain_impl.go
  14. 4
      core/offchain.go
  15. 2
      internal/chain/engine.go
  16. 2
      internal/chain/engine_test.go
  17. 37
      internal/registry/registry.go
  18. 2
      node/node_explorer.go
  19. 39
      node/node_handler.go
  20. 6
      node/node_handler_test.go
  21. 9
      node/node_newblock_test.go
  22. 2
      staking/slash/double-sign.go
  23. 3
      staking/slash/double-sign_test.go
  24. 53
      staking/verify/verify.go

@ -722,11 +722,12 @@ func setupConsensusAndNode(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfi
// We are not beacon chain, make sure beacon already initialized.
if nodeConfig.ShardID != shard.BeaconChainShardID {
_, err = collection.ShardChain(shard.BeaconChainShardID, core.Options{EpochChain: true})
beacon, err := collection.ShardChain(shard.BeaconChainShardID, core.Options{EpochChain: true})
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Error :%v \n", err)
os.Exit(1)
}
registry.SetBeaconchain(beacon)
}
blockchain, err = collection.ShardChain(nodeConfig.ShardID)
@ -734,11 +735,16 @@ func setupConsensusAndNode(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfi
_, _ = fmt.Fprintf(os.Stderr, "Error :%v \n", err)
os.Exit(1)
}
registry.SetBlockchain(blockchain)
registry.SetWebHooks(nodeConfig.WebHooks.Hooks)
if registry.GetBeaconchain() == nil {
registry.SetBeaconchain(registry.GetBlockchain())
}
// Consensus object.
decider := quorum.NewDecider(quorum.SuperMajorityVote, nodeConfig.ShardID)
currentConsensus, err := consensus.New(
myHost, nodeConfig.ShardID, nodeConfig.ConsensusPriKey, registry.SetBlockchain(blockchain), decider, minPeers, aggregateSig)
myHost, nodeConfig.ShardID, nodeConfig.ConsensusPriKey, registry, decider, minPeers, aggregateSig)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Error :%v \n", err)
@ -794,9 +800,6 @@ func setupConsensusAndNode(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfi
Uint64("viewID", viewID).
Msg("Init Blockchain")
// Assign closure functions to the consensus object
currentConsensus.SetBlockVerifier(
node.VerifyNewBlock(currentNode.NodeConfig, currentNode.Blockchain(), currentNode.Beaconchain()))
currentConsensus.PostConsensusJob = currentNode.PostConsensusProcessing
// update consensus information based on the blockchain
currentConsensus.SetMode(currentConsensus.UpdateConsensusInformation())

@ -6,6 +6,7 @@ import (
"sync/atomic"
"time"
"github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/registry"
@ -139,14 +140,20 @@ func (consensus *Consensus) Blockchain() core.BlockChain {
return consensus.registry.GetBlockchain()
}
func (consensus *Consensus) ReadySignal(p ProposalType) {
consensus.readySignal <- p
// ChainReader returns the chain reader.
// This is mostly the same as Blockchain, but it returns only read methods, so we assume it's safe for concurrent use.
func (consensus *Consensus) ChainReader() engine.ChainReader {
return consensus.Blockchain()
}
func (consensus *Consensus) GetReadySignal() chan ProposalType {
return consensus.readySignal
}
func (consensus *Consensus) ReadySignal(p ProposalType) {
consensus.readySignal <- p
}
func (consensus *Consensus) CommitSigChannel() chan []byte {
return consensus.commitSigChannel
}
@ -155,6 +162,11 @@ func (consensus *Consensus) GetCommitSigChannel() chan []byte {
return consensus.commitSigChannel
}
// Beaconchain returns the beaconchain.
func (consensus *Consensus) Beaconchain() core.BlockChain {
return consensus.registry.GetBeaconchain()
}
// VerifyBlock is a function used to verify the block and keep trace of verified blocks.
func (consensus *Consensus) verifyBlock(block *types.Block) error {
if !consensus.FBFTLog.IsBlockVerified(block.Hash()) {
@ -232,8 +244,8 @@ func (consensus *Consensus) getConsensusLeaderPrivateKey() (*bls.PrivateKeyWrapp
return consensus.getLeaderPrivateKey(consensus.LeaderPubKey.Object)
}
// SetBlockVerifier sets the block verifier
func (consensus *Consensus) SetBlockVerifier(verifier VerifyBlockFunc) {
// setBlockVerifier sets the block verifier
func (consensus *Consensus) setBlockVerifier(verifier VerifyBlockFunc) {
consensus.mutex.Lock()
defer consensus.mutex.Unlock()
consensus.BlockVerifier = verifier
@ -288,7 +300,6 @@ func New(
// the blockchain during initialization as it was
// displayed on explorer as Height right now
consensus.SetCurBlockViewID(0)
consensus.ShardID = shard
consensus.SlashChan = make(chan slash.Record)
consensus.readySignal = make(chan ProposalType)
consensus.commitSigChannel = make(chan []byte)
@ -297,6 +308,8 @@ func New(
consensus.IgnoreViewIDCheck = abool.NewBool(false)
// Make Sure Verifier is not null
consensus.vc = newViewChange()
// TODO: reference to blockchain/beaconchain should be removed.
consensus.setBlockVerifier(VerifyNewBlock(registry.GetWebHooks(), consensus.Blockchain(), consensus.Beaconchain()))
// init prometheus metrics
initMetrics()

@ -5,9 +5,11 @@ import (
"sync/atomic"
"time"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/webhooks"
"github.com/ethereum/go-ethereum/common"
protobuf "github.com/golang/protobuf/proto"
@ -590,7 +592,7 @@ func (consensus *Consensus) selfCommit(payload []byte) error {
consensus.switchPhase("selfCommit", FBFTCommit)
consensus.aggregatedPrepareSig = aggSig
consensus.prepareBitmap = mask
commitPayload := signature.ConstructCommitPayload(consensus.Blockchain(),
commitPayload := signature.ConstructCommitPayload(consensus.ChainReader().Config(),
block.Epoch(), block.Hash(), block.NumberU64(), block.Header().ViewID().Uint64())
for i, key := range consensus.priKey {
if err := consensus.commitBitmap.SetKey(key.Pub.Bytes, true); err != nil {
@ -658,3 +660,35 @@ func (consensus *Consensus) getLogger() *zerolog.Logger {
Logger()
return &logger
}
// VerifyNewBlock is called by consensus participants to verify the block (account model) they are
// running consensus on.
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 {
if hooks := hooks; hooks != nil {
if p := hooks.ProtocolIssues; p != nil {
url := p.OnCannotCommit
go func() {
webhooks.DoPost(url, map[string]interface{}{
"bad-header": newBlock.Header(),
"reason": err.Error(),
})
}()
}
}
utils.Logger().Error().
Str("blockHash", newBlock.Hash().Hex()).
Int("numTx", len(newBlock.Transactions())).
Int("numStakingTx", len(newBlock.StakingTransactions())).
Err(err).
Msg("[VerifyNewBlock] Cannot Verify New Block!!!")
return errors.Errorf(
"[VerifyNewBlock] Cannot Verify New Block!!! block-hash %s txn-count %d",
newBlock.Hash().Hex(),
len(newBlock.Transactions()),
)
}
return nil
}
}

@ -4,6 +4,7 @@ import (
"testing"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/registry"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/consensus/quorum"
@ -25,7 +26,8 @@ func TestSignAndMarshalConsensusMessage(t *testing.T) {
}
decider := quorum.NewDecider(quorum.SuperMajorityVote, shard.BeaconChainShardID)
blsPriKey := bls.RandPrivateKey()
consensus, err := New(host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), nil, decider, 3, false)
reg := registry.New()
consensus, err := New(host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), reg, decider, 3, false)
if err != nil {
t.Fatalf("Cannot craeate consensus: %v", err)
}
@ -57,8 +59,9 @@ func TestSetViewID(t *testing.T) {
quorum.SuperMajorityVote, shard.BeaconChainShardID,
)
blsPriKey := bls.RandPrivateKey()
reg := registry.New()
consensus, err := New(
host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), nil, decider, 3, false,
host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), reg, decider, 3, false,
)
if err != nil {
t.Fatalf("Cannot craeate consensus: %v", err)

@ -608,7 +608,7 @@ func (consensus *Consensus) verifyLastCommitSig(lastCommitSig []byte, blk *types
}
aggPubKey := consensus.commitBitmap.AggregatePublic
commitPayload := signature.ConstructCommitPayload(consensus.Blockchain(),
commitPayload := signature.ConstructCommitPayload(consensus.Blockchain().Config(),
blk.Epoch(), blk.Hash(), blk.NumberU64(), blk.Header().ViewID().Uint64())
if !aggSig.VerifyHash(aggPubKey, commitPayload) {

@ -10,6 +10,7 @@ import (
msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/registry"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/p2p"
@ -31,7 +32,8 @@ func TestConstructAnnounceMessage(test *testing.T) {
quorum.SuperMajorityVote, shard.BeaconChainShardID,
)
blsPriKey := bls.RandPrivateKey()
consensus, err := New(host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), nil, decider, 3, false)
reg := registry.New()
consensus, err := New(host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), reg, decider, 3, false)
if err != nil {
test.Fatalf("Cannot create consensus: %v", err)
}
@ -63,7 +65,8 @@ func TestConstructPreparedMessage(test *testing.T) {
quorum.SuperMajorityVote, shard.BeaconChainShardID,
)
blsPriKey := bls.RandPrivateKey()
consensus, err := New(host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), nil, decider, 3, false)
reg := registry.New()
consensus, err := New(host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), reg, decider, 3, false)
if err != nil {
test.Fatalf("Cannot craeate consensus: %v", err)
}
@ -143,7 +146,7 @@ func TestConstructPrepareMessage(test *testing.T) {
)
consensus, err := New(
host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey1), nil, decider, 3, false,
host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey1), registry.New(), decider, 3, false,
)
if err != nil {
test.Fatalf("Cannot create consensus: %v", err)
@ -234,7 +237,7 @@ func TestConstructCommitMessage(test *testing.T) {
quorum.SuperMajorityStake, shard.BeaconChainShardID,
)
consensus, err := New(host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey1), nil, decider, 3, false)
consensus, err := New(host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey1), registry.New(), decider, 3, false)
if err != nil {
test.Fatalf("Cannot create consensus: %v", err)
}
@ -316,7 +319,7 @@ func TestPopulateMessageFields(t *testing.T) {
quorum.SuperMajorityVote, shard.BeaconChainShardID,
)
consensus, err := New(
host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), nil, decider, 3, false,
host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsPriKey), registry.New(), decider, 3, false,
)
if err != nil {
t.Fatalf("Cannot craeate consensus: %v", err)

@ -114,7 +114,14 @@ func (consensus *Consensus) spinUpStateSync() {
v.Stop()
}
} else {
consensus.spinLegacyStateSync()
select {
case consensus.BlockNumLowChan <- struct{}{}:
consensus.current.SetMode(Syncing)
for _, v := range consensus.consensusTimeout {
v.Stop()
}
default:
}
}
}

@ -235,7 +235,7 @@ func (consensus *Consensus) onCommit(recvMsg *FBFTMessage) {
Msg("[OnCommit] Failed finding a matching block for committed message")
return
}
commitPayload := signature.ConstructCommitPayload(consensus.Blockchain(),
commitPayload := signature.ConstructCommitPayload(consensus.Blockchain().Config(),
blockObj.Epoch(), blockObj.Hash(), blockObj.NumberU64(), blockObj.Header().ViewID().Uint64())
logger = logger.With().
Uint64("MsgViewID", recvMsg.ViewID).

@ -8,18 +8,14 @@ import (
"github.com/harmony-one/harmony/internal/params"
)
type signatureChainReader interface {
Config() *params.ChainConfig
}
// ConstructCommitPayload returns the commit payload for consensus signatures.
func ConstructCommitPayload(
chain signatureChainReader, epoch *big.Int, blockHash common.Hash, blockNum, viewID uint64,
config *params.ChainConfig, epoch *big.Int, blockHash common.Hash, blockNum, viewID uint64,
) []byte {
blockNumBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(blockNumBytes, blockNum)
commitPayload := append(blockNumBytes, blockHash.Bytes()...)
if !chain.Config().IsStaking(epoch) {
if !config.IsStaking(epoch) {
return commitPayload
}
viewIDBytes := make([]byte, 8)

@ -46,7 +46,7 @@ func (consensus *Consensus) didReachPrepareQuorum() error {
Msg("[didReachPrepareQuorum] Unparseable block data")
return err
}
commitPayload := signature.ConstructCommitPayload(consensus.Blockchain(),
commitPayload := signature.ConstructCommitPayload(consensus.Blockchain().Config(),
blockObj.Epoch(), blockObj.Hash(), blockObj.NumberU64(), blockObj.Header().ViewID().Uint64())
// so by this point, everyone has committed to the blockhash of this block

@ -164,7 +164,7 @@ func (consensus *Consensus) sendCommitMessages(blockObj *types.Block) {
priKeys := consensus.getPriKeysInCommittee()
// Sign commit signature on the received block and construct the p2p messages
commitPayload := signature.ConstructCommitPayload(consensus.Blockchain(),
commitPayload := signature.ConstructCommitPayload(consensus.Blockchain().Config(),
blockObj.Epoch(), blockObj.Hash(), blockObj.NumberU64(), blockObj.Header().ViewID().Uint64())
p2pMsgs := consensus.constructP2pMessages(msg_pb.MessageType_COMMIT, commitPayload, priKeys)

@ -255,13 +255,6 @@ type BlockChain interface {
ReadValidatorStats(
addr common.Address,
) (*types2.ValidatorStats, error)
// UpdateValidatorVotingPower writes the voting power for the committees.
UpdateValidatorVotingPower(
batch rawdb.DatabaseWriter,
block *types.Block,
newEpochSuperCommittee, currentEpochSuperCommittee *shard.State,
state *state.DB,
) (map[common.Address]*types2.ValidatorStats, error)
// ComputeAndUpdateAPR ...
ComputeAndUpdateAPR(
block *types.Block, now *big.Int,

@ -2654,8 +2654,8 @@ func (bc *BlockChainImpl) ReadValidatorStats(
return rawdb.ReadValidatorStats(bc.db, addr)
}
func (bc *BlockChainImpl) UpdateValidatorVotingPower(
batch rawdb.DatabaseWriter,
func UpdateValidatorVotingPower(
bc BlockChain,
block *types.Block,
newEpochSuperCommittee, currentEpochSuperCommittee *shard.State,
state *state.DB,
@ -2681,7 +2681,7 @@ func (bc *BlockChainImpl) UpdateValidatorVotingPower(
// bc.db, currentValidator, currentEpochSuperCommittee.Epoch,
// )
// rawdb.DeleteValidatorStats(bc.db, currentValidator)
stats, err := rawdb.ReadValidatorStats(bc.db, currentValidator)
stats, err := rawdb.ReadValidatorStats(bc.ChainDb(), currentValidator)
if err != nil {
stats = staking.NewEmptyStats()
}
@ -2731,7 +2731,7 @@ func (bc *BlockChainImpl) UpdateValidatorVotingPower(
networkWide := votepower.AggregateRosters(rosters)
for key, value := range networkWide {
stats, err := rawdb.ReadValidatorStats(bc.db, key)
stats, err := rawdb.ReadValidatorStats(bc.ChainDb(), key)
if err != nil {
stats = staking.NewEmptyStats()
}

@ -205,8 +205,8 @@ func (bc *BlockChainImpl) CommitOffChainData(
if shardState, err := shard.DecodeWrapper(
header.ShardState(),
); err == nil {
if stats, err := bc.UpdateValidatorVotingPower(
batch, block, shardState, currentSuperCommittee, state,
if stats, err := UpdateValidatorVotingPower(
bc, block, shardState, currentSuperCommittee, state,
); err != nil {
utils.Logger().
Err(err).

@ -632,7 +632,7 @@ func payloadArgsFromCrossLink(cl types.CrossLink) payloadArgs {
}
func (args payloadArgs) constructPayload(chain engine.ChainReader) []byte {
return signature.ConstructCommitPayload(chain, args.epoch, args.blockHash, args.number, args.viewID)
return signature.ConstructCommitPayload(chain.Config(), args.epoch, args.blockHash, args.number, args.viewID)
}
type sigArgs struct {

@ -275,7 +275,7 @@ func (kp blsKeyPair) Pub() bls.SerializedPublicKey {
func (kp blsKeyPair) Sign(block *types.Block) []byte {
chain := &fakeBlockChain{config: *params.LocalnetChainConfig}
msg := consensus_sig.ConstructCommitPayload(chain, block.Epoch(), block.Hash(),
msg := consensus_sig.ConstructCommitPayload(chain.Config(), block.Epoch(), block.Hash(),
block.Number().Uint64(), block.Header().ViewID().Uint64())
sig := kp.pri.SignHash(msg)

@ -4,12 +4,15 @@ import (
"sync"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/webhooks"
)
// Registry consolidates services at one place.
type Registry struct {
mu sync.Mutex
blockchain core.BlockChain
beaconchain core.BlockChain
webHooks *webhooks.Hooks
txPool *core.TxPool
}
@ -35,6 +38,40 @@ func (r *Registry) GetBlockchain() core.BlockChain {
return r.blockchain
}
// SetBeaconchain sets the beaconchain to registry.
func (r *Registry) SetBeaconchain(bc core.BlockChain) *Registry {
r.mu.Lock()
defer r.mu.Unlock()
r.beaconchain = bc
return r
}
// GetBeaconchain gets the beaconchain from registry.
func (r *Registry) GetBeaconchain() core.BlockChain {
r.mu.Lock()
defer r.mu.Unlock()
return r.beaconchain
}
// SetWebHooks sets the webhooks to registry.
func (r *Registry) SetWebHooks(hooks *webhooks.Hooks) *Registry {
r.mu.Lock()
defer r.mu.Unlock()
r.webHooks = hooks
return r
}
// GetWebHooks gets the webhooks from registry.
func (r *Registry) GetWebHooks() *webhooks.Hooks {
r.mu.Lock()
defer r.mu.Unlock()
return r.webHooks
}
// SetTxPool sets the txpool to registry.
func (r *Registry) SetTxPool(txPool *core.TxPool) *Registry {
r.mu.Lock()

@ -68,7 +68,7 @@ func (node *Node) explorerMessageHandler(ctx context.Context, msg *msg_pb.Messag
return errBlockBeforeCommit
}
commitPayload := signature.ConstructCommitPayload(node.Blockchain(),
commitPayload := signature.ConstructCommitPayload(node.Blockchain().Config(),
block.Epoch(), block.Hash(), block.Number().Uint64(), block.Header().ViewID().Uint64())
if !aggSig.VerifyHash(mask.AggregatePublic, commitPayload) {
utils.Logger().

@ -25,7 +25,6 @@ import (
"github.com/harmony-one/harmony/staking/slash"
staking "github.com/harmony-one/harmony/staking/types"
"github.com/harmony-one/harmony/webhooks"
"github.com/pkg/errors"
)
const p2pMsgPrefixSize = 5
@ -328,38 +327,6 @@ func getCrosslinkHeadersForShards(shardChain core.BlockChain, curBlock *types.Bl
return headers, nil
}
// VerifyNewBlock is called by consensus participants to verify the block (account model) they are
// running consensus on.
func VerifyNewBlock(nodeConfig *nodeconfig.ConfigType, blockChain core.BlockChain, beaconChain core.BlockChain) func(*types.Block) error {
return func(newBlock *types.Block) error {
if err := blockChain.ValidateNewBlock(newBlock, beaconChain); err != nil {
if hooks := nodeConfig.WebHooks.Hooks; hooks != nil {
if p := hooks.ProtocolIssues; p != nil {
url := p.OnCannotCommit
go func() {
webhooks.DoPost(url, map[string]interface{}{
"bad-header": newBlock.Header(),
"reason": err.Error(),
})
}()
}
}
utils.Logger().Error().
Str("blockHash", newBlock.Hash().Hex()).
Int("numTx", len(newBlock.Transactions())).
Int("numStakingTx", len(newBlock.StakingTransactions())).
Err(err).
Msg("[VerifyNewBlock] Cannot Verify New Block!!!")
return errors.Errorf(
"[VerifyNewBlock] Cannot Verify New Block!!! block-hash %s txn-count %d",
newBlock.Hash().Hex(),
len(newBlock.Transactions()),
)
}
return nil
}
}
// PostConsensusProcessing is called by consensus participants, after consensus is done, to:
// 1. [leader] send new block to the client
// 2. [leader] send cross shard tx receipts to destination shard
@ -373,6 +340,7 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block) error {
node.BroadcastCXReceipts(newBlock)
} else {
if node.Consensus.Mode() != consensus.Listening {
numSignatures := node.Consensus.NumSignaturesIncludedInBlock(newBlock)
utils.Logger().Info().
Uint64("blockNum", newBlock.NumberU64()).
Uint64("epochNum", newBlock.Epoch().Uint64()).
@ -380,11 +348,10 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block) error {
Str("blockHash", newBlock.Hash().String()).
Int("numTxns", len(newBlock.Transactions())).
Int("numStakingTxns", len(newBlock.StakingTransactions())).
Uint32("numSignatures", node.Consensus.NumSignaturesIncludedInBlock(newBlock)).
Uint32("numSignatures", numSignatures).
Msg("BINGO !!! Reached Consensus")
numSig := float64(node.Consensus.NumSignaturesIncludedInBlock(newBlock))
node.Consensus.UpdateValidatorMetrics(numSig, float64(newBlock.NumberU64()))
node.Consensus.UpdateValidatorMetrics(float64(numSignatures), float64(newBlock.NumberU64()))
// 1% of the validator also need to do broadcasting
rnd := rand.Intn(100)

@ -103,7 +103,7 @@ func TestVerifyNewBlock(t *testing.T) {
t.Fatal("cannot get blockchain")
}
reg := registry.New().SetBlockchain(blockchain)
consensus, err := consensus.New(
consensusObj, err := consensus.New(
host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsKey), reg, decider, 3, false,
)
if err != nil {
@ -112,7 +112,7 @@ func TestVerifyNewBlock(t *testing.T) {
archiveMode := make(map[uint32]bool)
archiveMode[0] = true
archiveMode[1] = false
node := New(host, consensus, engine, collection, nil, nil, nil, archiveMode, nil, reg)
node := New(host, consensusObj, engine, collection, nil, nil, nil, archiveMode, nil, reg)
txs := make(map[common.Address]types.Transactions)
stks := staking.StakingTransactions{}
@ -129,7 +129,7 @@ func TestVerifyNewBlock(t *testing.T) {
// work around vrf verification as it's tested in another test.
node.Blockchain().Config().VRFEpoch = big.NewInt(2)
if err := VerifyNewBlock(nil, node.Blockchain(), node.Beaconchain())(block); err != nil {
if err := consensus.VerifyNewBlock(nil, node.Blockchain(), node.Beaconchain())(block); err != nil {
t.Error("New block is not verified successfully:", err)
}
}

@ -46,14 +46,15 @@ func TestFinalizeNewBlockAsync(t *testing.T) {
decider := quorum.NewDecider(
quorum.SuperMajorityVote, shard.BeaconChainShardID,
)
consensus, err := consensus.New(
host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsKey), nil, decider, 3, false,
reg := registry.New().SetBlockchain(blockchain).SetBeaconchain(blockchain)
consensusObj, err := consensus.New(
host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsKey), reg, decider, 3, false,
)
if err != nil {
t.Fatalf("Cannot craeate consensus: %v", err)
}
node := New(host, consensus, engine, collection, nil, nil, nil, nil, nil, registry.New().SetBlockchain(blockchain))
node := New(host, consensusObj, engine, collection, nil, nil, nil, nil, nil, registry.New().SetBlockchain(blockchain))
node.Worker.UpdateCurrent()
@ -71,7 +72,7 @@ func TestFinalizeNewBlockAsync(t *testing.T) {
commitSigs, func() uint64 { return 0 }, common.Address{}, nil, nil,
)
if err := VerifyNewBlock(nil, blockchain, nil)(block); err != nil {
if err := consensus.VerifyNewBlock(nil, blockchain, nil)(block); err != nil {
t.Error("New block is not verified successfully:", err)
}

@ -248,7 +248,7 @@ func Verify(
publicKey.Add(publicKeyObj)
}
// slash verification only happens in staking era, therefore want commit payload for staking epoch
commitPayload := consensus_sig.ConstructCommitPayload(chain,
commitPayload := consensus_sig.ConstructCommitPayload(chain.Config(),
candidate.Evidence.Epoch, ballot.BlockHeaderHash, candidate.Evidence.Height, candidate.Evidence.ViewID)
utils.Logger().Debug().
Uint64("epoch", candidate.Evidence.Epoch.Uint64()).

@ -1151,8 +1151,7 @@ func (kp blsKeyPair) Pub() bls.SerializedPublicKey {
}
func (kp blsKeyPair) Sign(block *types.Block) []byte {
chain := &fakeBlockChain{config: *params.LocalnetChainConfig}
msg := consensus_sig.ConstructCommitPayload(chain, block.Epoch(), block.Hash(),
msg := consensus_sig.ConstructCommitPayload(params.LocalnetChainConfig, block.Epoch(), block.Hash(),
block.Number().Uint64(), block.Header().ViewID().Uint64())
sig := kp.pri.SignHash(msg)

@ -1,54 +1 @@
package verify
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/consensus/signature"
"github.com/harmony-one/harmony/core"
bls_cosi "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/shard"
"github.com/pkg/errors"
)
var (
errQuorumVerifyAggSign = errors.New("insufficient voting power to verify aggregate sig")
errAggregateSigFail = errors.New("could not verify hash of aggregate signature")
)
// AggregateSigForCommittee ..
func AggregateSigForCommittee(
chain core.BlockChain,
committee *shard.Committee,
decider quorum.Decider,
aggSignature *bls.Sign,
hash common.Hash,
blockNum, viewID uint64,
epoch *big.Int,
bitmap []byte,
) error {
committerKeys, err := committee.BLSPublicKeys()
if err != nil {
return err
}
mask, err := bls_cosi.NewMask(committerKeys, nil)
if err != nil {
return err
}
if err := mask.SetMask(bitmap); err != nil {
return err
}
if !decider.IsQuorumAchievedByMask(mask) {
return errQuorumVerifyAggSign
}
commitPayload := signature.ConstructCommitPayload(chain, epoch, hash, blockNum, viewID)
if !aggSignature.VerifyHash(mask.AggregatePublic, commitPayload) {
return errAggregateSigFail
}
return nil
}

Loading…
Cancel
Save