當前位置: 首頁>>代碼示例>>Golang>>正文


Golang types.EventStringTimeoutWait函數代碼示例

本文整理匯總了Golang中github.com/tendermint/tendermint/types.EventStringTimeoutWait函數的典型用法代碼示例。如果您正苦於以下問題:Golang EventStringTimeoutWait函數的具體用法?Golang EventStringTimeoutWait怎麽用?Golang EventStringTimeoutWait使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。


在下文中一共展示了EventStringTimeoutWait函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。

示例1: handleTimeout

func (cs *ConsensusState) handleTimeout(ti timeoutInfo, rs RoundState) {
    log.Debug("Received tock", "timeout", ti.Duration, "height", ti.Height, "round", ti.Round, "step", ti.Step)

    // timeouts must be for current height, round, step
    if ti.Height != rs.Height || ti.Round < rs.Round || (ti.Round == rs.Round && ti.Step < rs.Step) {
        log.Debug("Ignoring tock because we're ahead", "height", rs.Height, "round", rs.Round, "step", rs.Step)
        return
    }

    // the timeout will now cause a state transition
    cs.mtx.Lock()
    defer cs.mtx.Unlock()

    switch ti.Step {
    case RoundStepNewHeight:
        // NewRound event fired from enterNewRound.
        // XXX: should we fire timeout here?
        cs.enterNewRound(ti.Height, 0)
    case RoundStepPropose:
        cs.evsw.FireEvent(types.EventStringTimeoutPropose(), cs.RoundStateEvent())
        cs.enterPrevote(ti.Height, ti.Round)
    case RoundStepPrevoteWait:
        cs.evsw.FireEvent(types.EventStringTimeoutWait(), cs.RoundStateEvent())
        cs.enterPrecommit(ti.Height, ti.Round)
    case RoundStepPrecommitWait:
        cs.evsw.FireEvent(types.EventStringTimeoutWait(), cs.RoundStateEvent())
        cs.enterNewRound(ti.Height, ti.Round+1)
    default:
        panic(Fmt("Invalid timeout step: %v", ti.Step))
    }

}
開發者ID:arrivets,項目名稱:tendermint,代碼行數:32,代碼來源:state.go

示例2: TestBadProposal

func TestBadProposal(t *testing.T) {
    css, privVals := simpleConsensusState(2)
    cs1, cs2 := css[0], css[1]
    cs1.newStepCh = make(chan *RoundState) // so it blocks

    timeoutChan := make(chan struct{})
    evsw := events.NewEventSwitch()
    evsw.OnStart()
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) {
        timeoutChan <- struct{}{}
    })
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) {
        timeoutChan <- struct{}{}
    })
    cs1.SetFireable(evsw)

    // make the second validator the proposer
    propBlock := changeProposer(t, cs1, cs2)

    // make the block bad by tampering with statehash
    stateHash := propBlock.StateHash
    stateHash[0] = byte((stateHash[0] + 1) % 255)
    propBlock.StateHash = stateHash
    propBlockParts := propBlock.MakePartSet()
    proposal := types.NewProposal(cs2.Height, cs2.Round, propBlockParts.Header(), cs2.Votes.POLRound())
    if err := cs2.privValidator.SignProposal(cs2.state.ChainID, proposal); err != nil {
        t.Fatal("failed to sign bad proposal", err)
    }

    // start round
    cs1.EnterNewRound(cs1.Height, 0, false)

    // now we're on a new round and not the proposer
    <-cs1.NewStepCh()
    // so set the proposal block (and fix voting power)
    cs1.mtx.Lock()
    cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = proposal, propBlock, propBlockParts
    fixVotingPower(t, cs1, privVals[1].Address)
    cs1.mtx.Unlock()
    // and wait for timeout
    <-timeoutChan

    // go to prevote, prevote for nil (proposal is bad)
    <-cs1.NewStepCh()
    validatePrevote(t, cs1, 0, privVals[0], nil)

    // add bad prevote from cs2. we should precommit nil
    signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header())
    _, _, _ = <-cs1.NewStepCh(), <-timeoutChan, <-cs1.NewStepCh()
    validatePrecommit(t, cs1, 0, 0, privVals[0], nil, nil)
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header())
}
開發者ID:huangjiehua,項目名稱:tendermint,代碼行數:52,代碼來源:state_test.go

示例3: EnterNewRound

// Enter: +2/3 precommits for nil at (height,round-1)
// Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1)
// Enter: `startTime = commitTime+timeoutCommit` from NewHeight(height)
// NOTE: cs.StartTime was already set for height.
func (cs *ConsensusState) EnterNewRound(height int, round int, timedOut bool) {
    cs.mtx.Lock()
    defer cs.mtx.Unlock()
    if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != RoundStepNewHeight) {
        log.Debug(Fmt("EnterNewRound(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))
        return
    }

    if timedOut {
        cs.evsw.FireEvent(types.EventStringTimeoutWait(), cs.RoundStateEvent())
    }

    if now := time.Now(); cs.StartTime.After(now) {
        log.Warn("Need to set a buffer and log.Warn() here for sanity.", "startTime", cs.StartTime, "now", now)
    }
    log.Notice(Fmt("EnterNewRound(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))

    // Increment validators if necessary
    validators := cs.Validators
    if cs.Round < round {
        validators = validators.Copy()
        validators.IncrementAccum(round - cs.Round)
    }

    // Setup new round
    cs.Round = round
    cs.Step = RoundStepNewRound
    cs.Validators = validators
    if round == 0 {
        // We've already reset these upon new height,
        // and meanwhile we might have received a proposal
        // for round 0.
    } else {
        cs.Proposal = nil
        cs.ProposalBlock = nil
        cs.ProposalBlockParts = nil
    }
    cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping

    cs.evsw.FireEvent(types.EventStringNewRound(), cs.RoundStateEvent())

    // Immediately go to EnterPropose.
    go cs.EnterPropose(height, round)
}
開發者ID:huangjiehua,項目名稱:tendermint,代碼行數:48,代碼來源:state.go

示例4: TestHalt1

// 4 vals.
// we receive a final precommit after going into next round, but others might have gone to commit already!
func TestHalt1(t *testing.T) {
    cs1, vss := randConsensusState(4)
    cs2, cs3, cs4 := vss[1], vss[2], vss[3]

    proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
    timeoutWaitCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutWait(), 1)
    newRoundCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringNewRound(), 1)
    newBlockCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringNewBlock(), 1)
    voteCh := subscribeToVoter(cs1, cs1.privValidator.Address)

    // start round and wait for propose and prevote
    startTestRound(cs1, cs1.Height, 0)
    <-newRoundCh
    re := <-proposalCh
    rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
    propBlock := rs.ProposalBlock
    propBlockParts := propBlock.MakePartSet()

    <-voteCh // prevote

    signAddVoteToFromMany(types.VoteTypePrevote, cs1, propBlock.Hash(), propBlockParts.Header(), cs3, cs4)
    <-voteCh // precommit

    // the proposed block should now be locked and our precommit added
    validatePrecommit(t, cs1, 0, 0, vss[0], propBlock.Hash(), propBlock.Hash())

    // add precommits from the rest
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, nil, types.PartSetHeader{}) // didnt receive proposal
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, propBlock.Hash(), propBlockParts.Header())
    // we receive this later, but cs3 might receive it earlier and with ours will go to commit!
    precommit4 := signVote(cs4, types.VoteTypePrecommit, propBlock.Hash(), propBlockParts.Header())

    incrementRound(cs2, cs3, cs4)

    // timeout to new round
    <-timeoutWaitCh
    re = <-newRoundCh
    rs = re.(types.EventDataRoundState).RoundState.(*RoundState)

    log.Notice("### ONTO ROUND 1")
    /*Round2
    // we timeout and prevote our lock
    // a polka happened but we didn't see it!
    */

    // go to prevote, prevote for locked block
    <-voteCh // prevote
    validatePrevote(t, cs1, 0, vss[0], rs.LockedBlock.Hash())

    // now we receive the precommit from the previous round
    addVoteToFrom(cs1, cs4, precommit4)

    // receiving that precommit should take us straight to commit
    <-newBlockCh
    re = <-newRoundCh
    rs = re.(types.EventDataRoundState).RoundState.(*RoundState)

    if rs.Height != 2 {
        t.Fatal("expected height to increment")
    }
}
開發者ID:arrivets,項目名稱:tendermint,代碼行數:63,代碼來源:state_test.go

示例5: TestLockPOLSafety2

// What we want:
// dont see P0, lock on P1 at R1, dont unlock using P0 at R2
func TestLockPOLSafety2(t *testing.T) {
    cs1, vss := randConsensusState(4)
    cs2, cs3, cs4 := vss[1], vss[2], vss[3]

    proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
    timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
    timeoutWaitCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutWait(), 1)
    newRoundCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringNewRound(), 1)
    unlockCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringUnlock(), 1)
    voteCh := subscribeToVoter(cs1, cs1.privValidator.Address)

    // the block for R0: gets polkad but we miss it
    // (even though we signed it, shhh)
    _, propBlock0 := decideProposal(cs1, vss[0], cs1.Height, cs1.Round)
    propBlockHash0 := propBlock0.Hash()
    propBlockParts0 := propBlock0.MakePartSet()

    // the others sign a polka but we don't see it
    prevotes := signVoteMany(types.VoteTypePrevote, propBlockHash0, propBlockParts0.Header(), cs2, cs3, cs4)

    // the block for round 1
    prop1, propBlock1 := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1)
    propBlockHash1 := propBlock1.Hash()
    propBlockParts1 := propBlock1.MakePartSet()

    incrementRound(cs2, cs3, cs4)

    cs1.updateRoundStep(0, RoundStepPrecommitWait)

    log.Notice("### ONTO Round 1")
    // jump in at round 1
    height := cs1.Height
    startTestRound(cs1, height, 1)
    <-newRoundCh

    cs1.SetProposalAndBlock(prop1, propBlock1, propBlockParts1, "some peer")
    <-proposalCh

    <-voteCh // prevote

    signAddVoteToFromMany(types.VoteTypePrevote, cs1, propBlockHash1, propBlockParts1.Header(), cs2, cs3, cs4)

    <-voteCh // precommit
    // the proposed block should now be locked and our precommit added
    validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash1, propBlockHash1)

    // add precommits from the rest
    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4)
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, propBlockHash1, propBlockParts1.Header())

    incrementRound(cs2, cs3, cs4)

    // timeout of precommit wait to new round
    <-timeoutWaitCh

    // in round 2 we see the polkad block from round 0
    newProp := types.NewProposal(height, 2, propBlockParts0.Header(), 0)
    if err := cs3.SignProposal(chainID, newProp); err != nil {
        t.Fatal(err)
    }
    cs1.SetProposalAndBlock(newProp, propBlock0, propBlockParts0, "some peer")
    addVoteToFromMany(cs1, prevotes, cs2, cs3, cs4) // add the pol votes

    <-newRoundCh
    log.Notice("### ONTO Round 2")
    /*Round2
    // now we see the polka from round 1, but we shouldnt unlock
    */

    select {
    case <-timeoutProposeCh:
        <-proposalCh
    case <-proposalCh:
    }

    select {
    case <-unlockCh:
        t.Fatal("validator unlocked using an old polka")
    case <-voteCh:
        // prevote our locked block
    }
    validatePrevote(t, cs1, 2, vss[0], propBlockHash1)

}
開發者ID:arrivets,項目名稱:tendermint,代碼行數:86,代碼來源:state_test.go

示例6: TestLockPOLSafety1

// 4 vals
// a polka at round 1 but we miss it
// then a polka at round 2 that we lock on
// then we see the polka from round 1 but shouldn't unlock
func TestLockPOLSafety1(t *testing.T) {
    cs1, vss := randConsensusState(4)
    cs2, cs3, cs4 := vss[1], vss[2], vss[3]

    proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
    timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
    timeoutWaitCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutWait(), 1)
    newRoundCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringNewRound(), 1)
    voteCh := subscribeToVoter(cs1, cs1.privValidator.Address)

    // start round and wait for propose and prevote
    startTestRound(cs1, cs1.Height, 0)
    <-newRoundCh
    re := <-proposalCh
    rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
    propBlock := rs.ProposalBlock

    <-voteCh // prevote

    validatePrevote(t, cs1, 0, vss[0], propBlock.Hash())

    // the others sign a polka but we don't see it
    prevotes := signVoteMany(types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet().Header(), cs2, cs3, cs4)

    // before we time out into new round, set next proposer
    // and next proposal block
    /*
        _, v1 := cs1.Validators.GetByAddress(vss[0].Address)
        v1.VotingPower = 1
        if updated := cs1.Validators.Update(v1); !updated {
            t.Fatal("failed to update validator")
        }*/

    log.Warn("old prop", "hash", fmt.Sprintf("%X", propBlock.Hash()))

    // we do see them precommit nil
    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3, cs4)

    prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1)
    propBlockHash := propBlock.Hash()
    propBlockParts := propBlock.MakePartSet()

    incrementRound(cs2, cs3, cs4)

    //XXX: this isnt gauranteed to get there before the timeoutPropose ...
    cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer")

    <-newRoundCh
    log.Notice("### ONTO ROUND 1")
    /*Round2
    // we timeout and prevote our lock
    // a polka happened but we didn't see it!
    */

    // now we're on a new round and not the proposer,
    // but we should receive the proposal
    select {
    case re = <-proposalCh:
    case <-timeoutProposeCh:
        re = <-proposalCh
    }

    rs = re.(types.EventDataRoundState).RoundState.(*RoundState)

    if rs.LockedBlock != nil {
        t.Fatal("we should not be locked!")
    }
    log.Warn("new prop", "hash", fmt.Sprintf("%X", propBlockHash))
    // go to prevote, prevote for proposal block
    <-voteCh
    validatePrevote(t, cs1, 1, vss[0], propBlockHash)

    // now we see the others prevote for it, so we should lock on it
    signAddVoteToFromMany(types.VoteTypePrevote, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3, cs4)

    <-voteCh // precommit

    // we should have precommitted
    validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash)

    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3)

    <-timeoutWaitCh

    incrementRound(cs2, cs3, cs4)

    <-newRoundCh

    log.Notice("### ONTO ROUND 2")
    /*Round3
    we see the polka from round 1 but we shouldn't unlock!
    */

    // timeout of propose
    <-timeoutProposeCh

//.........這裏部分代碼省略.........
開發者ID:arrivets,項目名稱:tendermint,代碼行數:101,代碼來源:state_test.go

示例7: TestLockPOLUnlock

// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
func TestLockPOLUnlock(t *testing.T) {
    cs1, vss := randConsensusState(4)
    cs2, cs3, cs4 := vss[1], vss[2], vss[3]

    proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
    timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
    timeoutWaitCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutWait(), 1)
    newRoundCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringNewRound(), 1)
    unlockCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringUnlock(), 1)
    voteCh := subscribeToVoter(cs1, cs1.privValidator.Address)

    // everything done from perspective of cs1

    /*
        Round1 (cs1, B) // B B B B // B nil B nil

        eg. didn't see the 2/3 prevotes
    */

    // start round and wait for propose and prevote
    startTestRound(cs1, cs1.Height, 0)
    <-newRoundCh
    re := <-proposalCh
    rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
    theBlockHash := rs.ProposalBlock.Hash()

    <-voteCh // prevote

    signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4)

    <-voteCh //precommit

    // the proposed block should now be locked and our precommit added
    validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash)

    // add precommits from the rest
    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4)
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header())

    // before we time out into new round, set next proposal block
    prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1)
    propBlockParts := propBlock.MakePartSet()

    incrementRound(cs2, cs3, cs4)

    // timeout to new round
    re = <-timeoutWaitCh
    rs = re.(types.EventDataRoundState).RoundState.(*RoundState)
    lockedBlockHash := rs.LockedBlock.Hash()

    //XXX: this isnt gauranteed to get there before the timeoutPropose ...
    cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer")

    <-newRoundCh
    log.Notice("#### ONTO ROUND 1")
    /*
        Round2 (cs2, C) // B nil nil nil // nil nil nil _

        cs1 unlocks!
    */

    // now we're on a new round and not the proposer,
    // but we should receive the proposal
    select {
    case <-proposalCh:
    case <-timeoutProposeCh:
        <-proposalCh
    }

    // go to prevote, prevote for locked block (not proposal)
    <-voteCh
    validatePrevote(t, cs1, 0, vss[0], lockedBlockHash)
    // now lets add prevotes from everyone else for nil (a polka!)
    signAddVoteToFromMany(types.VoteTypePrevote, cs1, nil, types.PartSetHeader{}, cs2, cs3, cs4)

    // the polka makes us unlock and precommit nil
    <-unlockCh
    <-voteCh // precommit

    // we should have unlocked and committed nil
    // NOTE: since we don't relock on nil, the lock round is 0
    validatePrecommit(t, cs1, 1, 0, vss[0], nil, nil)

    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3)
    <-newRoundCh
}
開發者ID:arrivets,項目名稱:tendermint,代碼行數:87,代碼來源:state_test.go

示例8: TestLockPOLRelock

// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
func TestLockPOLRelock(t *testing.T) {
    cs1, vss := randConsensusState(4)
    cs2, cs3, cs4 := vss[1], vss[2], vss[3]

    timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
    timeoutWaitCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutWait(), 1)
    proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
    voteCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringVote(), 1)
    newRoundCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringNewRound(), 1)
    newBlockCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringNewBlock(), 1)

    log.Debug("cs2 last round", "lr", cs2.PrivValidator.LastRound)

    // everything done from perspective of cs1

    /*
        Round1 (cs1, B) // B B B B// B nil B nil

        eg. cs2 and cs4 didn't see the 2/3 prevotes
    */

    // start round and wait for propose and prevote
    startTestRound(cs1, cs1.Height, 0)

    <-newRoundCh
    re := <-proposalCh
    rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
    theBlockHash := rs.ProposalBlock.Hash()

    <-voteCh // prevote

    signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4)
    _, _, _ = <-voteCh, <-voteCh, <-voteCh // prevotes

    <-voteCh // our precommit
    // the proposed block should now be locked and our precommit added
    validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash)

    // add precommits from the rest
    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4)
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header())
    _, _, _ = <-voteCh, <-voteCh, <-voteCh // precommits

    // before we timeout to the new round set the new proposal
    prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1)
    propBlockParts := propBlock.MakePartSet()
    propBlockHash := propBlock.Hash()

    incrementRound(cs2, cs3, cs4)

    // timeout to new round
    <-timeoutWaitCh

    //XXX: this isnt gauranteed to get there before the timeoutPropose ...
    cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer")

    <-newRoundCh
    log.Notice("### ONTO ROUND 1")

    /*
        Round2 (cs2, C) // B C C C // C C C _)

        cs1 changes lock!
    */

    // now we're on a new round and not the proposer
    // but we should receive the proposal
    select {
    case <-proposalCh:
    case <-timeoutProposeCh:
        <-proposalCh
    }

    // go to prevote, prevote for locked block (not proposal), move on
    <-voteCh
    validatePrevote(t, cs1, 0, vss[0], theBlockHash)

    // now lets add prevotes from everyone else for the new block
    signAddVoteToFromMany(types.VoteTypePrevote, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3, cs4)
    _, _, _ = <-voteCh, <-voteCh, <-voteCh // prevotes

    // now either we go to PrevoteWait or Precommit
    select {
    case <-timeoutWaitCh: // we're in PrevoteWait, go to Precommit
        <-voteCh
    case <-voteCh: // we went straight to Precommit
    }

    // we should have unlocked and locked on the new block
    validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash)

    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3)
    _, _ = <-voteCh, <-voteCh

    be := <-newBlockCh
    b := be.(types.EventDataNewBlock)
    re = <-newRoundCh
    rs = re.(types.EventDataRoundState).RoundState.(*RoundState)
    if rs.Height != 2 {
//.........這裏部分代碼省略.........
開發者ID:arrivets,項目名稱:tendermint,代碼行數:101,代碼來源:state_test.go

示例9: TestLockNoPOL

// two validators, 4 rounds.
// two vals take turns proposing. val1 locks on first one, precommits nil on everything else
func TestLockNoPOL(t *testing.T) {
    cs1, vss := randConsensusState(2)
    cs2 := vss[1]
    height := cs1.Height

    timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
    timeoutWaitCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutWait(), 1)
    voteCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringVote(), 1)
    proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
    newRoundCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringNewRound(), 1)

    /*
        Round1 (cs1, B) // B B // B B2
    */

    // start round and wait for prevote
    cs1.enterNewRound(height, 0)
    cs1.startRoutines(0)

    re := <-proposalCh
    rs := re.(types.EventDataRoundState).RoundState.(*RoundState)
    theBlockHash := rs.ProposalBlock.Hash()

    <-voteCh // prevote

    // we should now be stuck in limbo forever, waiting for more prevotes
    // prevote arrives from cs2:
    signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header())
    <-voteCh // prevote

    <-voteCh // precommit

    // the proposed block should now be locked and our precommit added
    validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash)

    // we should now be stuck in limbo forever, waiting for more precommits
    // lets add one for a different block
    // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round
    hash := make([]byte, len(theBlockHash))
    copy(hash, theBlockHash)
    hash[0] = byte((hash[0] + 1) % 255)
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, rs.ProposalBlock.MakePartSet().Header())
    <-voteCh // precommit

    // (note we're entering precommit for a second time this round)
    // but with invalid args. then we enterPrecommitWait, and the timeout to new round
    <-timeoutWaitCh

    ///

    <-newRoundCh
    log.Notice("#### ONTO ROUND 1")
    /*
        Round2 (cs1, B) // B B2
    */

    incrementRound(cs2)

    // now we're on a new round and not the proposer, so wait for timeout
    re = <-timeoutProposeCh
    rs = re.(types.EventDataRoundState).RoundState.(*RoundState)

    if rs.ProposalBlock != nil {
        t.Fatal("Expected proposal block to be nil")
    }

    // wait to finish prevote
    <-voteCh

    // we should have prevoted our locked block
    validatePrevote(t, cs1, 1, vss[0], rs.LockedBlock.Hash())

    // add a conflicting prevote from the other validator
    signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, hash, rs.ProposalBlock.MakePartSet().Header())
    <-voteCh

    // now we're going to enter prevote again, but with invalid args
    // and then prevote wait, which should timeout. then wait for precommit
    <-timeoutWaitCh

    <-voteCh // precommit

    // the proposed block should still be locked and our precommit added
    // we should precommit nil and be locked on the proposal
    validatePrecommit(t, cs1, 1, 0, vss[0], nil, theBlockHash)

    // add conflicting precommit from cs2
    // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, rs.ProposalBlock.MakePartSet().Header())
    <-voteCh

    // (note we're entering precommit for a second time this round, but with invalid args
    // then we enterPrecommitWait and timeout into NewRound
    <-timeoutWaitCh

    <-newRoundCh
    log.Notice("#### ONTO ROUND 2")
    /*
//.........這裏部分代碼省略.........
開發者ID:arrivets,項目名稱:tendermint,代碼行數:101,代碼來源:state_test.go

示例10: EnterPrecommit

// Enter: +2/3 precomits for block or nil.
// Enter: `timeoutPrevote` after any +2/3 prevotes.
// Enter: any +2/3 precommits for next round.
// Lock & precommit the ProposalBlock if we have enough prevotes for it (a POL in this round)
// else, unlock an existing lock and precommit nil if +2/3 of prevotes were nil,
// else, precommit nil otherwise.
func (cs *ConsensusState) EnterPrecommit(height int, round int, timedOut bool) {
    cs.mtx.Lock()
    defer cs.mtx.Unlock()
    if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPrecommit <= cs.Step) {
        log.Debug(Fmt("EnterPrecommit(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))
        return
    }

    if timedOut {
        cs.evsw.FireEvent(types.EventStringTimeoutWait(), cs.RoundStateEvent())
    }

    log.Info(Fmt("EnterPrecommit(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))

    defer func() {
        // Done EnterPrecommit:
        cs.Round = round
        cs.Step = RoundStepPrecommit
        cs.newStepCh <- cs.getRoundState()
    }()

    hash, partsHeader, ok := cs.Votes.Prevotes(round).TwoThirdsMajority()

    // If we don't have a polka, we must precommit nil
    if !ok {
        if cs.LockedBlock != nil {
            log.Info("EnterPrecommit: No +2/3 prevotes during EnterPrecommit while we're locked. Precommitting nil")
        } else {
            log.Info("EnterPrecommit: No +2/3 prevotes during EnterPrecommit. Precommitting nil.")
        }
        cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{})
        return
    }

    // At this point +2/3 prevoted for a particular block or nil
    cs.evsw.FireEvent(types.EventStringPolka(), cs.RoundStateEvent())

    // the latest POLRound should be this round
    if cs.Votes.POLRound() < round {
        PanicSanity(Fmt("This POLRound should be %v but got %", round, cs.Votes.POLRound()))
    }

    // +2/3 prevoted nil. Unlock and precommit nil.
    if len(hash) == 0 {
        if cs.LockedBlock == nil {
            log.Info("EnterPrecommit: +2/3 prevoted for nil.")
        } else {
            log.Info("EnterPrecommit: +2/3 prevoted for nil. Unlocking")
            cs.LockedRound = 0
            cs.LockedBlock = nil
            cs.LockedBlockParts = nil
            cs.evsw.FireEvent(types.EventStringUnlock(), cs.RoundStateEvent())
        }
        cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{})
        return
    }

    // At this point, +2/3 prevoted for a particular block.

    // If we're already locked on that block, precommit it, and update the LockedRound
    if cs.LockedBlock.HashesTo(hash) {
        log.Info("EnterPrecommit: +2/3 prevoted locked block. Relocking")
        cs.LockedRound = round
        cs.evsw.FireEvent(types.EventStringRelock(), cs.RoundStateEvent())
        cs.signAddVote(types.VoteTypePrecommit, hash, partsHeader)
        return
    }

    // If +2/3 prevoted for proposal block, stage and precommit it
    if cs.ProposalBlock.HashesTo(hash) {
        log.Info("EnterPrecommit: +2/3 prevoted proposal block. Locking", "hash", hash)
        // Validate the block.
        if err := cs.stageBlock(cs.ProposalBlock, cs.ProposalBlockParts); err != nil {
            PanicConsensus(Fmt("EnterPrecommit: +2/3 prevoted for an invalid block: %v", err))
        }
        cs.LockedRound = round
        cs.LockedBlock = cs.ProposalBlock
        cs.LockedBlockParts = cs.ProposalBlockParts
        cs.evsw.FireEvent(types.EventStringLock(), cs.RoundStateEvent())
        cs.signAddVote(types.VoteTypePrecommit, hash, partsHeader)
        return
    }

    // There was a polka in this round for a block we don't have.
    // Fetch that block, unlock, and precommit nil.
    // The +2/3 prevotes for this round is the POL for our unlock.
    // TODO: In the future save the POL prevotes for justification.
    cs.LockedRound = 0
    cs.LockedBlock = nil
    cs.LockedBlockParts = nil
    if !cs.ProposalBlockParts.HasHeader(partsHeader) {
        cs.ProposalBlock = nil
        cs.ProposalBlockParts = types.NewPartSetFromHeader(partsHeader)
    }
//.........這裏部分代碼省略.........
開發者ID:huangjiehua,項目名稱:tendermint,代碼行數:101,代碼來源:state.go

示例11: TestLockPOLSafety2

// 4 vals.
// polka P1 at R1, P2 at R2, and P3 at R3,
// we lock on P1 at R1, don't see P2, and unlock using P3 at R3
// then we should make sure we don't lock using P2
func TestLockPOLSafety2(t *testing.T) {
    css, privVals := simpleConsensusState(4)
    cs1, cs2, cs3, cs4 := css[0], css[1], css[2], css[3]
    cs1.newStepCh = make(chan *RoundState) // so it blocks

    timeoutChan := make(chan *types.EventDataRoundState)
    voteChan := make(chan *types.EventDataVote)
    evsw := events.NewEventSwitch()
    evsw.OnStart()
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) {
        timeoutChan <- data.(*types.EventDataRoundState)
    })
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) {
        timeoutChan <- data.(*types.EventDataRoundState)
    })
    evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) {
        vote := data.(*types.EventDataVote)
        // we only fire for our own votes
        if bytes.Equal(cs1.privValidator.Address, vote.Address) {
            voteChan <- vote
        }
    })
    cs1.SetFireable(evsw)

    // start round and wait for propose and prevote
    cs1.EnterNewRound(cs1.Height, 0, false)
    _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh()

    theBlockHash := cs1.ProposalBlock.Hash()

    donePrecommit := make(chan struct{})
    go func() {
        <-voteChan
        <-cs1.NewStepCh()
        donePrecommit <- struct{}{}
    }()
    signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4)
    <-donePrecommit

    // the proposed block should now be locked and our precommit added
    validatePrecommit(t, cs1, 0, 0, privVals[0], theBlockHash, theBlockHash)

    donePrecommitWait := make(chan struct{})
    go func() {
        <-cs1.NewStepCh()
        donePrecommitWait <- struct{}{}
    }()
    // add precommits from the rest
    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4)
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header())
    <-donePrecommitWait

    // before we time out into new round, set next proposer
    // and next proposal block
    _, v1 := cs1.Validators.GetByAddress(privVals[0].Address)
    v1.VotingPower = 1
    if updated := cs1.Validators.Update(v1); !updated {
        t.Fatal("failed to update validator")
    }

    cs2.decideProposal(cs2.Height, cs2.Round+1)
    prop, propBlock := cs2.Proposal, cs2.ProposalBlock
    if prop == nil || propBlock == nil {
        t.Fatal("Failed to create proposal block with cs2")
    }

    incrementRound(cs2, cs3, cs4)

    // timeout to new round
    <-timeoutChan

    log.Info("### ONTO Round 2")
    /*Round2
    // we timeout and prevote our lock
    // a polka happened but we didn't see it!
    */

    // now we're on a new round and not the proposer, so wait for timeout
    _, _ = <-cs1.NewStepCh(), <-timeoutChan
    // go to prevote, prevote for locked block
    _, _ = <-voteChan, <-cs1.NewStepCh()
    validatePrevote(t, cs1, 0, privVals[0], cs1.LockedBlock.Hash())

    // the others sign a polka but we don't see it
    prevotes := signVoteMany(types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet().Header(), cs2, cs3, cs4)

    // once we see prevotes for the next round we'll skip ahead

    incrementRound(cs2, cs3, cs4)

    log.Info("### ONTO Round 3")
    /*Round3
    a polka for nil causes us to unlock
    */

    // these prevotes will send us straight to precommit at the higher round
//.........這裏部分代碼省略.........
開發者ID:huangjiehua,項目名稱:tendermint,代碼行數:101,代碼來源:state_test.go

示例12: TestLockPOLSafety1

// 4 vals
// a polka at round 1 but we miss it
// then a polka at round 2 that we lock on
// then we see the polka from round 1 but shouldn't unlock
func TestLockPOLSafety1(t *testing.T) {
    css, privVals := simpleConsensusState(4)
    cs1, cs2, cs3, cs4 := css[0], css[1], css[2], css[3]
    cs1.newStepCh = make(chan *RoundState) // so it blocks

    timeoutChan := make(chan *types.EventDataRoundState)
    voteChan := make(chan *types.EventDataVote)
    evsw := events.NewEventSwitch()
    evsw.OnStart()
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) {
        timeoutChan <- data.(*types.EventDataRoundState)
    })
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) {
        timeoutChan <- data.(*types.EventDataRoundState)
    })
    evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) {
        vote := data.(*types.EventDataVote)
        // we only fire for our own votes
        if bytes.Equal(cs1.privValidator.Address, vote.Address) {
            voteChan <- vote
        }
    })
    cs1.SetFireable(evsw)

    // start round and wait for propose and prevote
    cs1.EnterNewRound(cs1.Height, 0, false)
    _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh()

    propBlock := cs1.ProposalBlock

    validatePrevote(t, cs1, 0, privVals[0], cs1.ProposalBlock.Hash())

    // the others sign a polka but we don't see it
    prevotes := signVoteMany(types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet().Header(), cs2, cs3, cs4)

    // before we time out into new round, set next proposer
    // and next proposal block
    _, v1 := cs1.Validators.GetByAddress(privVals[0].Address)
    v1.VotingPower = 1
    if updated := cs1.Validators.Update(v1); !updated {
        t.Fatal("failed to update validator")
    }

    log.Warn("old prop", "hash", fmt.Sprintf("%X", propBlock.Hash()))

    // we do see them precommit nil
    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3, cs4)

    cs2.decideProposal(cs2.Height, cs2.Round+1)
    prop, propBlock := cs2.Proposal, cs2.ProposalBlock
    if prop == nil || propBlock == nil {
        t.Fatal("Failed to create proposal block with cs2")
    }

    incrementRound(cs2, cs3, cs4)

    log.Info("### ONTO ROUND 2")
    /*Round2
    // we timeout and prevote our lock
    // a polka happened but we didn't see it!
    */

    // now we're on a new round and not the proposer,
    <-cs1.NewStepCh()
    // so set proposal
    cs1.mtx.Lock()
    propBlockHash, propBlockParts := propBlock.Hash(), propBlock.MakePartSet()
    cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlockParts
    cs1.mtx.Unlock()
    // and wait for timeout
    <-timeoutChan
    if cs1.LockedBlock != nil {
        t.Fatal("we should not be locked!")
    }
    log.Warn("new prop", "hash", fmt.Sprintf("%X", propBlockHash))
    // go to prevote, prevote for proposal block
    _, _ = <-voteChan, <-cs1.NewStepCh()
    validatePrevote(t, cs1, 1, privVals[0], propBlockHash)

    // now we see the others prevote for it, so we should lock on it
    donePrecommit := make(chan struct{})
    go func() {
        select {
        case <-cs1.NewStepCh(): // we're in PrevoteWait, go to Precommit
            <-voteChan
        case <-voteChan: // we went straight to Precommit
        }
        <-cs1.NewStepCh()
        donePrecommit <- struct{}{}
    }()
    // now lets add prevotes from everyone else for nil
    signAddVoteToFromMany(types.VoteTypePrevote, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3, cs4)
    <-donePrecommit

    // we should have precommitted
    validatePrecommit(t, cs1, 1, 1, privVals[0], propBlockHash, propBlockHash)
//.........這裏部分代碼省略.........
開發者ID:huangjiehua,項目名稱:tendermint,代碼行數:101,代碼來源:state_test.go

示例13: TestLockPOLUnlock

// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
func TestLockPOLUnlock(t *testing.T) {
    css, privVals := simpleConsensusState(4)
    cs1, cs2, cs3, cs4 := css[0], css[1], css[2], css[3]
    cs1.newStepCh = make(chan *RoundState) // so it blocks

    timeoutChan := make(chan *types.EventDataRoundState)
    voteChan := make(chan *types.EventDataVote)
    evsw := events.NewEventSwitch()
    evsw.OnStart()
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) {
        timeoutChan <- data.(*types.EventDataRoundState)
    })
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) {
        timeoutChan <- data.(*types.EventDataRoundState)
    })
    evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) {
        vote := data.(*types.EventDataVote)
        // we only fire for our own votes
        if bytes.Equal(cs1.privValidator.Address, vote.Address) {
            voteChan <- vote
        }
    })
    cs1.SetFireable(evsw)

    // everything done from perspective of cs1

    /*
        Round1 (cs1, B) // B B B B // B nil B nil

        eg. didn't see the 2/3 prevotes
    */

    // start round and wait for propose and prevote
    cs1.EnterNewRound(cs1.Height, 0, false)
    _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh()

    theBlockHash := cs1.ProposalBlock.Hash()

    donePrecommit := make(chan struct{})
    go func() {
        <-voteChan
        <-cs1.NewStepCh()
        donePrecommit <- struct{}{}
    }()
    signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4)
    <-donePrecommit

    // the proposed block should now be locked and our precommit added
    validatePrecommit(t, cs1, 0, 0, privVals[0], theBlockHash, theBlockHash)

    donePrecommitWait := make(chan struct{})
    go func() {
        <-cs1.NewStepCh()
        donePrecommitWait <- struct{}{}
    }()
    // add precommits from the rest
    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4)
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header())
    <-donePrecommitWait

    // before we time out into new round, set next proposer
    // and next proposal block
    _, v1 := cs1.Validators.GetByAddress(privVals[0].Address)
    v1.VotingPower = 1
    if updated := cs1.Validators.Update(v1); !updated {
        t.Fatal("failed to update validator")
    }

    cs2.decideProposal(cs2.Height, cs2.Round+1)
    prop, propBlock := cs2.Proposal, cs2.ProposalBlock
    if prop == nil || propBlock == nil {
        t.Fatal("Failed to create proposal block with cs2")
    }

    incrementRound(cs2, cs3, cs4)

    // timeout to new round
    <-timeoutChan

    log.Info("#### ONTO ROUND 2")
    /*
        Round2 (cs2, C) // B nil nil nil // nil nil nil _

        cs1 unlocks!
    */

    // now we're on a new round and not the proposer,
    <-cs1.NewStepCh()
    cs1.mtx.Lock()
    // so set the proposal block
    cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlock.MakePartSet()
    lockedBlockHash := cs1.LockedBlock.Hash()
    cs1.mtx.Unlock()
    // and wait for timeout
    <-timeoutChan

    // go to prevote, prevote for locked block (not proposal)
    _, _ = <-voteChan, <-cs1.NewStepCh()
    validatePrevote(t, cs1, 0, privVals[0], lockedBlockHash)
//.........這裏部分代碼省略.........
開發者ID:huangjiehua,項目名稱:tendermint,代碼行數:101,代碼來源:state_test.go

示例14: TestLockPOLRelock

// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
func TestLockPOLRelock(t *testing.T) {
    css, privVals := simpleConsensusState(4)
    cs1, cs2, cs3, cs4 := css[0], css[1], css[2], css[3]
    cs1.newStepCh = make(chan *RoundState) // so it blocks

    timeoutChan := make(chan *types.EventDataRoundState)
    voteChan := make(chan *types.EventDataVote)
    evsw := events.NewEventSwitch()
    evsw.OnStart()
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) {
        timeoutChan <- data.(*types.EventDataRoundState)
    })
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) {
        timeoutChan <- data.(*types.EventDataRoundState)
    })
    evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) {
        vote := data.(*types.EventDataVote)
        // we only fire for our own votes
        if bytes.Equal(cs1.privValidator.Address, vote.Address) {
            voteChan <- vote
        }
    })
    cs1.SetFireable(evsw)

    // everything done from perspective of cs1

    /*
        Round1 (cs1, B) // B B B B// B nil B nil

        eg. cs2 and cs4 didn't see the 2/3 prevotes
    */

    // start round and wait for propose and prevote
    cs1.EnterNewRound(cs1.Height, 0, false)
    _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh()

    theBlockHash := cs1.ProposalBlock.Hash()

    // wait to finish precommit after prevotes done
    // we do this in a go routine with another channel since otherwise
    // we may get deadlock with EnterPrecommit waiting to send on newStepCh and the final
    // signAddVoteToFrom waiting for the cs.mtx.Lock
    donePrecommit := make(chan struct{})
    go func() {
        <-voteChan
        <-cs1.NewStepCh()
        donePrecommit <- struct{}{}
    }()
    signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4)
    <-donePrecommit

    // the proposed block should now be locked and our precommit added
    validatePrecommit(t, cs1, 0, 0, privVals[0], theBlockHash, theBlockHash)

    donePrecommitWait := make(chan struct{})
    go func() {
        // (note we're entering precommit for a second time this round)
        // but with invalid args. then we EnterPrecommitWait, twice (?)
        <-cs1.NewStepCh()
        donePrecommitWait <- struct{}{}
    }()
    // add precommits from the rest
    signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4)
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header())
    <-donePrecommitWait

    // before we time out into new round, set next proposer
    // and next proposal block
    _, v1 := cs1.Validators.GetByAddress(privVals[0].Address)
    v1.VotingPower = 1
    if updated := cs1.Validators.Update(v1); !updated {
        t.Fatal("failed to update validator")
    }

    cs2.decideProposal(cs2.Height, cs2.Round+1)
    prop, propBlock := cs2.Proposal, cs2.ProposalBlock
    if prop == nil || propBlock == nil {
        t.Fatal("Failed to create proposal block with cs2")
    }

    incrementRound(cs2, cs3, cs4)

    // timeout to new round
    te := <-timeoutChan
    if te.Step != RoundStepPrecommitWait.String() {
        t.Fatalf("expected to timeout of precommit into new round. got %v", te.Step)
    }

    log.Info("### ONTO ROUND 2")

    /*
        Round2 (cs2, C) // B C C C // C C C _)

        cs1 changes lock!
    */

    // now we're on a new round and not the proposer
    <-cs1.NewStepCh()
    cs1.mtx.Lock()
//.........這裏部分代碼省略.........
開發者ID:huangjiehua,項目名稱:tendermint,代碼行數:101,代碼來源:state_test.go

示例15: TestLockNoPOL

// two validators, 4 rounds.
// val1 proposes the first 2 rounds, and is locked in the first.
// val2 proposes the next two. val1 should precommit nil on all (except first where he locks)
func TestLockNoPOL(t *testing.T) {
    css, privVals := simpleConsensusState(2)
    cs1, cs2 := css[0], css[1]
    cs1.newStepCh = make(chan *RoundState) // so it blocks

    timeoutChan := make(chan struct{})
    evsw := events.NewEventSwitch()
    evsw.OnStart()
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) {
        timeoutChan <- struct{}{}
    })
    evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) {
        timeoutChan <- struct{}{}
    })
    cs1.SetFireable(evsw)

    /*
        Round1 (cs1, B) // B B // B B2
    */

    // start round and wait for propose and prevote
    cs1.EnterNewRound(cs1.Height, 0, false)
    _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh()

    // we should now be stuck in limbo forever, waiting for more prevotes
    // prevote arrives from cs2:
    signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header())

    cs1.mtx.Lock() // XXX: sigh
    theBlockHash := cs1.ProposalBlock.Hash()
    cs1.mtx.Unlock()

    // wait to finish precommit
    <-cs1.NewStepCh()

    // the proposed block should now be locked and our precommit added
    validatePrecommit(t, cs1, 0, 0, privVals[0], theBlockHash, theBlockHash)

    // we should now be stuck in limbo forever, waiting for more precommits
    // lets add one for a different block
    // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round
    hash := cs1.ProposalBlock.Hash()
    hash[0] = byte((hash[0] + 1) % 255)
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header())

    // (note we're entering precommit for a second time this round)
    // but with invalid args. then we EnterPrecommitWait, and the timeout to new round
    _, _ = <-cs1.NewStepCh(), <-timeoutChan

    log.Info("#### ONTO ROUND 2")
    /*
        Round2 (cs1, B) // B B2
    */

    incrementRound(cs2)

    // go to prevote
    <-cs1.NewStepCh()

    // now we're on a new round and the proposer
    if cs1.ProposalBlock != cs1.LockedBlock {
        t.Fatalf("Expected proposal block to be locked block. Got %v, Expected %v", cs1.ProposalBlock, cs1.LockedBlock)
    }

    // wait to finish prevote
    <-cs1.NewStepCh()

    // we should have prevoted our locked block
    validatePrevote(t, cs1, 1, privVals[0], cs1.LockedBlock.Hash())

    // add a conflicting prevote from the other validator
    signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, hash, cs1.ProposalBlockParts.Header())

    // now we're going to enter prevote again, but with invalid args
    // and then prevote wait, which should timeout. then wait for precommit
    _, _, _ = <-cs1.NewStepCh(), <-timeoutChan, <-cs1.NewStepCh()

    // the proposed block should still be locked and our precommit added
    // we should precommit nil and be locked on the proposal
    validatePrecommit(t, cs1, 1, 0, privVals[0], nil, theBlockHash)

    // add conflicting precommit from cs2
    // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round
    signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header())

    // (note we're entering precommit for a second time this round, but with invalid args
    // then we EnterPrecommitWait and timeout into NewRound
    _, _ = <-cs1.NewStepCh(), <-timeoutChan

    log.Info("#### ONTO ROUND 3")
    /*
        Round3 (cs2, _) // B, B2
    */

    incrementRound(cs2)

    // now we're on a new round and not the proposer, so wait for timeout
//.........這裏部分代碼省略.........
開發者ID:huangjiehua,項目名稱:tendermint,代碼行數:101,代碼來源:state_test.go


注:本文中的github.com/tendermint/tendermint/types.EventStringTimeoutWait函數示例由純淨天空整理自Github/MSDocs等開源代碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。