Commit 2e11cbbd authored by Saswat's avatar Saswat

implement broadcast

parent ad275da9
...@@ -10,10 +10,10 @@ class Network: ...@@ -10,10 +10,10 @@ class Network:
self.pij = random.randrange(10, 500) # speed of light propagation delay in ms self.pij = random.randrange(10, 500) # speed of light propagation delay in ms
self.create_nodes() self.create_nodes()
self.create_connections() self.create_connections()
self.sim.push_event(Event(0, self.init_simulation)) self.sim.push_event(Event(0, self.init_simulation,))
return return
def init_simulation(self): def init_simulation(self, args):
for node in self.nodes: for node in self.nodes:
node.init_simulation() node.init_simulation()
return return
...@@ -52,7 +52,8 @@ class Network: ...@@ -52,7 +52,8 @@ class Network:
for i in range(self.args.num_nodes): for i in range(self.args.num_nodes):
self.nodes.append(Node(self.sim, i, bandwidth_type[i],\ self.nodes.append(Node(self.sim, i, bandwidth_type[i],\
cpu_type[i], Tk[i], self.args.T_tx, self.args.num_nodes)) cpu_type[i], Tk[i], self.args.T_tx,\
self.args.num_nodes, self.pij))
return return
def create_connections(self): def create_connections(self):
...@@ -84,14 +85,8 @@ class Network: ...@@ -84,14 +85,8 @@ class Network:
print(neighbors) print(neighbors)
for i in range(num_nodes): for i in range(num_nodes):
for j in adjacency_list[i]: for j in adjacency_list[i]:
self.nodes[i].neighbors.append(id(self.nodes[j])) self.nodes[i].neighbors.append(self.nodes[j])
for node in self.nodes:
print(node.nodeId, node)
print("Graph created") print("Graph created")
return return
\ No newline at end of file
def calculate_latency(sender, receiver, message_size):
# Calculate latency based on provided formula
pass
def forward_transaction(sender, receiver, transaction):
# Forward transaction from sender to receiver if conditions are met
pass
\ No newline at end of file
...@@ -2,8 +2,16 @@ from blockchain import Blockchain ...@@ -2,8 +2,16 @@ from blockchain import Blockchain
from simulate import Event from simulate import Event
from utils import * from utils import *
#TODO(SM): Need to bind each transaction with a time of arrival at a node
txn_id = 0
def get_txn_id():
global txn_id
txn_id += 1
return txn_id
class Node: class Node:
def __init__(self, sim, ID, bandwidth_type, cpu_type, Tk, T_tx, num_nodes): def __init__(self, sim, ID, bandwidth_type, cpu_type, Tk, T_tx, num_nodes, pij):
# Initialize node attributes # Initialize node attributes
self.sim = sim self.sim = sim
self.balance = 0 self.balance = 0
...@@ -13,6 +21,7 @@ class Node: ...@@ -13,6 +21,7 @@ class Node:
self.Tk = Tk self.Tk = Tk
self.T_tx = T_tx self.T_tx = T_tx
self.num_nodes = num_nodes self.num_nodes = num_nodes
self.pij = pij
self.neighbors = [] self.neighbors = []
...@@ -20,25 +29,82 @@ class Node: ...@@ -20,25 +29,82 @@ class Node:
self.pending_transactions = [] self.pending_transactions = []
def init_simulation(self): def init_simulation(self):
"""
Initialize the simulation for generatinv transactions
TODO: Schedule Block creation event
"""
# Initialize simulation # Initialize simulation
# schedule the first transaction # schedule the first transaction
self.sim.push_event(Event(self.sim.curr_time + sample_exponential(self.T_tx),\ self.sim.push_event(Event(self.sim.curr_time + sample_exponential(self.T_tx),\
self.generate_random_transaction)) self._event_generate_transaction))
pass pass
def generate_random_transaction(self):
# Generate a transaction for the given peer def get_latency(self, node, data):
# Format: "TxnID: IDx pays IDy C coins" """
print("Generating a transaction for node", self.nodeId) Get the latency to send the transaction to the given node
"""
# check if the bandwidth type is slow for either of the nodes
if(self.bandwidth_type == 1 and node.bandwidth_type == 1):
cij = 100
else:
cij = 5
dij = sample_exponential(96/cij)
latency = dij + self.pij
if(type(data) == str): # transaction
m = 1024
else:
# TODO(AG): latency for block
m = 1024
return latency + (float(m)/cij)
def _event_receive_transaction(self, txn):
"""
Event to receive a transaction from a neighbor
"""
print(self.nodeId, "Received transaction", txn)
if txn not in self.pending_transactions:
self.pending_transactions.append(txn)
return
def _event_broadcast_transaction(self, txn):
"""
Broadcast the transaction to the neighbors
"""
print(self.nodeId, "Broadcasting txn", txn)
for neighbor in self.neighbors:
print(self.nodeId, "Sending txn", txn, "to", neighbor.nodeId)
self.sim.push_event(Event(self.sim.curr_time + self.get_latency(neighbor, txn),\
neighbor._event_receive_transaction, txn))
return
def _event_generate_transaction(self, args):
"""
Generate a transaction for the given peer
Format: "TxnID: IDx pays IDy C coins"
"""
# Select a random destination node and amount # Select a random destination node and amount
dest = self.nodeId dest = self.nodeId
while dest == self.nodeId: while dest == self.nodeId:
dest = random.randint(0, self.num_nodes) dest = random.randint(0, self.num_nodes)
amount = random.randint(1, self.balance + 10) amount = random.randint(1, self.balance + 10)
txn = "TxnID: " + str(self.nodeId) + " pays " + str(dest) + " " + str(amount) + " coins"
# Create a transaction and it to current nodes pending transactions
txn = str(get_txn_id()) + ": " + str(self.nodeId) + " pays "\
+ str(dest) + " " + str(amount) + " coins"
print(self.nodeId, "Generated a txn:", txn)
self.pending_transactions.append(txn) self.pending_transactions.append(txn)
# schedule the next transaction # schedule the next transaction
self.sim.push_event(Event(self.sim.curr_time + sample_exponential(self.T_tx),\ self.sim.push_event(Event(self.sim.curr_time + sample_exponential(self.T_tx),\
self.generate_random_transaction)) self._event_generate_transaction))
# broadcast the transaction to the neighbors
self._event_broadcast_transaction(txn)
pass pass
...@@ -3,12 +3,13 @@ import random ...@@ -3,12 +3,13 @@ import random
event_id = 0 # for debug purposes event_id = 0 # for debug purposes
class Event: class Event:
def __init__(self, time, operation): def __init__(self, time, operation, *args):
self.time = time self.time = time
self.operation = operation self.operation = operation
self.args = args
def process(self): def process(self):
print("Processing event at time", self.time) #print("Processing event at time", self.time)
return self.operation() return self.operation(self.args)
class EventSimulator: class EventSimulator:
""" """
...@@ -40,8 +41,8 @@ class EventSimulator: ...@@ -40,8 +41,8 @@ class EventSimulator:
""" """
Add event to the queue just before the time it is supposed to occur Add event to the queue just before the time it is supposed to occur
""" """
print(self.curr_time, "Pushing event at time", event.time) #print(self.curr_time, "Pushing event at time", event.time)
time.sleep(2) #time.sleep(2)
for i in range(len(self.queue)): for i in range(len(self.queue)):
if self.queue[i].time > event.time: if self.queue[i].time > event.time:
self.queue.insert(i, event) self.queue.insert(i, event)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment