Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

104 changes: 104 additions & 0 deletions simulator/src/main/java/simblock/block/BlockChain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package simblock.block;


import utility.graph.DAG;

import java.util.ArrayList;
import java.util.Collections;

public class BlockChain {
private static final BlockChain instance = new BlockChain();
private DAG<Block> chain;


private BlockChain(){
chain = new DAG<Block>();
}


public static BlockChain getInstance(){
return instance;
}

public void setGenesisBlock(Block genesisBlock){
chain.setRoot(genesisBlock);
}

public void addBlock(Block block) throws Exception {
int currentHeight = chain.getCurrentHeight();
if(block.getHeight() <= currentHeight){
if(!doesBlockExist(block)){
chain.addToDAG(block, block.getHeight());
}
}
else if(block.getHeight() <= currentHeight + 1){
chain.addToDAG(block, block.getHeight());
}
else{
throw new Exception("Problem in Adding block to chain");
}

return;
}

public void putBlockInMainChain(Block block){
try{
int blockHeight = block.getHeight();
ArrayList<Block> blocksOnSameHeight = chain.getNodesByHeight(blockHeight);

if(blocksOnSameHeight.size() == 1){
return;
}
else{
int blockIndex = -1;

for(int i=0; i < blocksOnSameHeight.size(); i++){
if(block.getId() == blocksOnSameHeight.get(i).getId()){
blockIndex = i;
break;
}
}

if(blockIndex == -1){
throw new Exception("Cannot find Block for Swapping");
}

Collections.swap(blocksOnSameHeight, 0, blockIndex);
chain.setDAGHeight(blockHeight, blocksOnSameHeight);
}
}
catch (Exception ex){
System.out.println(ex.getMessage());
}
}

public int getChainHeight(){
return chain.getCurrentHeight();
}

public int getTotalNumberOfBlocksOnChain(){
return chain.getTotalNumberOfNodes();
}

public boolean doesBlockExist(Block block){
ArrayList<Block> blocksOnSameHeight = chain.getNodesByHeight(block.getHeight());

for(Block chainBlock : blocksOnSameHeight){
if(chainBlock.getId() == block.getId()){
return true;
}
}

return false;
}

public ArrayList<Block> getMainChain(){
ArrayList<Block> mainChain = new ArrayList<>();

for(int i=0; i < chain.getCurrentHeight(); i++){
mainChain.add(chain.getNodesByHeight(i).get(0));
}

return mainChain;
}
}
19 changes: 19 additions & 0 deletions simulator/src/main/java/simblock/node/HonestNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package simblock.node;

public class HonestNode extends Node{
/**
* Instantiates a new Node.
*
* @param nodeID the node id
* @param numConnection the number of connections a node can have
* @param region the region
* @param miningPower the mining power
* @param routingTableName the routing table name
* @param consensusAlgoName the consensus algorithm name
* @param useCBR whether the node uses compact block relay
* @param isChurnNode whether the node causes churn
*/
public HonestNode(int nodeID, int numConnection, int region, long miningPower, String routingTableName, String consensusAlgoName, boolean useCBR, boolean isChurnNode) {
super(nodeID, numConnection, region, miningPower, routingTableName, consensusAlgoName, useCBR, isChurnNode);
}
}
72 changes: 29 additions & 43 deletions simulator/src/main/java/simblock/node/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import static simblock.settings.SimulationConfiguration.CBR_FAILURE_RATE_FOR_CHURN_NODE;
import static simblock.settings.SimulationConfiguration.CBR_FAILURE_RATE_FOR_CONTROL_NODE;
import static simblock.settings.SimulationConfiguration.COMPACT_BLOCK_SIZE;
import static simblock.simulator.Main.OUT_JSON_FILE;
import static simblock.simulator.Network.getBandwidth;
import static simblock.simulator.Simulator.arriveBlock;
import static simblock.simulator.Timer.getCurrentTime;
Expand All @@ -36,6 +35,7 @@

import simblock.block.Block;
import simblock.node.consensus.AbstractConsensusAlgo;
import simblock.node.consensus.ProofOfWork;
import simblock.node.routing.AbstractRoutingTable;
import simblock.task.AbstractMessageTask;
import simblock.task.AbstractMintingTask;
Expand All @@ -52,68 +52,68 @@ public class Node {
/**
* Unique node ID.
*/
private final int nodeID;
protected final int nodeID;

/**
* Region assigned to the node.
*/
private final int region;
protected final int region;

/**
* Mining power assigned to the node.
*/
private final long miningPower;
protected final long miningPower;

/**
* A nodes routing table.
*/
private AbstractRoutingTable routingTable;
protected AbstractRoutingTable routingTable;

/**
* The consensus algorithm used by the node.
*/
private AbstractConsensusAlgo consensusAlgo;
protected AbstractConsensusAlgo consensusAlgo;

/**
* Whether the node uses compact block relay.
*/
private boolean useCBR;
protected boolean useCBR;

/**
* The node causes churn.
*/
private boolean isChurnNode;
protected boolean isChurnNode;

/**
* The current block.
*/
private Block block;
protected Block block;

/**
* Orphaned blocks known to node.
*/
private final Set<Block> orphans = new HashSet<>();
protected final Set<Block> orphans = new HashSet<>();

/**
* The current minting task
*/
private AbstractMintingTask mintingTask = null;
protected AbstractMintingTask mintingTask = null;

/**
* In the process of sending blocks.
*/
// TODO verify
private boolean sendingBlock = false;
protected boolean sendingBlock = false;

//TODO
private final ArrayList<AbstractMessageTask> messageQue = new ArrayList<>();
protected final ArrayList<AbstractMessageTask> messageQue = new ArrayList<>();
// TODO
private final Set<Block> downloadingBlocks = new HashSet<>();
protected final Set<Block> downloadingBlocks = new HashSet<>();

/**
* Processing time of tasks expressed in milliseconds.
*/
private final long processingTime = 2;
protected final long processingTime = 2;

/**
* Instantiates a new Node.
Expand All @@ -140,8 +140,7 @@ public Node(
try {
this.routingTable = (AbstractRoutingTable) Class.forName(routingTableName).getConstructor(
Node.class).newInstance(this);
this.consensusAlgo = (AbstractConsensusAlgo) Class.forName(consensusAlgoName).getConstructor(
Node.class).newInstance(this);
this.consensusAlgo = ProofOfWork.getInstance();
this.setNumConnection(numConnection);
} catch (Exception e) {
e.printStackTrace();
Expand Down Expand Up @@ -273,7 +272,7 @@ public void joinNetwork() {
* Mint the genesis block.
*/
public void genesisBlock() {
Block genesis = this.consensusAlgo.genesisBlock();
Block genesis = this.consensusAlgo.genesisBlock(this);
this.receiveBlock(genesis);
}

Expand All @@ -290,29 +289,16 @@ public void addToChain(Block newBlock) {
this.mintingTask = null;
}
// Update the current block
this.block = newBlock;
printAddBlock(newBlock);
if(newBlock.getHeight() == 0){
this.block = newBlock;
}
else if(newBlock.getHeight() > this.block.getHeight()){
this.block = newBlock;
}
// Observe and handle new block arrival
arriveBlock(newBlock, this);
}

/**
* Logs the provided block to the logfile.
*
* @param newBlock the block to be logged
*/
private void printAddBlock(Block newBlock) {
OUT_JSON_FILE.print("{");
OUT_JSON_FILE.print("\"kind\":\"add-block\",");
OUT_JSON_FILE.print("\"content\":{");
OUT_JSON_FILE.print("\"timestamp\":" + getCurrentTime() + ",");
OUT_JSON_FILE.print("\"node-id\":" + this.getNodeID() + ",");
OUT_JSON_FILE.print("\"block-id\":" + newBlock.getId());
OUT_JSON_FILE.print("}");
OUT_JSON_FILE.print("},");
OUT_JSON_FILE.flush();
}

/**
* Add orphans.
*
Expand All @@ -321,7 +307,7 @@ private void printAddBlock(Block newBlock) {
*/
//TODO check this out later
public void addOrphans(Block orphanBlock, Block validBlock) {
if (orphanBlock != validBlock) {
/* if (orphanBlock != validBlock) {
this.orphans.add(orphanBlock);
this.orphans.remove(validBlock);
if (validBlock == null || orphanBlock.getHeight() > validBlock.getHeight()) {
Expand All @@ -331,14 +317,14 @@ public void addOrphans(Block orphanBlock, Block validBlock) {
} else {
this.addOrphans(orphanBlock, validBlock.getParent());
}
}
}*/
}

/**
* Generates a new minting task and registers it
*/
public void minting() {
AbstractMintingTask task = this.consensusAlgo.minting();
AbstractMintingTask task = this.consensusAlgo.minting(this);
this.mintingTask = task;
if (task != null) {
putTask(task);
Expand All @@ -363,15 +349,15 @@ public void sendInv(Block block) {
* @param block the block
*/
public void receiveBlock(Block block) {
if (this.consensusAlgo.isReceivedBlockValid(block, this.block)) {
if (this.consensusAlgo.isReceivedBlockValid(this, block, this.block)) {
if (this.block != null && !this.block.isOnSameChainAs(block)) {
// If orphan mark orphan
this.addOrphans(this.block, block);
}
// Else add to canonical chain
this.addToChain(block);
// Generates a new minting task
this.minting();
//this.minting();
// Advertise received block
this.sendInv(block);
} else if (!this.orphans.contains(block) && !block.isOnSameChainAs(this.block)) {
Expand All @@ -394,7 +380,7 @@ public void receiveMessage(AbstractMessageTask message) {
if (message instanceof InvMessageTask) {
Block block = ((InvMessageTask) message).getBlock();
if (!this.orphans.contains(block) && !this.downloadingBlocks.contains(block)) {
if (this.consensusAlgo.isReceivedBlockValid(block, this.block)) {
if (this.consensusAlgo.isReceivedBlockValid(this, block, this.block)) {
AbstractMessageTask task = new RecMessageTask(this, from, block);
putTask(task);
downloadingBlocks.add(block);
Expand Down
Loading