47 lines
1.7 KiB
Python
47 lines
1.7 KiB
Python
import random
|
|
|
|
# NOTE: Inspired by github.com/ethereum/research networksim.py.
|
|
class NetworkSimulator():
|
|
def __init__(self):
|
|
self.nodes = []
|
|
self.time = 0
|
|
self.queue = {}
|
|
self.peers = {}
|
|
# Global network reliability
|
|
self.reliability = 1 # 0.95? Dunno.
|
|
|
|
def tick(self):
|
|
if self.time in self.queue:
|
|
# XXX: Should sender be here?
|
|
for sender, receiver, msg in self.queue[self.time]:
|
|
if random.random() < self.reliability:
|
|
#print "*** message ok", sender.name, "->", receiver.name
|
|
receiver.on_receive(sender, msg)
|
|
#else:
|
|
#print "*** message dropped", sender.name, "->", receiver.name
|
|
#print ""
|
|
print "tick", self.time + 1
|
|
#print "-----------"
|
|
for n in self.nodes:
|
|
n.tick()
|
|
self.time += 1
|
|
|
|
# XXX: This should be normal distribution or Poisson
|
|
def latency_uniform_random(self):
|
|
# XXX: Hardcode for now, easier analyze
|
|
latency = 1
|
|
#latency = random.randint(1,3)
|
|
return latency
|
|
|
|
# NOTE: Direct message, no broadcast etc
|
|
# XXX: Better name like direct_send or just send? Less confusing wrt 'messages'
|
|
def send_message(self, sender_id, receiver_id, message):
|
|
#print "*** (network) send_message", sender_id, receiver_id
|
|
# XXX: Assuming sender exists
|
|
sender = self.peers[sender_id]
|
|
receiver = self.peers[receiver_id]
|
|
recv_time = self.time + self.latency_uniform_random()
|
|
if recv_time not in self.queue:
|
|
self.queue[recv_time] = []
|
|
self.queue[recv_time].append((sender, receiver, message))
|