Finish network simulator
This commit is contained in:
parent
f6a66c8d3c
commit
3bc75711d5
|
@ -17,15 +17,7 @@ import
|
|||
# Nimble packages
|
||||
nimcrypto,
|
||||
# Local imports
|
||||
./fork_choice_types, ./networksim
|
||||
|
||||
###########################################################
|
||||
# Forward declarations
|
||||
|
||||
method on_receive(self: Node, obj: BlockOrSig, reprocess = false) {.base.} =
|
||||
raise newException(ValueError, "Not implemented error. Please implement in child types")
|
||||
|
||||
###########################################################
|
||||
./fork_choice_types
|
||||
|
||||
proc broadcast(self: Node, x: BlockOrSig) =
|
||||
if self.sleepy and self.timestamp != DurationZero:
|
||||
|
@ -48,8 +40,8 @@ func add_to_multiset[K, V](
|
|||
multiset: TableRef[K, seq[V]],
|
||||
k: K,
|
||||
v: V or seq[V]) =
|
||||
if k notin multiset:
|
||||
multiset[k] = @[]
|
||||
# if k notin multiset: # Unneeded with seq "not nil" changes
|
||||
# multiset[k] = @[]
|
||||
multiset[k].add v
|
||||
|
||||
func change_head(self: Node, chain: var seq[MDigest[256]], new_head: Block) =
|
||||
|
@ -241,7 +233,7 @@ func get_sig_targets(self: Node, start_slot: int32): seq[MDigest[256]] =
|
|||
doAssert self.blocks[x].slot <= start_slot - 1 - i
|
||||
doAssert result.len == min(EPOCH_LENGTH, start_slot)
|
||||
|
||||
proc tick(self: Node) =
|
||||
proc tick*(self: Node) =
|
||||
self.timestamp += initDuration(milliseconds = 100)
|
||||
self.log &"Tick: {self.timestamp}", lvl=1
|
||||
# Make a block?
|
||||
|
|
|
@ -107,7 +107,7 @@ type
|
|||
agents*: seq[Node]
|
||||
latency_distribution_sample*: proc (): Duration
|
||||
time*: Duration
|
||||
objqueue*: TableRef[Duration, seq[(Node, BlockOrSig)]]
|
||||
objqueue*: TableRef[Duration, seq[tuple[recipient: Node, obj: BlockOrSig]]]
|
||||
peers*: TableRef[int, seq[Node]]
|
||||
reliability*: float
|
||||
|
||||
|
@ -153,3 +153,23 @@ proc initSig*(
|
|||
result.timestamp = ts
|
||||
for val in result.hash.data.mitems:
|
||||
val = rand(0.byte .. 7.byte)
|
||||
|
||||
###########################################################
|
||||
# Forward declarations
|
||||
|
||||
method on_receive*(self: Node, obj: BlockOrSig, reprocess = false) {.base.} =
|
||||
raise newException(ValueError, "Not implemented error. Please implement in child types")
|
||||
|
||||
###########################################################
|
||||
|
||||
###########################################################
|
||||
# Common
|
||||
|
||||
func broadcast*(self: NetworkSimulator, sender: Node, obj: BlockOrSig) =
|
||||
for p in self.peers[sender.id]:
|
||||
let recv_time = self.time + self.latency_distribution_sample()
|
||||
if recv_time notin self.objqueue:
|
||||
self.objqueue[recv_time] = @[]
|
||||
self.objqueue[recv_time].add (p, obj)
|
||||
|
||||
###########################################################
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
tables, times, sugar, random,
|
||||
./fork_choice_types, ./distributions
|
||||
./fork_choice_types, ./fork_choice_rule, ./distributions
|
||||
|
||||
proc initNetworkSimulator*(latency: int): NetworkSimulator =
|
||||
result.latency_distribution_sample = () => initDuration(
|
||||
|
@ -37,9 +37,50 @@ proc generate_peers*(self: NetworkSimulator, num_peers = 5) =
|
|||
for peer in p:
|
||||
self.peers[peer.id].add a
|
||||
|
||||
func broadcast*(self: NetworkSimulator, sender: Node, obj: BlockOrSig) =
|
||||
for p in self.peers[sender.id]:
|
||||
proc tick(self: NetworkSimulator) =
|
||||
if self.time in self.objqueue:
|
||||
for ro in self.objqueue[self.time]:
|
||||
let (recipient, obj) = ro
|
||||
if rand(1.0) < self.reliability:
|
||||
recipient.on_receive(obj)
|
||||
self.objqueue.del self.time
|
||||
for a in self.agents:
|
||||
a.tick()
|
||||
self.time += initDuration(seconds = 1)
|
||||
|
||||
proc run(self: NetworkSimulator, steps: int) =
|
||||
for i in 0 ..< steps:
|
||||
self.tick()
|
||||
|
||||
# func broadcast*(self: NetworkSimulator, sender: Node, obj: BlockOrSig)
|
||||
# ## defined in fork_choice_types.nim
|
||||
|
||||
proc direct_send(self: NetworkSimulator, to_id: int32, obj: BlockOrSig) =
|
||||
for a in self.agents:
|
||||
if a.id == to_id:
|
||||
let recv_time = self.time + self.latency_distribution_sample()
|
||||
if recv_time notin self.objqueue:
|
||||
self.objqueue[recv_time] = @[]
|
||||
self.objqueue[recv_time].add (p, obj)
|
||||
# if recv_time notin self.objqueue: # Unneeded with seq "not nil" changes
|
||||
# self.objqueue[recv_time] = @[]
|
||||
self.objqueue[recv_time].add (a, obj)
|
||||
|
||||
proc knock_offline_random(self: NetworkSimulator, n: int) =
|
||||
var ko = initTable[int32, Node]()
|
||||
while ko.len < n:
|
||||
let c = rand(self.agents)
|
||||
ko[c.id] = c
|
||||
# for c in ko.values: # Unneeded with seq "not nil" changes
|
||||
# self.peers[c.id] = @[]
|
||||
for a in self.agents:
|
||||
self.peers[a.id] = lc[x | (x <- self.peers[a.id], x.id notin ko), Node] # List comprehension
|
||||
|
||||
proc partition(self: NetworkSimulator) =
|
||||
var a = initTable[int32, Node]()
|
||||
while a.len < self.agents.len div 2:
|
||||
let c = rand(self.agents)
|
||||
a[c.id] = c
|
||||
for c in self.agents:
|
||||
if c.id in a:
|
||||
self.peers[c.id] = lc[x | (x <- self.peers[c.id], x.id in a), Node]
|
||||
else:
|
||||
self.peers[c.id] = lc[x | (x <- self.peers[c.id], x.id notin a), Node]
|
||||
|
||||
|
|
Loading…
Reference in New Issue