me.edwards.des.block
Class BlockChain

java.lang.Object
  extended by me.edwards.des.block.BlockChain

public class BlockChain
extends java.lang.Object

Data structure to maintain Blocks in the BlockChain. Blocks can be randomly appended to the BlockChain using append(Block) and will be put into the correct order to form a continuous tree of Blocks backwards-linked through the previous hash fields. The BlockChain maintains a queue of orphan Blocks to ensure that Blocks received by the Node out-of-order in the tree can be appended to the BlockChain correctly. The BlockChain also maintains a list of all the Blocks acting as leaves on the top of the tree, but will always choose the longest continuous chain of Blocks as the main chain.

The branching abilities of the BlockChain provide the mechanism of the network to "vote" on valid Blocks and come to a consensus of what the "real" BlockChain is. Blocks that are generated and deemed valid are added to the BlockChain while invalid Blocks will never be added to the BlockChain. When two valid Blocks with the same parent are added to the BlockChain, a branch is created, which may cause a split in the network. Further explanation provided with append(Block).

Created on: Nov 2, 2015 at 2:23:14 PM

Author:
Matthew Edwards

Nested Class Summary
 class BlockChain.Node
          Represents a tree node in the BlockChain

Created on: Dec 21, 2015 at 5:20:30 PM
 
Field Summary
static int BLOCK_GOAL
          The goal time for ten Blocks to be mined, in minutes.
static int MAXIMUM_BLOCK_SIZE
          The maximum size, in bytes, that a Block may be
private  java.util.ArrayList<Block> queue
           
private  BlockChain.Node top
           
private  java.util.ArrayList<BlockChain.Node> topList
           
 
Constructor Summary
BlockChain(Block genesis)
          Creates new BlockChain with the first Block (the Genesis Block).
BlockChain(int size, byte[][] binary)
          Initializes BlockChain from binary data as a byte array.
 
Method Summary
 void append(Block block)
          Queues the specified Block to be added to this BlockChain.
 boolean contains(java.lang.String hash)
          Returns true if the specified hash belongs to a Block in this BlockChain.
 Block get(java.lang.String hash)
          Returns the Block in this BlockChain with the specified hash.
 byte[][] getBytes()
          Returns the BlockChain in binary format as a chunk array.
 int getCurrentTarget()
          Returns the current target of the BlockChain.
 long getMedianTime(java.lang.String hash)
          Returns the Median Time of the last 10 (or available) Blocks.
 BlockChain.Node getNode(java.lang.String hash)
          Returns the node in this BlockChain containing the Block with the specified hash.
 int getSize()
          Returns the number of Blocks in the longest branch in this BlockChain
 Block getTop()
          Returns the Block on the top of the longest branch in this BlockChain.
 boolean hasBallot(java.lang.String hash, java.lang.String uuid)
          Returns True if the specified Ballot is contained in the longest branch of this BlockChain.
 java.lang.String toString()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

MAXIMUM_BLOCK_SIZE

public static final int MAXIMUM_BLOCK_SIZE
The maximum size, in bytes, that a Block may be

See Also:
Constant Field Values

BLOCK_GOAL

public static final int BLOCK_GOAL
The goal time for ten Blocks to be mined, in minutes.

See Also:
Constant Field Values

top

private BlockChain.Node top

queue

private java.util.ArrayList<Block> queue

topList

private java.util.ArrayList<BlockChain.Node> topList
Constructor Detail

BlockChain

public BlockChain(Block genesis)
Creates new BlockChain with the first Block (the Genesis Block). This constructor is only used when the Node is starting a new BlockChain, otherwise the BlockChain is downloaded from a peer Node or loaded from file.

Parameters:
genesis - First Block in the new BlockChain

BlockChain

public BlockChain(int size,
                  byte[][] binary)
Initializes BlockChain from binary data as a byte array. This constructor is used when a BlockChain is loaded from a file or downloaded from a peer Node.

Parameters:
size - Number of chunks in which this BlockChain was saved
binary - Loaded array of chunks (byte arrays containing Blocks) representing this BlockChain
Method Detail

getBytes

public byte[][] getBytes()
Returns the BlockChain in binary format as a chunk array.

Returns:
Array of chunks (byte arrays containing Blocks) representing this BlockChain

getTop

public Block getTop()
Returns the Block on the top of the longest branch in this BlockChain.

Returns:
Block at the top of this BlockChain

getSize

public int getSize()
Returns the number of Blocks in the longest branch in this BlockChain

Returns:
Number of Blocks in the longest branch

append

public void append(Block block)
Queues the specified Block to be added to this BlockChain. This method accepts orphan Blocks (a Block whose parent is not contained in the BlockChain), child Blocks of the main chain, and child Blocks of branch chains. The algorithm for appending Blocks allows for branching of the BlockChain, and resolution of Blocks to form a consensus between Nodes.

For example, if a Node in California generated a valid Block at the same time as a Node in Virginia, Nodes on the East Coast might have a different version of the BlockChain than Nodes on the West Coast. The East Coast would have the Block generated by the Node in Virginia as the top block in the BlockChain, while the West Coast would have the Block generated by the Node in California as the top block in the BlockChain. However, all Nodes would have both the "East Block" and the "West Block" contained in their BlockChains, just disagree on which Block is the at the top of the BlockChain.

When the next Block is generated and propagated throughout the network, it will have either the "East Block" or the "West Block" as a parent. As Nodes receive this new Block (which as an example will have the "East Block" as its parent), the branch containing the parent will be extended, and the entire network will come to a consensus concerning the BlockChain. The new block will be at the top of the BlockChain and the "East Block" will be its parent. The branch containing the "West Block" is now shorter, and declared invalid by each Node. Therefore, the entire network will have a single agreed-upon BlockChain.

Parameters:
block - Block to be added to this BlockChain

contains

public boolean contains(java.lang.String hash)
Returns true if the specified hash belongs to a Block in this BlockChain.

Parameters:
hash - Block's 32-digit hexadecimal hash
Returns:
True if the specified hash belongs to a Block in this BlockChain

get

public Block get(java.lang.String hash)
Returns the Block in this BlockChain with the specified hash.

Parameters:
hash - Block's 32-digit hexadecimal hash
Returns:
If the Block exists, it is returned, otherwise, a null value is returned.

getNode

public BlockChain.Node getNode(java.lang.String hash)
Returns the node in this BlockChain containing the Block with the specified hash.

Parameters:
hash - Block's 32-digit hexadecimal hash
Returns:
If the Block exists, the node containing it is returned. Otherwise, a null value is returned.

getMedianTime

public long getMedianTime(java.lang.String hash)
Returns the Median Time of the last 10 (or available) Blocks.

Parameters:
hash - Hash of the Block at which to begin
Returns:
The Median Time of the last 10 Blocks, -1 if the Hash could not be found.

hasBallot

public boolean hasBallot(java.lang.String hash,
                         java.lang.String uuid)
Returns True if the specified Ballot is contained in the longest branch of this BlockChain.

Parameters:
hash - Parent hash of the Block containing this ballot.
uuid - UUID of the Ballot
Returns:
True if the Ballot exists, False otherwise

getCurrentTarget

public int getCurrentTarget()
Returns the current target of the BlockChain. This method is used for adjusting the difficulty of mining a Block.

The difficulty is adjusted by finding the difference in timestamps of the past 10 (or available) Blocks. The target is then multiplied by a scalar in order to increase or decrease the difficulty so that the actual difference matches the goal difference.

Returns:
Current BlockChain target in Short-Format

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object