Fix tables initialization issues

This commit is contained in:
mratsim 2018-09-11 14:02:45 +02:00
parent 3bc75711d5
commit acf322ea7b
4 changed files with 73 additions and 14 deletions

View File

@ -40,9 +40,7 @@ func add_to_multiset[K, V](
multiset: TableRef[K, seq[V]],
k: K,
v: V or seq[V]) =
# if k notin multiset: # Unneeded with seq "not nil" changes
# multiset[k] = @[]
multiset[k].add v
multiset.mgetOrPut(k, @[]).add v
func change_head(self: Node, chain: var seq[MDigest[256]], new_head: Block) =
chain.add newSeq[MDigest[256]](new_head.height + 1 - chain.len)
@ -240,7 +238,9 @@ proc tick*(self: Node) =
let slot = int32 seconds(self.timestamp div SLOT_SIZE)
if slot > self.last_made_block and (slot mod NOTARIES) == self.id:
self.broadcast(
initBlock(self.blocks[self.main_chain[^1]], slot, self.id)
initBlock(self.blocks[
self.main_chain[^1]
], slot, self.id)
)
self.last_made_block = slot
# Make a sig?
@ -248,13 +248,11 @@ proc tick*(self: Node) =
var sig_from = self.main_chain.high
while sig_from > 0 and self.blocks[self.main_chain[sig_from]].slot >= slot - EPOCH_LENGTH:
dec sig_from
let sig = initSig(self.id, self.get_sig_targets(slot), slot, self.timestamp)
let sig = newSig(self.id, self.get_sig_targets(slot), slot, self.timestamp)
self.log &"Sig: {self.id} {sig.slot} {sig.targets.mapIt(($it)[0 ..< 4])}"
self.broadcast sig
self.last_made_sig = slot
# process time queue
var first = self.timequeue[0]
while self.timequeue.len > 0 and first.min_timestamp <= self.timestamp:
while self.timequeue.len > 0 and self.timequeue[0].min_timestamp <= self.timestamp:
self.timequeue.delete(0) # This is expensive, but we can't use a queue due to random insertions in add_to_timequeue
self.on_receive(first, reprocess = true)
first = self.timequeue[0]
self.on_receive(self.timequeue[0], reprocess = true)

View File

@ -0,0 +1,37 @@
# beacon_chain
# Copyright (c) 2018 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
# A port of https://github.com/ethereum/research/blob/master/clock_disparity/ghost_node.py
# Specs: https://ethresear.ch/t/beacon-chain-casper-ffg-rpj-mini-spec/2760
# Part of Casper+Sharding chain v2.1: https://notes.ethereum.org/SCIg8AH5SA-O4C1G1LYZHQ#
# Note that implementation is not updated to the latest v2.1 yet
import
./fork_choice_types, ./networksim, ./fork_choice_rule, ./distributions,
sequtils, times, strformat, tables
let net = newNetworkSimulator(latency = 22)
for i in 0'i32 ..< NOTARIES:
net.agents.add newNode(
id = i,
network = net,
timestamp = initDuration(seconds = max(normal_distribution(300, 300), 0)) div 10,
sleepy = i mod 4 == 0
)
net.generate_peers()
for i in 0 ..< 100000:
net.tick()
for n in net.agents:
echo &"Local timestamp: {n.timestamp:>.1}, timequeue len {n.timequeue.len}"
echo "Main chain head: ", n.blocks[n.main_chain[^1]].height
echo "Total main chain blocks received: ", toSeq(values(n.blocks)).filterIt(it is Block).len
# echo "Notarized main chain blocks received: ", toSeq(values(n.blocks)).filterIt((it is Block) and n.is_notarized(it)).len - 1

View File

@ -141,7 +141,7 @@ type
last_made_block*: int32
last_made_sig*: int32
proc initSig*(
proc newSig*(
proposer: int32,
targets: seq[MDigest[256]],
slot: int32,
@ -154,6 +154,29 @@ proc initSig*(
for val in result.hash.data.mitems:
val = rand(0.byte .. 7.byte)
proc newNode*(
id: int32,
network: NetworkSimulator,
sleepy, careless = false,
timestamp = DurationZero
): Node =
new result
result.id = id
result.network = network
result.timestamp = timestamp
result.sleepy = sleepy
result.careless = careless
result.main_chain = @[Genesis.hash]
result.blocks = {Genesis.hash: Genesis}.newTable
# Boilerplate empty initialization
result.processed = newTable[BlockOrSigHash, BlockOrSig]()
result.children = newTable[MDigest[256], seq[MDigest[256]]]()
result.parentqueue = newTable[MDigest[256], seq[BlockOrSig]]()
result.scores = newTable[MDigest[256], int]()
result.scores_at_height = newTable[array[36, byte], int]()
result.sigs = newTable[MDigest[384], Sig]()
###########################################################
# Forward declarations

View File

@ -13,7 +13,8 @@ import
tables, times, sugar, random,
./fork_choice_types, ./fork_choice_rule, ./distributions
proc initNetworkSimulator*(latency: int): NetworkSimulator =
proc newNetworkSimulator*(latency: int): NetworkSimulator =
new result
result.latency_distribution_sample = () => initDuration(
seconds = max(
0,
@ -33,11 +34,11 @@ proc generate_peers*(self: NetworkSimulator, num_peers = 5) =
p.add self.agents.rand()
if p[^1] == a:
discard p.pop()
self.peers[a.id].add p
self.peers.mgetOrPut(a.id, @[]).add p
for peer in p:
self.peers[peer.id].add a
self.peers.mgetOrPut(peer.id, @[]).add a
proc tick(self: NetworkSimulator) =
proc tick*(self: NetworkSimulator) =
if self.time in self.objqueue:
for ro in self.objqueue[self.time]:
let (recipient, obj) = ro