mirror of
https://github.com/logos-blockchain/logos-blockchain-specs.git
synced 2026-02-25 15:43:08 +00:00
add cover prob
This commit is contained in:
parent
38d1738565
commit
373bab822c
@ -1,4 +1,8 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Self
|
||||
|
||||
import dacite
|
||||
import yaml
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -7,5 +11,24 @@ class Config:
|
||||
num_nodes: int
|
||||
num_mix_layers: int
|
||||
message_interval: int
|
||||
message_prob: float
|
||||
real_message_prob: float
|
||||
cover_message_prob: float
|
||||
max_message_prep_time: float
|
||||
|
||||
@classmethod
|
||||
def load(cls, yaml_path: str) -> Self:
|
||||
with open(yaml_path, "r") as f:
|
||||
data = yaml.safe_load(f)
|
||||
config = dacite.from_dict(data_class=Config, data=data)
|
||||
|
||||
# Validations
|
||||
assert config.running_time > 0
|
||||
assert config.num_nodes > 0
|
||||
assert 0 < config.num_mix_layers <= config.num_nodes
|
||||
assert config.message_interval > 0
|
||||
assert config.real_message_prob >= 0
|
||||
assert config.cover_message_prob >= 0
|
||||
assert config.real_message_prob + config.cover_message_prob <= 1
|
||||
assert config.max_message_prep_time >= 0
|
||||
|
||||
return config
|
||||
|
||||
@ -2,5 +2,8 @@ running_time: 30
|
||||
num_nodes: 5
|
||||
num_mix_layers: 3
|
||||
message_interval: 1
|
||||
message_prob: 0.2
|
||||
# (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
|
||||
max_message_prep_time: 0.3
|
||||
@ -1,10 +1,8 @@
|
||||
import argparse
|
||||
|
||||
import dacite
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
import seaborn
|
||||
import yaml
|
||||
|
||||
from config import Config
|
||||
from simulation import Simulation
|
||||
@ -14,10 +12,7 @@ if __name__ == "__main__":
|
||||
parser.add_argument("--config", type=str, required=True, help="Configuration file path")
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.config, "r") as f:
|
||||
config = yaml.safe_load(f)
|
||||
config = dacite.from_dict(data_class=Config, data=config)
|
||||
|
||||
config = Config.load(args.config)
|
||||
sim = Simulation(config)
|
||||
sim.run()
|
||||
|
||||
|
||||
@ -29,23 +29,29 @@ class Node:
|
||||
Creates/encapsulate a message and send it to the network through the mixnet
|
||||
"""
|
||||
while True:
|
||||
# TODO: Use the realistic cover traffic emission rate
|
||||
yield self.env.timeout(self.config.message_interval)
|
||||
|
||||
if not self.is_message_sender():
|
||||
payload = self.payload_to_send()
|
||||
if payload is None: # nothing to send in this turn
|
||||
continue
|
||||
|
||||
prep_time = random.uniform(0, self.config.max_message_prep_time)
|
||||
yield self.env.timeout(prep_time)
|
||||
|
||||
self.log("Sending a message to the mixnet")
|
||||
msg = self.create_message()
|
||||
msg = self.create_message(payload)
|
||||
self.env.process(self.p2p.broadcast(msg))
|
||||
|
||||
def is_message_sender(self) -> bool:
|
||||
return random.random() < self.config.message_prob
|
||||
def payload_to_send(self) -> bytes | None:
|
||||
rnd = random.random()
|
||||
if rnd < self.config.real_message_prob:
|
||||
return self.REAL_PAYLOAD
|
||||
elif rnd < self.config.real_message_prob + self.config.cover_message_prob:
|
||||
return self.COVER_PAYLOAD
|
||||
else:
|
||||
return None
|
||||
|
||||
def create_message(self) -> SphinxPacket:
|
||||
def create_message(self, payload: bytes) -> SphinxPacket:
|
||||
"""
|
||||
Creates a message using the Sphinx format
|
||||
@return:
|
||||
@ -54,7 +60,6 @@ class Node:
|
||||
public_keys = [mix.public_key for mix in mixes]
|
||||
# TODO: replace with realistic tx
|
||||
incentive_txs = [Node.create_incentive_tx(mix.public_key) for mix in mixes]
|
||||
payload = random.choice([self.REAL_PAYLOAD, self.COVER_PAYLOAD])
|
||||
return SphinxPacket(public_keys, incentive_txs, payload)
|
||||
|
||||
def receive_message(self, msg: SphinxPacket | bytes):
|
||||
@ -78,6 +83,8 @@ class Node:
|
||||
+ self.PADDING_SEPARATOR
|
||||
+ bytes(len(msg) - len(msg.payload) - len(self.PADDING_SEPARATOR)))
|
||||
self.env.process(self.p2p.broadcast(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))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user