From a666e14ef3f5df62cc971f83aa5088420dffd598 Mon Sep 17 00:00:00 2001 From: Rongjian Lan Date: Tue, 20 Oct 2020 17:30:35 -0700 Subject: [PATCH] Add more tests --- consensus/engine/consensus_engine.go | 1 + node/node_newblock.go | 22 ++++----- node/node_newblock_test.go | 73 ++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 node/node_newblock_test.go diff --git a/consensus/engine/consensus_engine.go b/consensus/engine/consensus_engine.go index 8e6489107..f1f6bb46d 100644 --- a/consensus/engine/consensus_engine.go +++ b/consensus/engine/consensus_engine.go @@ -111,6 +111,7 @@ type Engine interface { // Note: The block header and state database might be updated to reflect any // consensus rules that happen at finalization (e.g. block rewards). // sigsReady signal indicates whether the commit sigs are populated in the header object. + // Finalize() will block on sigsReady signal until the first value is send to the channel. Finalize( chain ChainReader, header *block.Header, state *state.DB, txs []*types.Transaction, diff --git a/node/node_newblock.go b/node/node_newblock.go index 8cc9757ff..fcfd45461 100644 --- a/node/node_newblock.go +++ b/node/node_newblock.go @@ -53,7 +53,7 @@ func (node *Node) WaitForConsensusReadyV2(readySignal chan struct{}, stopChan ch node.Consensus.StartFinalityCount() if err != nil { - utils.Logger().Error().Err(err).Msg("[proposeNewBlock] Cannot get commit signatures from last block") + utils.Logger().Error().Err(err).Msg("[ProposeNewBlock] Cannot get commit signatures from last block") break } // Currently the block proposal is not triggered asynchronously yet with last consensus. @@ -89,8 +89,8 @@ func (node *Node) WaitForConsensusReadyV2(readySignal chan struct{}, stopChan ch func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) { currentHeader := node.Blockchain().CurrentHeader() nowEpoch, blockNow := currentHeader.Epoch(), currentHeader.Number() - utils.AnalysisStart("proposeNewBlock", nowEpoch, blockNow) - defer utils.AnalysisEnd("proposeNewBlock", nowEpoch, blockNow) + utils.AnalysisStart("ProposeNewBlock", nowEpoch, blockNow) + defer utils.AnalysisEnd("ProposeNewBlock", nowEpoch, blockNow) node.Worker.UpdateCurrent() @@ -111,7 +111,7 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) emptyAddr := common.Address{} if coinbase == emptyAddr { - return nil, errors.New("[proposeNewBlock] Failed setting coinbase") + return nil, errors.New("[ProposeNewBlock] Failed setting coinbase") } // Must set coinbase here because the operations below depend on it @@ -192,7 +192,7 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) if err == nil || exist != nil { invalidToDelete = append(invalidToDelete, pending) utils.Logger().Debug(). - AnErr("[proposeNewBlock] pending crosslink is already committed onchain", err) + AnErr("[ProposeNewBlock] pending crosslink is already committed onchain", err) continue } @@ -200,19 +200,19 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) // no need to verify again in proposal. if !node.Blockchain().Config().IsCrossLink(pending.Epoch()) { utils.Logger().Debug(). - AnErr("[proposeNewBlock] pending crosslink that's before crosslink epoch", err) + AnErr("[ProposeNewBlock] pending crosslink that's before crosslink epoch", err) continue } crossLinksToPropose = append(crossLinksToPropose, pending) } utils.Logger().Info(). - Msgf("[proposeNewBlock] Proposed %d crosslinks from %d pending crosslinks", + Msgf("[ProposeNewBlock] Proposed %d crosslinks from %d pending crosslinks", len(crossLinksToPropose), len(allPending), ) } else { utils.Logger().Error().Err(err).Msgf( - "[proposeNewBlock] Unable to Read PendingCrossLinks, number of crosslinks: %d", + "[ProposeNewBlock] Unable to Read PendingCrossLinks, number of crosslinks: %d", len(allPending), ) } @@ -240,14 +240,14 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) coinbase, crossLinksToPropose, shardState, ) if err != nil { - utils.Logger().Error().Err(err).Msg("[proposeNewBlock] Failed finalizing the new block") + utils.Logger().Error().Err(err).Msg("[ProposeNewBlock] Failed finalizing the new block") return nil, err } - utils.Logger().Info().Msg("[proposeNewBlock] verifying the new block header") + utils.Logger().Info().Msg("[ProposeNewBlock] verifying the new block header") err = node.Blockchain().Validator().ValidateHeader(finalizedBlock, true) if err != nil { - utils.Logger().Error().Err(err).Msg("[proposeNewBlock] Failed verifying the new block header") + utils.Logger().Error().Err(err).Msg("[ProposeNewBlock] Failed verifying the new block header") return nil, err } return finalizedBlock, nil diff --git a/node/node_newblock_test.go b/node/node_newblock_test.go new file mode 100644 index 000000000..32cb36673 --- /dev/null +++ b/node/node_newblock_test.go @@ -0,0 +1,73 @@ +package node + +import ( + "strings" + "testing" + + "github.com/harmony-one/harmony/internal/shardchain" + + "github.com/ethereum/go-ethereum/common" + "github.com/harmony-one/harmony/consensus" + "github.com/harmony-one/harmony/consensus/quorum" + "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/crypto/bls" + "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/multibls" + "github.com/harmony-one/harmony/p2p" + "github.com/harmony-one/harmony/shard" + staking "github.com/harmony-one/harmony/staking/types" +) + +func TestFinalizeNewBlockAsync(t *testing.T) { + blsKey := bls.RandPrivateKey() + pubKey := blsKey.GetPublicKey() + leader := p2p.Peer{IP: "127.0.0.1", Port: "8882", ConsensusPubKey: pubKey} + priKey, _, _ := utils.GenKeyP2P("127.0.0.1", "9902") + host, err := p2p.NewHost(&leader, priKey) + if err != nil { + t.Fatalf("newhost failure: %v", err) + } + decider := quorum.NewDecider( + quorum.SuperMajorityVote, shard.BeaconChainShardID, + ) + consensus, err := consensus.New( + host, shard.BeaconChainShardID, leader, multibls.GetPrivateKeys(blsKey), decider, + ) + if err != nil { + t.Fatalf("Cannot craeate consensus: %v", err) + } + var testDBFactory = &shardchain.MemDBFactory{} + node := New(host, consensus, testDBFactory, nil, false) + + node.Worker.UpdateCurrent() + + txs := make(map[common.Address]types.Transactions) + stks := staking.StakingTransactions{} + node.Worker.CommitTransactions( + txs, stks, common.Address{}, + ) + commitSigs := make(chan []byte) + go func() { + commitSigs <- []byte{} + }() + + block, _ := node.Worker.FinalizeNewBlock( + commitSigs, 0, common.Address{}, nil, nil, + ) + + if err := node.VerifyNewBlock(block); err != nil { + t.Error("New block is not verified successfully:", err) + } + + node.Blockchain().InsertChain(types.Blocks{block}, false) + + node.Worker.UpdateCurrent() + + _, err = node.Worker.FinalizeNewBlock( + commitSigs, 0, common.Address{}, nil, nil, + ) + + if !strings.Contains(err.Error(), "cannot finalize block") { + t.Error("expect timeout on FinalizeNewBlock") + } +}