plots, but not expected

This commit is contained in:
Youngjoon Lee 2024-05-31 21:07:47 +09:00
parent 7ce7be991f
commit 7dc003456d
No known key found for this signature in database
GPG Key ID: 09B750B5BD6F08A2
3 changed files with 73 additions and 8 deletions

View File

@ -2,9 +2,11 @@ import random
from collections import defaultdict, Counter
from typing import TYPE_CHECKING
import numpy as np
import pandas as pd
import seaborn
from matplotlib import pyplot as plt
import scipy.stats as stats
from adversary import NodeState
from config import Config
@ -174,6 +176,7 @@ class Analysis:
- there is no message to track back within a reasonable time window
- enough hops have been traversed
"""
all_results = []
window = len(self.sim.p2p.adversary.msgs_in_node_per_window) - 1
while window >= 0:
items = self.sim.p2p.adversary.msgs_in_node_per_window[window].items()
@ -181,10 +184,61 @@ class Analysis:
if len(actual_receivers) == 0:
window -= 1
continue
receiver = random.choice(actual_receivers)
nodes_per_hop = self.timing_attack_with(receiver, window)
self.print_nodes_per_hop(nodes_per_hop, window)
window -= len(nodes_per_hop)
results = []
max_hops = 0
for receiver in actual_receivers:
nodes_per_hop = self.timing_attack_with(receiver, window)
self.print_nodes_per_hop(nodes_per_hop, window)
results.append(nodes_per_hop)
max_hops = max(max_hops, len(nodes_per_hop))
window -= max_hops
all_results.extend(results)
suspected_senders = Counter()
for result in all_results:
print(Counter({node.id: count for node, count in result[-1].items()}))
suspected_senders.update(result[-1])
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
keys = list(suspected_senders.keys())
values = list(suspected_senders.values())
# Create the bar plot
plt.figure(figsize=(12, 8))
plt.bar(keys, values)
plt.xlabel('Node ID')
plt.ylabel('Counts')
plt.title('Suspected Sender Counts')
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()
# Calculate the mean and standard deviation of the counts
mean = np.mean(values)
std_dev = np.std(values)
# Plot the histogram of the values
plt.figure(figsize=(12, 8))
plt.hist(values, bins=30, density=True, alpha=0.6, color='g', label='Counts Histogram')
# Plot the normal distribution curve
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = stats.norm.pdf(x, mean, std_dev)
plt.plot(x, p, 'k', linewidth=2, label='Normal Distribution')
title = "Fit results: mean = %.2f, std_dev = %.2f" % (mean, std_dev)
plt.title(title)
plt.xlabel('Counts')
plt.ylabel('Density')
plt.legend()
plt.show()
def timing_attack_with(self, starting_node: "Node", starting_window: int):
_, senders = self.sim.p2p.adversary.msgs_in_node_per_window[starting_window][starting_node]

View File

@ -1,4 +1,4 @@
from collections import defaultdict
from collections import defaultdict, Counter
from typing import TYPE_CHECKING
import pandas as pd
@ -15,12 +15,20 @@ class Measurement:
def __init__(self, env: simpy.Environment, config: Config):
self.env = env
self.config = config
self.original_senders = Counter()
self.egress_bandwidth_per_time = []
self.ingress_bandwidth_per_time = []
self.message_hops = defaultdict(int) # dict[msg_hash, hops]
self.env.process(self._update_bandwidth_window())
def set_nodes(self, nodes: list["Node"]):
for node in nodes:
self.original_senders[node] = 0
def count_original_sender(self, sender: "Node"):
self.original_senders[sender] += 1
def measure_egress(self, node: "Node", msg: SphinxPacket | bytes):
self.egress_bandwidth_per_time[-1][node] += len(msg)

View File

@ -27,6 +27,7 @@ class P2P(ABC):
def set_nodes(self, nodes: list["Node"]):
self.nodes = nodes
self.measurement.set_nodes(nodes)
def get_nodes(self, n: int) -> list["Node"]:
return random.sample(self.nodes, n)
@ -40,6 +41,9 @@ class P2P(ABC):
yield self.env.timeout(0)
def send(self, msg: SphinxPacket | bytes, hops: int, sender: "Node", receiver: "Node", is_first_of_msg: bool):
if hops == 0:
self.measurement.count_original_sender(sender)
if is_first_of_msg:
self.adversary.inspect_message_size(msg)
self.adversary.observe_sending_node(sender, receiver)
@ -128,9 +132,8 @@ class GossipP2P(P2P):
msg_hash = hashlib.sha256(bytes(msg)).digest()
if msg_hash not in self.message_cache[receiver]:
self.message_cache[receiver][msg_hash] = sender
hops += 1
self.measurement.update_message_hops(msg_hash, hops)
# Receive and gossip
self.env.process(receiver.receive_message(msg))
hops += 1
self.measurement.update_message_hops(msg_hash, hops)
self.env.process(self.broadcast(receiver, msg, hops))