iterate over committed blocks

This commit is contained in:
Mark Spanbroek 2024-09-25 11:25:20 +02:00
parent 9dc432ae3c
commit c03cfe66d7
3 changed files with 45 additions and 7 deletions

View File

@ -9,6 +9,7 @@ export validator.nextRound
export validator.propose
export validator.receive
export validator.status
export validator.committed
import ./mysticeti/committee

View File

@ -17,10 +17,11 @@ type
skippedBy: Stake
certifiedBy: Stake
status: ProposalStatus
ProposalStatus* = enum
ProposalStatus* {.pure.} = enum
undecided
toSkip
toCommit
skip
commit
committed
func new*(T: type Validator; identity: Identity, committee: Committee): T =
let round = Round[T.Signing, T.Hashing](number: 0)
@ -65,7 +66,7 @@ func updateSkipped(validator: Validator, supporter: Block) =
if not supporter.hasParent(previous.number, id):
slot.skippedBy += validator.committee.stake(supporter.author)
if slot.skippedBy > 2/3:
slot.status = ProposalStatus.toSkip
slot.status = ProposalStatus.skip
func updateCertified(validator: Validator, certificate: Block) =
without (proposing, voting, _) =? validator.wave:
@ -79,7 +80,7 @@ func updateCertified(validator: Validator, certificate: Block) =
if support > 2/3:
proposerSlot.certifiedBy += validator.committee.stake(certificate.author)
if proposerSlot.certifiedBy > 2/3:
proposerSlot.status = ProposalStatus.toCommit
proposerSlot.status = ProposalStatus.commit
proc propose*(validator: Validator, transactions: seq[Transaction]): auto =
assert validator.identifier notin validator.last.slots
@ -118,3 +119,19 @@ func status*(validator: Validator, blck: Block): ?ProposalStatus =
func status*(validator: Validator, proposal: SignedBlock): ?ProposalStatus =
validator.status(proposal.blck)
iterator committed*(validator: Validator): auto =
var done = false
var current = some validator.first
while not done and round =? current:
for slot in round.slots.mvalues:
case slot.status
of ProposalStatus.undecided:
done = true
break
of ProposalStatus.skip, ProposalStatus.committed:
discard
of ProposalStatus.commit:
slot.status = ProposalStatus.committed
yield slot.proposal
current = round.next

View File

@ -51,7 +51,7 @@ suite "Commitee of Validators":
validators[0].receive(validators[2].propose(seq[Transaction].example))
check validators[0].status(proposal) == some ProposalStatus.undecided
validators[0].receive(validators[3].propose(seq[Transaction].example))
check validators[0].status(proposal) == some ProposalStatus.toSkip
check validators[0].status(proposal) == some ProposalStatus.skip
test "commits blocks that have >2f certificates":
# First round: proposing
@ -65,4 +65,24 @@ suite "Commitee of Validators":
validators[0].receive(validators[1].propose(seq[Transaction].example))
check validators[0].status(proposals[0]) == some ProposalStatus.undecided
validators[0].receive(validators[2].propose(seq[Transaction].example))
check validators[0].status(proposals[0]) == some ProposalStatus.toCommit
check validators[0].status(proposals[0]) == some ProposalStatus.commit
test "can iterate over the list of committed blocks":
let first = exchangeProposals().mapIt(it.blck)
nextRound()
let second = exchangeProposals().mapIt(it.blck)
nextRound()
discard exchangeProposals()
let committedFirst = toSeq(validators[0].committed())
check committedFirst.len == first.len
for blck in first:
check blck in committedFirst
nextRound()
discard exchangeProposals()
let committedSecond = toSeq(validators[0].committed())
check committedSecond.len == second.len
for blck in second:
check blck in committedSecond