mirror of
https://github.com/logos-blockchain/logos-blockchain-specs.git
synced 2026-01-27 17:33:09 +00:00
improve advesary: io_window_moving_interval
This commit is contained in:
parent
5e698b7e00
commit
55f0f67554
@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from collections import defaultdict
|
||||
from collections import defaultdict, deque
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
@ -21,7 +21,8 @@ class Adversary:
|
||||
self.config = config
|
||||
self.message_sizes = []
|
||||
self.senders_around_interval = defaultdict(int)
|
||||
self.mixed_msgs_per_window = []
|
||||
self.msgs_in_node_per_window = [] # [<node, int>]
|
||||
self.cur_window_per_node = defaultdict(lambda: deque()) # <node, [(time, int)]>: int is + or -.
|
||||
# self.node_states = defaultdict(dict)
|
||||
|
||||
self.env.process(self.update_observation_window())
|
||||
@ -30,12 +31,12 @@ class Adversary:
|
||||
self.message_sizes.append(len(msg))
|
||||
|
||||
def observe_receiving_node(self, node: "Node"):
|
||||
self.mixed_msgs_per_window[-1][node] += 1
|
||||
self.cur_window_per_node[node].append((self.env.now, 1))
|
||||
# if node not in self.node_states[self.env.now]:
|
||||
# self.node_states[self.env.now][node] = NodeState.RECEIVING
|
||||
|
||||
def observe_sending_node(self, node: "Node"):
|
||||
self.mixed_msgs_per_window[-1][node] -= 1
|
||||
self.cur_window_per_node[node].append((self.env.now, -1))
|
||||
if self.is_around_message_interval(self.env.now):
|
||||
self.senders_around_interval[node] += 1
|
||||
# self.node_states[self.env.now][node] = NodeState.SENDING
|
||||
@ -46,8 +47,19 @@ class Adversary:
|
||||
|
||||
def update_observation_window(self):
|
||||
while True:
|
||||
self.mixed_msgs_per_window.append(defaultdict(int))
|
||||
yield self.env.timeout(self.config.adversary.io_observation_window)
|
||||
yield self.env.timeout(self.config.adversary.io_window_moving_interval)
|
||||
|
||||
self.msgs_in_node_per_window.append(defaultdict(int)) # <node, int>
|
||||
for node, queue in self.cur_window_per_node.items():
|
||||
msg_cnt = 0.0
|
||||
# Pop old events that are out of the new window, and accumulate msg_cnt
|
||||
while queue and queue[0][0] < self.env.now - self.config.adversary.io_window_size:
|
||||
_, delta = queue.popleft()
|
||||
msg_cnt += delta
|
||||
# Iterate remaining events that will remain in the new window, and accumulate msg_cnt
|
||||
for _, delta in queue:
|
||||
msg_cnt += delta
|
||||
self.msgs_in_node_per_window[-1][node] = msg_cnt
|
||||
|
||||
|
||||
class NodeState(Enum):
|
||||
|
||||
@ -16,8 +16,7 @@ class Analysis:
|
||||
message_size_df = self.message_size_distribution()
|
||||
self.bandwidth(message_size_df)
|
||||
self.messages_emitted_around_interval()
|
||||
if self.config.mixnet.is_mixing_on():
|
||||
self.mixed_messages_per_node_over_time()
|
||||
self.messages_in_node_over_time()
|
||||
# self.node_states()
|
||||
|
||||
def bandwidth(self, message_size_df: pd.DataFrame):
|
||||
@ -88,24 +87,25 @@ class Analysis:
|
||||
plt.legend(title="expected")
|
||||
plt.show()
|
||||
|
||||
def mixed_messages_per_node_over_time(self):
|
||||
def messages_in_node_over_time(self):
|
||||
dataframes = []
|
||||
for mixed_msgs_per_node in self.sim.p2p.adversary.mixed_msgs_per_window:
|
||||
df = pd.DataFrame([(node.id, cnt) for node, cnt in mixed_msgs_per_node.items()],
|
||||
columns=["node_id", "msg_count"])
|
||||
dataframes.append(df)
|
||||
observation_times = range(len(dataframes))
|
||||
df = pd.concat([df.assign(Time=time) for df, time in zip(dataframes, observation_times)], ignore_index=True)
|
||||
df = df.pivot(index="Time", columns="node_id", values="msg_count")
|
||||
for i, msgs_in_node in enumerate(self.sim.p2p.adversary.msgs_in_node_per_window):
|
||||
time = i * self.config.adversary.io_window_moving_interval
|
||||
df = pd.DataFrame([(time, node.id, cnt) for node, cnt in msgs_in_node.items()],
|
||||
columns=["time", "node_id", "msg_count"])
|
||||
if not df.empty:
|
||||
dataframes.append(df)
|
||||
df = pd.concat(dataframes, ignore_index=True)
|
||||
df_pivot = df.pivot(index="time", columns="node_id", values="msg_count")
|
||||
plt.figure(figsize=(12, 6))
|
||||
for column in df.columns:
|
||||
plt.plot(df.index, df[column], marker="o", label=column)
|
||||
plt.title("Mixed messages in each mix over time")
|
||||
for column in df_pivot.columns:
|
||||
plt.plot(df_pivot.index, df_pivot[column], marker=None, label=column)
|
||||
plt.title("Messages in each node over time")
|
||||
plt.xlabel("Time")
|
||||
plt.ylabel("Msg Count")
|
||||
plt.ylim(bottom=0)
|
||||
plt.legend(title="Node ID")
|
||||
plt.grid(True)
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
|
||||
def node_states(self):
|
||||
|
||||
@ -131,8 +131,12 @@ class MeasurementConfig:
|
||||
|
||||
@dataclass
|
||||
class AdversaryConfig:
|
||||
# A discrete time window for the adversary to observe inputs and outputs of a certain node
|
||||
io_observation_window: int
|
||||
# A time window for the adversary to observe inputs and outputs of each node
|
||||
io_window_size: float
|
||||
# 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.
|
||||
io_window_moving_interval: float
|
||||
|
||||
def validate(self):
|
||||
assert self.io_observation_window >= 1
|
||||
assert self.io_window_size > 0
|
||||
assert 0 < self.io_window_moving_interval <= self.io_window_size
|
||||
|
||||
@ -38,5 +38,8 @@ measurement:
|
||||
sim_time_per_second: 1
|
||||
|
||||
adversary:
|
||||
# A discrete time window for the adversary to observe inputs and outputs of a certain node
|
||||
io_observation_window: 1
|
||||
# A time window for the adversary to observe inputs and outputs of each node
|
||||
io_window_size: 0.20
|
||||
# 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.
|
||||
io_window_moving_interval: 0.10
|
||||
Loading…
x
Reference in New Issue
Block a user