add tests for proposer slots

This commit is contained in:
Mark Spanbroek 2024-10-16 15:08:24 +02:00
parent 87da1b774d
commit c3b8429ed6
4 changed files with 98 additions and 2 deletions

View File

@ -15,6 +15,7 @@ export validator.committed
import ./mysticeti/committee
export committee.Committee
export committee.Stake
export committee.new
export committee.CommitteeMember
export committee.`==`

View File

@ -22,8 +22,6 @@ func proposals*(slot: ProposerSlot): auto =
slot.proposals
func proposal*(slot: ProposerSlot): auto =
if slot.proposals.len == 1:
return some slot.proposals[0]
if slot.status in [SlotStatus.commit, SlotStatus.committed]:
for proposal in slot.proposals:
if proposal.certifiedBy > 2/3:

View File

@ -0,0 +1,96 @@
import ../basics
import mysticeti
import mysticeti/validator/slots
suite "Proposer Slots":
type Block = mysticeti.Block[MockHashing]
type BlockId = mysticeti.BlockId[MockHashing]
type Proposal = slots.Proposal[MockHashing]
type ProposerSlot = slots.ProposerSlot[MockHashing]
var slot: ProposerSlot
setup:
slot = ProposerSlot.new()
test "slots are undecided by default":
check slot.status == SlotStatus.undecided
test "slots have no proposals initially":
check slot.proposals.len == 0
test "slots have not chosen a proposal initially":
check slot.proposal == none Proposal
test "blocks can be added to slots, and they become proposals":
let blocks = seq[Block].example
for blck in blocks:
slot.add(blck)
for blck in blocks:
check slot.proposals.anyIt(it.blck == blck)
test "proposals have no certificates initially":
slot.add(Block.example)
let proposal = slot.proposals[0]
check proposal.certificates.len == 0
test "proposals can be certified by other blocks":
slot.add(Block.example)
let proposal = slot.proposals[0]
let certificate1, certificate2 = BlockId.example
proposal.certifyBy(certificate1, Stake(1/9))
proposal.certifyBy(certificate2, Stake(2/9))
check proposal.certificates == @[certificate1, certificate2]
test "slots can be committed when a proposal is certified by >2/3 stake":
slot.add(Block.example)
let proposal = slot.proposals[0]
proposal.certifyBy(BlockId.example, 1/3)
check slot.status == SlotStatus.undecided
proposal.certifyBy(BlockId.example, 1/3)
check slot.status == SlotStatus.undecided
proposal.certifyBy(BlockId.example, 1/1000)
check slot.status == SlotStatus.commit
test "slots choose a proposal when it is certified by >2/3 stake":
slot.add(Block.example)
slot.add(Block.example)
let proposal = slot.proposals[1]
proposal.certifyBy(BlockId.example, 1/3)
check slot.proposal == none Proposal
proposal.certifyBy(BlockId.example, 1/3)
check slot.proposal == none Proposal
proposal.certifyBy(BlockId.example, 1/1000)
check slot.proposal == some proposal
test "proposals can be certified by an anchor":
let anchor = ProposerSlot.new()
anchor.add(Block.example)
anchor.proposals[0].certifyBy(BlockId.example, 3/4)
slot.add(Block.example)
let proposal = slot.proposals[0]
proposal.certify(!anchor.proposal)
check slot.status == SlotStatus.commit
check slot.proposal == some proposal
test "committing a slot marks it as committed and returns the chosen block":
let block1, block2 = Block.example
slot.add(block1)
slot.add(block2)
let proposal = slot.proposals[1]
proposal.certifyBy(BlockId.example, 3/4)
check slot.commit() == block2
check slot.status == SlotStatus.committed
test "slots can be skipped when >2/3 stake skip it":
slot.skipBy(1/3)
check slot.status == SlotStatus.undecided
slot.skipBy(1/3)
check slot.status == SlotStatus.undecided
slot.skipBy(1/1000)
check slot.status == SlotStatus.skip
test "slots can be skipped immediately":
slot.skip()
check slot.status == SlotStatus.skip

View File

@ -1,5 +1,6 @@
import ./mysticeti/testCommittee
import ./mysticeti/testBlocks
import ./mysticeti/validator/testSlots
import ./mysticeti/validator/testSingle
import ./mysticeti/validator/testMultiple