Commit d366f99d authored by Abhishek Kumar's avatar Abhishek Kumar

Completed txns code

parent fb9756fb
from utils import *
from simulate import Event
class Block:
def __init__(self, peer, ID, transactions, previous_block_ID):
def __init__(self, nodeID, ID, transactions, previous_block_ID):
# Initialize block attributes
self.blk_Id = ID
self.transactions = transactions
self.prev_blk_Id = previous_block_ID
self.pow_user_id = peer
self.pow_user_id = nodeID
return
class Blockchain:
def __init__(self):
# Initialize blockchain attributes
# TODO: Should broadcast the genesis block
self.chain = {}
self.genensis_block = Block(0, [], -1)
self.chain[self.genensis_block.blk_Id] = self.genensis_block
self.head = 0
self.genensis_block = Block(-1, gen_hash(GENESIS_SECRET), [], -1)
self.chain[self.genensis_block.blk_Id] = (self.genensis_block, 0) #
self.head = self.genensis_block.blk_Id
self.len_longest_chain = 1
self.seen_transactions = set()
self.pending_transactions = set()
self.next_pow_completion_time = 0
pass
def get_chain_length(self, blk_Id = None):
def get_chain_length(self, blk_Id=None):
# Return the length of the longest chain
if blk_Id is None:
curr = self.len_longest_chain
curr = self.head
curr = blk_Id
cnt = 0
while(curr != -1):
while curr != self.genensis_block.blk_Id:
if curr not in self.chain:
print("ERROR: Block not found in the chain")
break
curr = self.chain[curr].prev_blk_Id
cnt += 1
return cnt
def receive_txn(self, txn):
"""
Receive transaction from a neighbor
if already seen, return 0 else return 1
Receive transaction from a neighbor
if already seen, return 0 else return 1
"""
if txn in self.seen_transactions:
return 0
......@@ -49,18 +50,33 @@ class Blockchain:
self.seen_transactions.add(txn_id)
self.pending_transactions.add(txn)
return 1
def verify_blk(self, blk):
"""
Verify the block
if valid, return 1 else 0
Verify the block
if valid, return 1 else 0
"""
return 1
def add_mined_block(self, blk):
"""
Add the mined block to the blockchain
Add the mined block to the blockchain
"""
return
def
def print_chain(self):
pass
def already_exist(self, blk):
print(blk, self.chain.get(blk.blk_Id))
exit()
if blk.blk_Id in self.chain:
return True
return False
def received_txn(self, txn):
if txn in self.pending_transactions or txn in self.seen_transactions:
return False
self.pending_transactions.add(txn)
return True
......@@ -3,30 +3,46 @@ from simulate import EventSimulator
import random
from network import Network
def parse_cmd():
"""
Parse command line arguments
"""
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--num_nodes', type = int, default = 50, help="Number of nodes in the network")
parser.add_argument('--z0', type = int, default = 10, help="percentage of node with slow bandwidth")
parser.add_argument('--z1', type = int, default = 10, help="percentage of node with low CPU")
parser.add_argument('--T_tx', type = int, default = 10, help="Interarrival time between transactions")
parser.add_argument('--I', type = int, default = 100, help="Interarrival time between blocks")
parser.add_argument('--T_dij', type = int, default = 10, help="Mean of queuing delay")
#parser.add_argument('--pij', type = int, default = 10, help="speed of light propagation delay")
parser.add_argument('--sim_time', type = int, default = 100, help="Simulation time in seconds")
parser.add_argument('--seed', type = int, default = 0, help="Seed for random number generator")
parser.add_argument(
"-n", "--num_nodes", type=int, default=50, help="Number of nodes in the network"
)
parser.add_argument(
"--z0", type=int, default=10, help="percentage of node with slow bandwidth"
)
parser.add_argument(
"--z1", type=int, default=10, help="percentage of node with low CPU"
)
parser.add_argument(
"--T_tx", type=int, default=10, help="Interarrival time between transactions"
)
parser.add_argument(
"--I", type=int, default=100, help="Interarrival time between blocks"
)
parser.add_argument("--T_dij", type=int, default=10, help="Mean of queuing delay")
# parser.add_argument('--pij', type = int, default = 10, help="speed of light propagation delay")
parser.add_argument(
"--sim_time", type=int, default=100, help="Simulation time in seconds"
)
parser.add_argument(
"--seed", type=int, default=0, help="Seed for random number generator"
)
return parser.parse_args()
if __name__ == '__main__':
if __name__ == "__main__":
args = parse_cmd()
random.seed(args.seed)
print(args)
sim = EventSimulator(args)
nx = Network(sim, args)
sim.startSimulation()
exit(0)
\ No newline at end of file
exit(0)
......@@ -3,38 +3,45 @@ import random
from simulate import Event
from utils import sample_exponential
class Network:
def __init__(self, sim, args):
self.args = args
self.sim = sim
self.pij = float(random.randrange(10, 500)) * 0.001# speed of light propagation delay in ms
# speed of light propagation delay in ms
self.pij = float(random.randrange(10, 500)) * 0.001
self.I = 600
self.create_nodes()
self.create_connections()
self.sim.push_event(Event(0, self.init_simulation,))
self.sim.push_event(
Event(
0,
self.init_simulation,
)
)
return
def init_simulation(self, args):
for node in self.nodes:
node.init_simulation()
return
def create_nodes(self):
"""
Create a list of nodes with the specified parameters
Create a list of nodes with the specified parameters
"""
self.nodes = []
# Create a list of badwidth and cpu type based on z0 and z1
# 0 is slow and 1 is fast
bandwidth_type = [1] * self.args.num_nodes
num_slow_bandwidth = int((self.args.z0*self.args.num_nodes)/100)
num_slow_bandwidth = int((self.args.z0 * self.args.num_nodes) / 100)
rand_idx = random.sample(range(self.args.num_nodes), num_slow_bandwidth)
for idx in rand_idx:
bandwidth_type[idx] = 0
cpu_type = [1] * self.args.num_nodes
num_slow_cpu = int((self.args.z1*self.args.num_nodes)/100)
num_slow_cpu = int((self.args.z1 * self.args.num_nodes) / 100)
rand_idx = random.sample(range(self.args.num_nodes), num_slow_cpu)
for idx in rand_idx:
cpu_type[idx] = 0
......@@ -42,8 +49,8 @@ class Network:
# Based on CPU type calculate the PoW time Tk
# 10 * h_k * (n - num_slow) + h_k * num_slow = 1
# => h_k = 1 / (10 * n - 9 * num_slow)
h_k_slow = 1 / float(10*self.args.num_nodes - 9*num_slow_cpu)
h_k_slow = 1 / float(10 * self.args.num_nodes - 9 * num_slow_cpu)
Tk = []
for i in range(self.args.num_nodes):
if cpu_type[i] == 0:
......@@ -52,26 +59,43 @@ class Network:
Tk.append(10 * (1 - h_k_slow))
for i in range(self.args.num_nodes):
self.nodes.append(Node(self.sim, i, bandwidth_type[i],\
cpu_type[i], float(self.I)/Tk[i], self.args.T_tx,\
self.args.num_nodes, self.pij))
self.nodes.append(
Node(
self.sim,
i,
bandwidth_type[i],
cpu_type[i],
float(self.I) / Tk[i],
self.args.T_tx,
self.args.num_nodes,
self.pij,
)
)
return
def create_connections(self):
"""
Create a bidirectional graph, 3-6 adjacent nodes per node
TODO(SM): Need a better way to create a valid graph
Create a bidirectional graph, 3-6 adjacent nodes per node
TODO(SM): Need a better way to create a valid graph
"""
num_nodes = self.args.num_nodes
valid_graph = False
cnt = 0
while valid_graph == False:
#print("tyring to create a valid graph",cnt)
# print("tyring to create a valid graph",cnt)
adjacency_list = [[] for _ in range(num_nodes)]
for i in range(num_nodes):
num_connections = random.randint(3, 6)
potential_neighbors = [x for x in range(num_nodes) if x != i and len(adjacency_list[x]) < 6 and x not in adjacency_list[i]]
neighbors = random.sample(potential_neighbors, min(num_connections, len(potential_neighbors)))
potential_neighbors = [
x
for x in range(num_nodes)
if x != i
and len(adjacency_list[x]) < 6
and x not in adjacency_list[i]
]
neighbors = random.sample(
potential_neighbors, min(num_connections, len(potential_neighbors))
)
for j in neighbors:
adjacency_list[i].append(j)
adjacency_list[j].append(i)
......@@ -90,4 +114,4 @@ class Network:
for node in self.nodes:
print(node.nodeId, node)
print("Graph created")
return
\ No newline at end of file
return
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -7,6 +7,7 @@ class Event:
self.time = time
self.operation = operation
self.args = args
def process(self):
#print("Processing event at time", self.time)
return self.operation(self.args)
......@@ -30,7 +31,7 @@ class EventSimulator:
Start the simulation.
Run till the simulation time is reached or the queue is empty
"""
print("Starting the simulation")
print("Starting the simulation...")
while len(self.queue) > 0 and self.queue[0].time < self.sim_time:
event = self.queue.pop(0)
self.curr_time = event.time
......
import random
import hashlib
GENESIS_SECRET = "afa25t#$e09ad&1q0-9quQ8q2_aE8Q^"
def gen_hash(value):
return hashlib.sha256(value.encode("utf-8")).hexdigest()
def sample_exponential(mean):
return random.expovariate(1/mean)
return random.expovariate(1 / mean)
txn_id = 0
txn_id = 0
def gen_txn_id():
global txn_id
txn_id += 1
return txn_id
def get_txn_id(txn):
return txn.split(":")[0]
blk_id = 0
blk_id = 0
def gen_blk_id():
global blk_id
blk_id += 1
return blk_id
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