skeleton implementation of validator

This commit is contained in:
Mark Spanbroek 2024-08-20 10:45:49 +02:00
parent 4ca2e35e54
commit 93bb47fa3f
8 changed files with 166 additions and 0 deletions

15
mysticeti.nim Normal file
View File

@ -0,0 +1,15 @@
import ./mysticeti/validator
export validator.Validator
export validator.ProposalStatus
export validator.new
export validator.nextRound
export validator.propose
export validator.receive
export validator.status
import ./mysticeti/transactions
export transactions.Transaction
export transactions.Block
export transactions.round

9
mysticeti/basics.nim Normal file
View File

@ -0,0 +1,9 @@
import std/tables
export tables
import pkg/questionable
import pkg/questionable/results
export questionable
export results

20
mysticeti/identity.nim Normal file
View File

@ -0,0 +1,20 @@
type Identity* = object
type Identifier* = object
func init*(_: type Identity): Identity =
Identity()
func identifier*(identity: Identity): Identifier =
discard
type Signed*[T] = object
value: T
func sign*[T](identity: Identity, value: T): Signed[T] =
Signed[T](value: value)
func value*[T](signed: Signed[T]): T =
signed.value
func signatories*[T](signed: Signed[T]): seq[Identifier] =
discard

View File

@ -0,0 +1,31 @@
import ./identity
type Transaction* = object
type
Block* = object
author: Identifier
round: uint64
parents: seq[BlockHash]
transactions: seq[Transaction]
BlockHash* = object
func new*(
_: type Block,
author: Identifier,
round: uint64,
parents: seq[BlockHash],
transactions: seq[Transaction]
): Block =
Block(
author: author,
round: round,
parents: parents,
transactions: transactions
)
func author*(blck: Block): Identifier =
blck.author
func round*(blck: Block): uint64 =
blck.round

63
mysticeti/validator.nim Normal file
View File

@ -0,0 +1,63 @@
import ./basics
import ./identity
import ./transactions
type
Validator* = ref object
identity: Identity
round: Round
Round = ref object
number: uint64
previous: ?Round
proposals: Table[Identifier, seq[Proposal]]
Proposal = object
blck: Block
status: ProposalStatus
ProposalStatus* = enum
undecided
toSkip
toCommit
func new*(_: type Validator): Validator =
Validator(identity: Identity.init(), round: Round(number: 0))
func identifier*(validator: Validator): Identifier =
validator.identity.identifier
func nextRound*(validator: Validator) =
let previous = validator.round
validator.round = Round(number: previous.number + 1, previous: some previous)
func propose*(validator: Validator, transactions: seq[Transaction]): Signed[Block] =
var parents: seq[BlockHash]
let blck = Block.new(
author = validator.identifier,
round = validator.round.number,
parents = parents,
transactions = transactions
)
let proposal = Proposal(blck: blck)
validator.round.proposals[validator.identifier] = @[proposal]
validator.identity.sign(blck)
func receive*(validator: Validator, proposal: Signed[Block]) =
discard
func round(validator: Validator, number: uint64): ?Round =
var round = validator.round
while round.number > number and previous =? round.previous:
round = previous
if round.number == number:
some round
else:
none Round
func status*(validator: Validator, blck: Block): ?ProposalStatus =
if round =? round(validator, blck.round) and blck.author in round.proposals:
let proposal = round.proposals[blck.author][0]
some proposal.status
else:
none ProposalStatus
func status*(validator: Validator, proposal: Signed[Block]): ?ProposalStatus =
validator.status(proposal.value)

9
tests/examples.nim Normal file
View File

@ -0,0 +1,9 @@
import std/random
import std/sequtils
import mysticeti
proc example*(_: type Transaction): Transaction =
discard
proc example*[T](_: type seq[T], length=0..10): seq[T] =
newSeqWith(rand(length), T.example)

1
tests/nim.cfg Normal file
View File

@ -0,0 +1 @@
--path:".."

18
tests/testValidator.nim Normal file
View File

@ -0,0 +1,18 @@
import std/unittest
import pkg/questionable
import mysticeti
import ./examples
suite "Validator":
var validator: Validator
var validator2, validator3: Validator
setup:
validator = Validator.new()
validator2 = Validator.new()
validator3 = Validator.new()
test "by default proposals are undecided":
let proposal = validator.propose(seq[Transaction].example)
check validator.status(proposal) == some ProposalStatus.undecided