Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
blockchain_CS765_HW1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Saswat
blockchain_CS765_HW1
Commits
d366f99d
Commit
d366f99d
authored
Feb 06, 2024
by
Abhishek Kumar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Completed txns code
parent
fb9756fb
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1223 additions
and
120 deletions
+1223
-120
blockchain.py
blockchain.py
+37
-21
main.py
main.py
+29
-13
network.py
network.py
+43
-19
node.py
node.py
+110
-62
sim.log
sim.log
+985
-0
simulate.py
simulate.py
+2
-1
utils.py
utils.py
+17
-4
No files found.
blockchain.py
View file @
d366f99d
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
main.py
View file @
d366f99d
...
...
@@ -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
)
network.py
View file @
d366f99d
...
...
@@ -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
node.py
View file @
d366f99d
This diff is collapsed.
Click to expand it.
sim.log
0 → 100644
View file @
d366f99d
This source diff could not be displayed because it is too large. You can
view the blob
instead.
simulate.py
View file @
d366f99d
...
...
@@ -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
...
...
utils.py
View file @
d366f99d
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment