analyze nodes who emitted messages around the promised interval

This commit is contained in:
Youngjoon Lee 2024-05-15 18:01:42 +09:00
parent 7492be95fb
commit 661f40680c
No known key found for this signature in database
GPG Key ID: 09B750B5BD6F08A2
6 changed files with 28 additions and 14 deletions

View File

@ -11,7 +11,7 @@ class Config:
num_nodes: int
num_mix_layers: int
message_interval: int
real_message_prob: float
real_message_prob: float # TODO: should be proportional to its stake
cover_message_prob: float
max_message_prep_time: float

View File

@ -1,9 +1,9 @@
running_time: 30
num_nodes: 5
num_nodes: 100
num_mix_layers: 3
message_interval: 1
# (real_message_prob + cover_message_prob) should be <= 1
# If the sum is < 1, then the remaining probability is for sending nothing.
real_message_prob: 0.1
cover_message_prob: 0.4
real_message_prob: 0.01
cover_message_prob: 0.2
max_message_prep_time: 0.3

View File

@ -8,7 +8,7 @@ from config import Config
from simulation import Simulation
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Run simulation', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser = argparse.ArgumentParser(description="Run simulation", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--config", type=str, required=True, help="Configuration file path")
args = parser.parse_args()
@ -16,12 +16,17 @@ if __name__ == "__main__":
sim = Simulation(config)
sim.run()
# Stat the distribution of message sizes
df = pd.DataFrame(sim.p2p.message_sizes, columns=["message_size"])
print(df.describe())
# Visualize the nodes emitted messages around the promised interval
df = pd.DataFrame([(node.id, cnt) for node, cnt in sim.p2p.nodes_emitted_msg_around_interval.items()], columns=["node", "count"])
plt.figure(figsize=(10, 6))
seaborn.boxplot(y=df["message_size"])
plt.title("Message size distribution")
plt.ylabel("Message Size (bytes)")
seaborn.barplot(x="node", y="count", data=df)
plt.title("Messages emitted around the promised interval")
plt.xlabel("Node ID")
plt.ylabel("Msg Count")
plt.show()
print("Simulation complete!")

View File

@ -40,7 +40,7 @@ class Node:
self.log("Sending a message to the mixnet")
msg = self.create_message(payload)
self.env.process(self.p2p.broadcast(msg))
self.env.process(self.p2p.broadcast(self, msg))
def payload_to_send(self) -> bytes | None:
rnd = random.random()
@ -82,13 +82,13 @@ class Node:
final_padded_msg = (msg.payload
+ self.PADDING_SEPARATOR
+ bytes(len(msg) - len(msg.payload) - len(self.PADDING_SEPARATOR)))
self.env.process(self.p2p.broadcast(final_padded_msg))
self.env.process(self.p2p.broadcast(self, final_padded_msg))
else:
self.log("Dropping a cover message: %s" % msg.payload)
else:
# TODO: use Poisson delay or something else
yield self.env.timeout(random.randint(0, 5))
self.env.process(self.p2p.broadcast(msg))
self.env.process(self.p2p.broadcast(self, msg))
else:
self.log("Receiving SphinxPacket, but not mine")
else:

View File

@ -1,24 +1,33 @@
import math
import random
from collections import defaultdict
import simpy
from config import Config
from sphinx import SphinxPacket
class P2p:
def __init__(self, env: simpy.Environment):
def __init__(self, env: simpy.Environment, config: Config):
self.env = env
self.config = config
self.nodes = []
self.message_sizes = []
self.nodes_emitted_msg_around_interval = defaultdict(int)
def add_node(self, nodes):
self.nodes.extend(nodes)
# TODO: This should accept only bytes, but SphinxPacket is also accepted until we implement the Sphinx serde
def broadcast(self, msg: SphinxPacket | bytes):
def broadcast(self, sender, msg: SphinxPacket | bytes):
self.log("Broadcasting a msg: %d bytes" % len(msg))
self.message_sizes.append(len(msg))
now_frac, now_int = math.modf(self.env.now)
if now_int % self.config.message_interval == 0 and now_frac <= self.config.max_message_prep_time:
self.nodes_emitted_msg_around_interval[sender] += 1
# Yield 0 to ensure that the broadcast is done in the same time step.
# Without this, SimPy complains that the broadcast func is not a generator.
yield self.env.timeout(0)

View File

@ -12,7 +12,7 @@ class Simulation:
random.seed()
self.config = config
self.env = simpy.Environment()
self.p2p = P2p(self.env)
self.p2p = P2p(self.env, config)
self.nodes = [Node(i, self.env, self.p2p, config) for i in range(config.num_nodes)]
self.p2p.add_node(self.nodes)