diff --git a/mysticeti/validator.nim b/mysticeti/validator.nim index 676619e..3007b05 100644 --- a/mysticeti/validator.nim +++ b/mysticeti/validator.nim @@ -30,10 +30,10 @@ func membership*(validator: Validator): CommitteeMember = validator.membership func round*(validator: Validator): uint64 = - validator.rounds.last.number + validator.rounds.latest.number func nextRound*(validator: Validator) = - validator.rounds.addNextRound() + validator.rounds.addNewRound() func skips(blck: Block, round: uint64, author: CommitteeMember): bool = for parent in blck.parents: @@ -42,7 +42,7 @@ func skips(blck: Block, round: uint64, author: CommitteeMember): bool = true func updateSkipped(validator: Validator, supporter: Block) = - if previous =? validator.rounds.last.previous: + if previous =? validator.rounds.latest.previous: for member in previous.members: let slot = previous[member] if supporter.skips(previous.number, member): @@ -63,29 +63,29 @@ func updateCertified(validator: Validator, certificate: Block) = proposal.certifyBy(certificate.id, stake) proc propose*(validator: Validator, transactions: seq[Transaction]): auto = - assert validator.rounds.last[validator.membership].proposals.len == 0 + assert validator.rounds.latest[validator.membership].proposals.len == 0 var parents: seq[BlockId[Validator.Hashing]] - if previous =? validator.rounds.last.previous: + if previous =? validator.rounds.latest.previous: for slot in previous.slots: if slot.proposals.len == 1: parents.add(slot.proposals[0].blck.id) let blck = Block.new( author = validator.membership, - round = validator.rounds.last.number, + round = validator.rounds.latest.number, parents = parents, transactions = transactions ) - validator.rounds.last.add(blck) + validator.rounds.latest.add(blck) validator.updateCertified(blck) validator.identity.sign(blck) func receive*(validator: Validator, signed: SignedBlock) = - validator.rounds.last.add(signed.blck) + validator.rounds.latest.add(signed.blck) validator.updateSkipped(signed.blck) validator.updateCertified(signed.blck) func status*(validator: Validator, blck: Block): ?SlotStatus = - if round =? validator.rounds.first.find(blck.round): + if round =? validator.rounds.oldest.find(blck.round): some round[blck.author].status else: none SlotStatus @@ -114,8 +114,8 @@ func updateIndirect(validator: Validator, slot: ProposerSlot, round: Round) = iterator committed*(validator: Validator): auto = var done = false - var current = some validator.rounds.first - while not done and round =? current: + while not done: + let round = validator.rounds.oldest for slot in round.slots: if slot.status == SlotStatus.undecided: validator.updateIndirect(slot, round) @@ -128,5 +128,4 @@ iterator committed*(validator: Validator): auto = of SlotStatus.commit: yield slot.commit() if not done: - validator.rounds.remove(round) - current = round.next + validator.rounds.removeOldestRound() diff --git a/mysticeti/validator/rounds.nim b/mysticeti/validator/rounds.nim index 6d10daa..e132b63 100644 --- a/mysticeti/validator/rounds.nim +++ b/mysticeti/validator/rounds.nim @@ -75,40 +75,40 @@ func add*(round: Round, blck: Block): auto = slot.add(blck) type Rounds*[Hashing] = object - first, last: Round[Hashing] + oldest, latest: Round[Hashing] func new*(T: type Rounds, slots: int, start: uint64 = 0): T = let round = Round[T.Hashing].new(start, slots) - T(first: round, last: round) + T(oldest: round, latest: round) -func first*(rounds: Rounds): auto = - rounds.first +func oldest*(rounds: Rounds): auto = + rounds.oldest -func last*(rounds: Rounds): auto = - rounds.last +func latest*(rounds: Rounds): auto = + rounds.latest func wave*(rounds: Rounds): auto = # A wave consists of 3 rounds: proposing -> voting -> certifying - type Round = typeof(rounds.last) - let certifying = rounds.last + type Round = typeof(rounds.latest) + let certifying = rounds.latest if voting =? certifying.previous: if proposing =? voting.previous: return some (proposing, voting, certifying) none (Round, Round, Round) -func addNextRound*(rounds: var Rounds) = - let previous = rounds.last +func addNewRound*(rounds: var Rounds) = + let previous = rounds.latest let next = Round[Rounds.Hashing].new(previous.number + 1, previous.slots.len) next.previous = some previous previous.next = some next - rounds.last = next + rounds.latest = next -func remove*(rounds: var Rounds, round: Round) = - if previous =? round.previous: - previous.next = round.next - else: - rounds.first = !round.next - if next =? round.next: - next.previous = round.previous - else: - rounds.last = !round.previous +func removeOldestRound*(rounds: var Rounds) = + assert rounds.oldest.previous.isNone + assert rounds.oldest.next.isSome + type Round = typeof(rounds.oldest) + let oldest = rounds.oldest + let next = !oldest.next + next.previous = none Round + oldest.next = none Round + rounds.oldest = next diff --git a/tests/mysticeti/validator/testRounds.nim b/tests/mysticeti/validator/testRounds.nim index 501a1f1..637ab84 100644 --- a/tests/mysticeti/validator/testRounds.nim +++ b/tests/mysticeti/validator/testRounds.nim @@ -8,12 +8,12 @@ suite "Validator Rounds": test "members are ordered round-robin for each round": var rounds = Rounds.new(4) - check toSeq(rounds.last.members) == @[0, 1, 2, 3].mapIt(CommitteeMember(it)) - rounds.addNextRound() - check toSeq(rounds.last.members) == @[1, 2, 3, 0].mapIt(CommitteeMember(it)) - rounds.addNextRound() - check toSeq(rounds.last.members) == @[2, 3, 0, 1].mapIt(CommitteeMember(it)) - rounds.addNextRound() - check toSeq(rounds.last.members) == @[3, 0, 1, 2].mapIt(CommitteeMember(it)) - rounds.addNextRound() - check toSeq(rounds.last.members) == @[0, 1, 2, 3].mapIt(CommitteeMember(it)) + check toSeq(rounds.latest.members) == @[0, 1, 2, 3].mapIt(CommitteeMember(it)) + rounds.addNewRound() + check toSeq(rounds.latest.members) == @[1, 2, 3, 0].mapIt(CommitteeMember(it)) + rounds.addNewRound() + check toSeq(rounds.latest.members) == @[2, 3, 0, 1].mapIt(CommitteeMember(it)) + rounds.addNewRound() + check toSeq(rounds.latest.members) == @[3, 0, 1, 2].mapIt(CommitteeMember(it)) + rounds.addNewRound() + check toSeq(rounds.latest.members) == @[0, 1, 2, 3].mapIt(CommitteeMember(it))