Fix tables initialization issues
This commit is contained in:
parent
3bc75711d5
commit
acf322ea7b
|
@ -40,9 +40,7 @@ func add_to_multiset[K, V](
|
||||||
multiset: TableRef[K, seq[V]],
|
multiset: TableRef[K, seq[V]],
|
||||||
k: K,
|
k: K,
|
||||||
v: V or seq[V]) =
|
v: V or seq[V]) =
|
||||||
# if k notin multiset: # Unneeded with seq "not nil" changes
|
multiset.mgetOrPut(k, @[]).add v
|
||||||
# multiset[k] = @[]
|
|
||||||
multiset[k].add v
|
|
||||||
|
|
||||||
func change_head(self: Node, chain: var seq[MDigest[256]], new_head: Block) =
|
func change_head(self: Node, chain: var seq[MDigest[256]], new_head: Block) =
|
||||||
chain.add newSeq[MDigest[256]](new_head.height + 1 - chain.len)
|
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)
|
let slot = int32 seconds(self.timestamp div SLOT_SIZE)
|
||||||
if slot > self.last_made_block and (slot mod NOTARIES) == self.id:
|
if slot > self.last_made_block and (slot mod NOTARIES) == self.id:
|
||||||
self.broadcast(
|
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
|
self.last_made_block = slot
|
||||||
# Make a sig?
|
# Make a sig?
|
||||||
|
@ -248,13 +248,11 @@ proc tick*(self: Node) =
|
||||||
var sig_from = self.main_chain.high
|
var sig_from = self.main_chain.high
|
||||||
while sig_from > 0 and self.blocks[self.main_chain[sig_from]].slot >= slot - EPOCH_LENGTH:
|
while sig_from > 0 and self.blocks[self.main_chain[sig_from]].slot >= slot - EPOCH_LENGTH:
|
||||||
dec sig_from
|
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.log &"Sig: {self.id} {sig.slot} {sig.targets.mapIt(($it)[0 ..< 4])}"
|
||||||
self.broadcast sig
|
self.broadcast sig
|
||||||
self.last_made_sig = slot
|
self.last_made_sig = slot
|
||||||
# process time queue
|
# process time queue
|
||||||
var first = self.timequeue[0]
|
while self.timequeue.len > 0 and self.timequeue[0].min_timestamp <= self.timestamp:
|
||||||
while self.timequeue.len > 0 and first.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.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)
|
self.on_receive(self.timequeue[0], reprocess = true)
|
||||||
first = self.timequeue[0]
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -141,7 +141,7 @@ type
|
||||||
last_made_block*: int32
|
last_made_block*: int32
|
||||||
last_made_sig*: int32
|
last_made_sig*: int32
|
||||||
|
|
||||||
proc initSig*(
|
proc newSig*(
|
||||||
proposer: int32,
|
proposer: int32,
|
||||||
targets: seq[MDigest[256]],
|
targets: seq[MDigest[256]],
|
||||||
slot: int32,
|
slot: int32,
|
||||||
|
@ -154,6 +154,29 @@ proc initSig*(
|
||||||
for val in result.hash.data.mitems:
|
for val in result.hash.data.mitems:
|
||||||
val = rand(0.byte .. 7.byte)
|
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
|
# Forward declarations
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,8 @@ import
|
||||||
tables, times, sugar, random,
|
tables, times, sugar, random,
|
||||||
./fork_choice_types, ./fork_choice_rule, ./distributions
|
./fork_choice_types, ./fork_choice_rule, ./distributions
|
||||||
|
|
||||||
proc initNetworkSimulator*(latency: int): NetworkSimulator =
|
proc newNetworkSimulator*(latency: int): NetworkSimulator =
|
||||||
|
new result
|
||||||
result.latency_distribution_sample = () => initDuration(
|
result.latency_distribution_sample = () => initDuration(
|
||||||
seconds = max(
|
seconds = max(
|
||||||
0,
|
0,
|
||||||
|
@ -33,11 +34,11 @@ proc generate_peers*(self: NetworkSimulator, num_peers = 5) =
|
||||||
p.add self.agents.rand()
|
p.add self.agents.rand()
|
||||||
if p[^1] == a:
|
if p[^1] == a:
|
||||||
discard p.pop()
|
discard p.pop()
|
||||||
self.peers[a.id].add p
|
self.peers.mgetOrPut(a.id, @[]).add p
|
||||||
for peer in 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:
|
if self.time in self.objqueue:
|
||||||
for ro in self.objqueue[self.time]:
|
for ro in self.objqueue[self.time]:
|
||||||
let (recipient, obj) = ro
|
let (recipient, obj) = ro
|
||||||
|
|
Loading…
Reference in New Issue