mirror of
https://github.com/logos-blockchain/logos-blockchain-specs.git
synced 2026-01-03 21:53:07 +00:00
add min_network_latency and min_mix_delay for easy window adjustments
This commit is contained in:
parent
c94e5fa8ac
commit
1aaa0abd53
@ -60,7 +60,9 @@ class Adversary:
|
||||
if delta > 0:
|
||||
senders.add(sender)
|
||||
# Iterate remaining events that will remain in the new window, and accumulate msg_cnt
|
||||
for _, delta, sender in queue:
|
||||
for t, delta, sender in queue:
|
||||
if t >= self.env.now - self.config.adversary.io_window_moving_interval:
|
||||
break
|
||||
msg_cnt += delta
|
||||
if delta > 0:
|
||||
senders.add(sender)
|
||||
|
||||
@ -165,6 +165,7 @@ class Analysis:
|
||||
print(df.describe())
|
||||
plt.figure(figsize=(6, 6))
|
||||
seaborn.boxplot(data=df, y="hops", medianprops={"color": "red", "linewidth": 2.5})
|
||||
plt.ylim(bottom=0)
|
||||
plt.title("Message hops distribution")
|
||||
plt.show()
|
||||
|
||||
@ -202,7 +203,17 @@ class Analysis:
|
||||
suspected_senders = ({node.id: count for node, count in suspected_senders.items()})
|
||||
print(f"suspected nodes count: {len(suspected_senders)}")
|
||||
|
||||
# Extract keys and values from the Counter
|
||||
# Create the bar plot for original sender counts
|
||||
original_senders = ({node.id: count for node, count in self.sim.p2p.measurement.original_senders.items()})
|
||||
plt.figure(figsize=(12, 8))
|
||||
plt.bar(list(original_senders.keys()), list(original_senders.values()))
|
||||
plt.xlabel('Node ID')
|
||||
plt.ylabel('Counts')
|
||||
plt.title('Original Sender Counts')
|
||||
plt.xlim(-1, self.config.mixnet.num_nodes)
|
||||
plt.show()
|
||||
|
||||
# Create the bar plot for suspected sender counts
|
||||
keys = list(suspected_senders.keys())
|
||||
values = list(suspected_senders.values())
|
||||
# Create the bar plot
|
||||
@ -211,24 +222,17 @@ class Analysis:
|
||||
plt.xlabel('Node ID')
|
||||
plt.ylabel('Counts')
|
||||
plt.title('Suspected Sender Counts')
|
||||
plt.xlim(-1, self.config.mixnet.num_nodes)
|
||||
plt.show()
|
||||
|
||||
# Create the bar plot for original sender counts
|
||||
original_senders = ({node.id: count for node, count in self.sim.p2p.measurement.original_senders.items()})
|
||||
plt.figure(figsize=(12, 8))
|
||||
plt.bar(list(original_senders.keys()), list(original_senders.values()))
|
||||
plt.xlabel('Node ID')
|
||||
plt.ylabel('Counts')
|
||||
plt.title('Original Sender Counts')
|
||||
plt.show()
|
||||
|
||||
# Create the bar plot for original sender counts
|
||||
# Create the bar plot for broadcasters
|
||||
broadcasters = ({node.id: count for node, count in self.sim.p2p.broadcasters.items()})
|
||||
plt.figure(figsize=(12, 8))
|
||||
plt.bar(list(broadcasters.keys()), list(broadcasters.values()))
|
||||
plt.xlabel('Node ID')
|
||||
plt.ylabel('Counts')
|
||||
plt.title('Broadcasters')
|
||||
plt.xlim(-1, self.config.mixnet.num_nodes)
|
||||
plt.show()
|
||||
|
||||
# Calculate the mean and standard deviation of the counts
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import Self
|
||||
|
||||
@ -26,7 +28,7 @@ class Config:
|
||||
config.p2p.validate()
|
||||
config.measurement.validate()
|
||||
config.adversary.validate()
|
||||
|
||||
|
||||
return config
|
||||
|
||||
def description(self):
|
||||
@ -64,6 +66,7 @@ class MixnetConfig:
|
||||
# A maximum preparation time (computation time) for a message sender before sending the message
|
||||
max_message_prep_time: float
|
||||
# A maximum delay of messages mixed in a mix node
|
||||
min_mix_delay: float
|
||||
max_mix_delay: float
|
||||
|
||||
def validate(self):
|
||||
@ -77,13 +80,14 @@ class MixnetConfig:
|
||||
assert weight >= 1
|
||||
assert self.cover_message_prob >= 0
|
||||
assert self.max_message_prep_time >= 0
|
||||
assert self.max_mix_delay >= 0
|
||||
assert 0 <= self.min_mix_delay <= self.max_mix_delay
|
||||
|
||||
def description(self):
|
||||
return (
|
||||
f"payload: {self.payload_size} bytes\n"
|
||||
f"num_nodes: {self.num_nodes}\n"
|
||||
f"num_mix_layers: {self.num_mix_layers}\n"
|
||||
f"min_mix_delay: {self.min_mix_delay}\n"
|
||||
f"max_mix_delay: {self.max_mix_delay}\n"
|
||||
f"msg_interval: {self.message_interval}\n"
|
||||
f"real_msg_prob: {self.real_message_prob:.2f}\n"
|
||||
@ -93,6 +97,9 @@ class MixnetConfig:
|
||||
def is_mixing_on(self) -> bool:
|
||||
return self.num_mix_layers > 0
|
||||
|
||||
def random_mix_delay(self) -> float:
|
||||
return random.uniform(self.min_mix_delay, self.max_mix_delay)
|
||||
|
||||
|
||||
@dataclass
|
||||
class P2PConfig:
|
||||
@ -101,6 +108,7 @@ class P2PConfig:
|
||||
# A connection density, only if the type is gossip
|
||||
connection_density: int
|
||||
# A maximum network latency between nodes directly connected with each other
|
||||
min_network_latency: float
|
||||
max_network_latency: float
|
||||
|
||||
TYPE_ONE_TO_ALL = "1-to-all"
|
||||
@ -110,15 +118,19 @@ class P2PConfig:
|
||||
assert self.type in [self.TYPE_ONE_TO_ALL, self.TYPE_GOSSIP]
|
||||
if self.type == self.TYPE_GOSSIP:
|
||||
assert self.connection_density > 0
|
||||
assert self.max_network_latency >= 0
|
||||
assert 0 < self.min_network_latency <= self.max_network_latency
|
||||
|
||||
def description(self):
|
||||
return (
|
||||
f"p2p_type: {self.type}\n"
|
||||
f"conn_density: {self.connection_density}\n"
|
||||
f"min_net_latency: {self.min_network_latency:.2f}\n"
|
||||
f"max_net_latency: {self.max_network_latency:.2f}"
|
||||
)
|
||||
|
||||
def random_network_latency(self) -> float:
|
||||
return random.uniform(self.min_network_latency, self.max_network_latency)
|
||||
|
||||
|
||||
@dataclass
|
||||
class MeasurementConfig:
|
||||
|
||||
@ -23,7 +23,8 @@ mixnet:
|
||||
# A maximum preparation time (computation time) for a message sender before sending the message
|
||||
max_message_prep_time: 0
|
||||
# A maximum delay of messages mixed in a mix node
|
||||
max_mix_delay: 0
|
||||
min_mix_delay: 0.0
|
||||
max_mix_delay: 0.0
|
||||
|
||||
p2p:
|
||||
# Broadcasting type: 1-to-all | gossip
|
||||
@ -31,6 +32,7 @@ p2p:
|
||||
# A connection density, only if the type is gossip
|
||||
connection_density: 6
|
||||
# A maximum network latency between nodes directly connected with each other
|
||||
min_network_latency: 0.10
|
||||
max_network_latency: 0.20
|
||||
|
||||
measurement:
|
||||
@ -39,7 +41,9 @@ measurement:
|
||||
|
||||
adversary:
|
||||
# A time window for the adversary to observe inputs and outputs of each node
|
||||
io_window_size: 0.20
|
||||
# Recommendation: Same as `mixnet.max_mix_delay + (p2p.max_network_latency - p2p.min_network_latency)`
|
||||
io_window_size: 0.10
|
||||
# A moving interval of the time window for the adversary to observe inputs and outputs of each node
|
||||
# This must be smaller or equal to io_window_size.
|
||||
# Recommendation: Same as `p2p.min_network_latency`
|
||||
io_window_moving_interval: 0.10
|
||||
@ -50,7 +50,7 @@ class P2P(ABC):
|
||||
self.measurement.measure_egress(sender, msg)
|
||||
|
||||
# simulate network latency
|
||||
yield self.env.timeout(random.uniform(0, self.config.p2p.max_network_latency))
|
||||
yield self.env.timeout(self.config.p2p.random_network_latency())
|
||||
|
||||
self.measurement.measure_ingress(receiver, msg)
|
||||
self.adversary.observe_receiving_node(sender, receiver)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user