mirror of
https://github.com/logos-storage/nim-mysticeti.git
synced 2026-01-05 23:23:08 +00:00
skeleton implementation of validator
This commit is contained in:
parent
4ca2e35e54
commit
93bb47fa3f
15
mysticeti.nim
Normal file
15
mysticeti.nim
Normal 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
9
mysticeti/basics.nim
Normal 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
20
mysticeti/identity.nim
Normal 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
|
||||||
31
mysticeti/transactions.nim
Normal file
31
mysticeti/transactions.nim
Normal 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
63
mysticeti/validator.nim
Normal 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
9
tests/examples.nim
Normal 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
1
tests/nim.cfg
Normal file
@ -0,0 +1 @@
|
|||||||
|
--path:".."
|
||||||
18
tests/testValidator.nim
Normal file
18
tests/testValidator.nim
Normal 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
|
||||||
Loading…
x
Reference in New Issue
Block a user