diff --git a/Specs/Quint/asyncModelsTest.qnt b/Specs/Quint/asyncModelsTest.qnt index 4849b1790..f51e79e23 100644 --- a/Specs/Quint/asyncModelsTest.qnt +++ b/Specs/Quint/asyncModelsTest.qnt @@ -159,7 +159,6 @@ run RoundswitchTest = { .then(N4F0::valStep("v4")) .then(N4F0::valStep("v4")) .then(all { - // this should work, once the bookkeeper skip event is fixed assert(N4F0::system.get("v4").es.cs.round == 1), N4F0::unchangedAll }) diff --git a/Specs/Quint/executor.qnt b/Specs/Quint/executor.qnt index f096a5cd6..9c01323ab 100644 --- a/Specs/Quint/executor.qnt +++ b/Specs/Quint/executor.qnt @@ -479,7 +479,7 @@ pure def executor (es: ExecutorState, input: ExecutorInput) : (ExecutorState, Co res } else if (input.name == "votemessage" and input.vote.step == "Precommit") { - val res = applyVote(es.bk, toVote(input.vote), es.valset.get(input.vote.src)) + val res = applyVote(es.bk, toVote(input.vote), es.valset.get(input.vote.src), es.cs.round) val newES = { ...es, bk: res.bookkeeper, applyvotesResult: res.event} // only a commit event can come here. val cons_res = Precommit(newES, input, res.event) @@ -491,7 +491,7 @@ pure def executor (es: ExecutorState, input: ExecutorInput) : (ExecutorState, Co cons_res } else if (input.name == "votemessage" and input.vote.step == "Prevote") { - val res = applyVote(es.bk, toVote(input.vote), es.valset.get(input.vote.src)) + val res = applyVote(es.bk, toVote(input.vote), es.valset.get(input.vote.src), es.cs.round) val newES = { ...es, bk: res.bookkeeper, applyvotesResult: res.event} // only a commit event can come here. val cons_res = Prevote(newES, input, res.event) @@ -608,4 +608,4 @@ pure def nextActionCommand (state: NodeState, command: str) : (NodeState, Execut (state, defaultInput) } -} \ No newline at end of file +} diff --git a/Specs/Quint/statemachineAsync.qnt b/Specs/Quint/statemachineAsync.qnt index 7f7ec787e..b4b628f51 100644 --- a/Specs/Quint/statemachineAsync.qnt +++ b/Specs/Quint/statemachineAsync.qnt @@ -186,4 +186,4 @@ action step = { } -} \ No newline at end of file +} diff --git a/Specs/Quint/voteBookkeeper.qnt b/Specs/Quint/voteBookkeeper.qnt index a22770bfe..539af2cb6 100644 --- a/Specs/Quint/voteBookkeeper.qnt +++ b/Specs/Quint/voteBookkeeper.qnt @@ -157,7 +157,7 @@ module voteBookkeeper { // TO DISCUSS: // - There might be a problem if we generalize from single-shot to multi-shot: the keeper only keeps the totalWeight // of the current height; I wonder if we need to keep the totalWeight for every Height that we may receive a vote for. - pure def applyVote(keeper: Bookkeeper, vote: Vote, weight: Weight): { bookkeeper: Bookkeeper, event: ExecutorEvent } = + pure def applyVote(keeper: Bookkeeper, vote: Vote, weight: Weight, currentRound: Round): { bookkeeper: Bookkeeper, event: ExecutorEvent } = val height = keeper.height val total = keeper.totalWeight @@ -186,9 +186,9 @@ module voteBookkeeper { val threshold = computeThreshold(updatedVoteCount, vote.value) val event = toEvent(vote.round, vote.typ, threshold) val finalEvent = - if (not(event.in(roundVotes.emittedEvents))) + if (event.name != "None" and not(event.in(roundVotes.emittedEvents))) event - else if (roundVotes.emittedEvents == Set() and isSkip(updatedVotesAddressesWeights.mapSumValues(), total)) + else if (vote.round > currentRound and roundVotes.emittedEvents == Set() and isSkip(updatedVotesAddressesWeights.mapSumValues(), total)) { round: vote.round, name: "Skip", value: "null" } else { round: vote.round, name: "None", value: "null" } diff --git a/Specs/Quint/voteBookkeeperTest.qnt b/Specs/Quint/voteBookkeeperTest.qnt index 3ffa98f44..a4ccbf2a7 100644 --- a/Specs/Quint/voteBookkeeperTest.qnt +++ b/Specs/Quint/voteBookkeeperTest.qnt @@ -25,8 +25,8 @@ module voteBookkeeperTest { lastEmitted' = { round: -1, name: "", value: "null" }, } - action applyVoteAction(vote: Vote, weight: Weight): bool = - val result = applyVote(bookkeeper, vote, weight) + action applyVoteAction(vote: Vote, weight: Weight, currentRound: Round): bool = + val result = applyVote(bookkeeper, vote, weight, currentRound) all { bookkeeper' = result.bookkeeper, lastEmitted' = result.event, @@ -45,33 +45,33 @@ module voteBookkeeperTest { // each of the total voting power run synchronousConsensusTest = init(100) - .then(applyVoteAction({typ: "Prevote", round: 1, value: "proposal", address: "alice"}, 60)) + .then(applyVoteAction({typ: "Prevote", round: 1, value: "proposal", address: "alice"}, 60, 1)) .then(_assert(lastEmitted == {round: 1, name: "None", value: "null"})) - .then(applyVoteAction({typ: "Prevote", round: 1, value: "proposal", address: "john"}, 10)) + .then(applyVoteAction({typ: "Prevote", round: 1, value: "proposal", address: "john"}, 10, 1)) .then(_assert(lastEmitted == {round: 1, name: "PolkaValue", value: "proposal"})) - .then(applyVoteAction({typ: "Prevote", round: 1, value: "proposal", address: "bob"}, 30)) + .then(applyVoteAction({typ: "Prevote", round: 1, value: "proposal", address: "bob"}, 30, 1)) .then(_assert(lastEmitted == {round: 1, name: "None", value: "null"})) - .then(applyVoteAction({typ: "Precommit", round: 1, value: "proposal", address: "bob"}, 30)) + .then(applyVoteAction({typ: "Precommit", round: 1, value: "proposal", address: "bob"}, 30, 1)) .then(_assert(lastEmitted == {round: 1, name: "None", value: "null"})) - .then(applyVoteAction({typ: "Precommit", round: 1, value: "proposal", address: "john"}, 10)) + .then(applyVoteAction({typ: "Precommit", round: 1, value: "proposal", address: "john"}, 10, 1)) .then(_assert(lastEmitted == {round: 1, name: "None", value: "null"})) - .then(applyVoteAction({typ: "Precommit", round: 1, value: "proposal", address: "alice"}, 60)) + .then(applyVoteAction({typ: "Precommit", round: 1, value: "proposal", address: "alice"}, 60, 1)) .then(_assert(lastEmitted == {round: 1, name: "PrecommitValue", value: "proposal"})) // Reaching PolkaAny run polkaAnyTest = init(100) - .then(applyVoteAction({typ: "Prevote", round: 1, value: "val1", address: "alice"}, 60)) + .then(applyVoteAction({typ: "Prevote", round: 1, value: "val1", address: "alice"}, 60, 1)) .then(_assert(lastEmitted == {round: 1, name: "None", value: "null"})) - .then(applyVoteAction({typ: "Prevote", round: 1, value: "nil", address: "john"}, 10)) + .then(applyVoteAction({typ: "Prevote", round: 1, value: "nil", address: "john"}, 10, 1)) .then(_assert(lastEmitted == {round: 1, name: "PolkaAny", value: "null"})) // Reaching PolkaNil run polkaNilTest = init(100) - .then(applyVoteAction({typ: "Prevote", round: 1, value: "nil", address: "alice"}, 60)) + .then(applyVoteAction({typ: "Prevote", round: 1, value: "nil", address: "alice"}, 60, 1)) .then(_assert(lastEmitted == {round: 1, name: "None", value: "null"})) - .then(applyVoteAction({typ: "Prevote", round: 1, value: "nil", address: "john"}, 10)) + .then(applyVoteAction({typ: "Prevote", round: 1, value: "nil", address: "john"}, 10, 1)) .then(_assert(lastEmitted == {round: 1, name: "PolkaNil", value: "null"})) }